-- 0003_device_pairing.sql
-- Additive, idempotent migration for the OAuth2 device-authorization-grant
-- style "device pairing" flow used by the Home Assistant add-on.
-- Safe to run multiple times.

-- 1. Device pairings ------------------------------------------------------
-- One row per device-pairing attempt. The opaque device_code is only ever
-- stored as a SHA-256 hash; the short, human-typed user_code is stored in the
-- clear so it can be looked up when the user approves on the web.
create table if not exists public.device_pairings (
  id               bigint generated always as identity primary key,
  device_code_hash text not null,
  user_code        text not null,
  user_id          uuid,
  subdomain        citext,
  status           text not null default 'pending',
  interval_seconds int not null default 5,
  created_at       timestamptz not null default now(),
  expires_at       timestamptz not null,
  approved_at      timestamptz,
  claimed_at       timestamptz,
  last_polled_at   timestamptz
);

create unique index if not exists device_pairings_device_code_hash_uidx
  on public.device_pairings (device_code_hash);

create unique index if not exists device_pairings_user_code_uidx
  on public.device_pairings (user_code);

create index if not exists device_pairings_expires_at_idx
  on public.device_pairings (expires_at);

-- Cascade-delete pairings when the owning auth user is removed.
do $$
begin
  if not exists (
    select 1 from pg_constraint
    where conname = 'device_pairings_user_id_fkey'
      and conrelid = 'public.device_pairings'::regclass
  ) then
    alter table public.device_pairings
      add constraint device_pairings_user_id_fkey
      foreign key (user_id) references auth.users (id) on delete cascade;
  end if;
end $$;

-- RLS enabled with NO policies: service-role only.
alter table public.device_pairings enable row level security;

comment on table public.device_pairings is
  'Device-authorization-grant pairings (device_code SHA-256 hashed). RLS enabled with no policies: service-role only.';

-- 2. Device tokens --------------------------------------------------------
-- Long-lived bearer tokens minted to a paired device. Only the SHA-256 hash
-- is stored; the plaintext is returned to the device exactly once at mint.
create table if not exists public.device_tokens (
  id           bigint generated always as identity primary key,
  token_hash   text not null,
  user_id      uuid not null,
  label        text,
  created_at   timestamptz not null default now(),
  last_used_at timestamptz,
  revoked_at   timestamptz
);

create unique index if not exists device_tokens_token_hash_uidx
  on public.device_tokens (token_hash);

create index if not exists device_tokens_user_id_idx
  on public.device_tokens (user_id);

-- Cascade-delete device tokens when the owning auth user is removed.
do $$
begin
  if not exists (
    select 1 from pg_constraint
    where conname = 'device_tokens_user_id_fkey'
      and conrelid = 'public.device_tokens'::regclass
  ) then
    alter table public.device_tokens
      add constraint device_tokens_user_id_fkey
      foreign key (user_id) references auth.users (id) on delete cascade;
  end if;
end $$;

-- RLS enabled with NO policies: service-role only.
alter table public.device_tokens enable row level security;

comment on table public.device_tokens is
  'Device bearer tokens (SHA-256 hashed). RLS enabled with no policies: service-role only.';
