-- ① 관리자 명단 테이블
create table if not exists public.admins (
user_id uuid primary key references auth.users(id) on delete cascade,
email text,
created_at timestamptz default now()
);
alter table public.admins enable row level security;
drop policy if exists "admins_self_read" on public.admins;
create policy "admins_self_read" on public.admins
for select to authenticated using (auth.uid() = user_id);
-- ② 관리자 판별 함수 (RLS 정책에서 호출)
create or replace function public.is_admin()
returns boolean language sql security definer stable
set search_path = public as $$
select exists (select 1 from public.admins where user_id = auth.uid());
$$;
grant execute on function public.is_admin() to anon, authenticated;
-- ③ 관리자 계정 등록 (★ 실제 계정으로 수정)
insert into public.admins (user_id, email)
select id, email from auth.users
where email in ('admin@poyouth.or.kr', 'youjoongwon@kakao.com')
on conflict (user_id) do nothing;
-- ④ 근거자료 테이블
create table if not exists public.archive_items (
id uuid primary key default gen_random_uuid(),
kind text not null,
title text not null,
org text,
ref_date text,
url text,
file_path text,
file_name text,
file_size bigint,
backs text[] default '{}',
linked_source text,
created_at timestamptz default now(),
created_by uuid default auth.uid()
);
create index if not exists archive_items_created_idx on public.archive_items (created_at desc);
alter table public.archive_items enable row level security;
-- 읽기: 누구나 / 등록·수정·삭제: 관리자만
drop policy if exists "archive_public_read" on public.archive_items;
create policy "archive_public_read" on public.archive_items
for select to anon, authenticated using (true);
drop policy if exists "archive_admin_insert" on public.archive_items;
create policy "archive_admin_insert" on public.archive_items
for insert to authenticated with check (public.is_admin());
drop policy if exists "archive_admin_update" on public.archive_items;
create policy "archive_admin_update" on public.archive_items
for update to authenticated using (public.is_admin()) with check (public.is_admin());
drop policy if exists "archive_admin_delete" on public.archive_items;
create policy "archive_admin_delete" on public.archive_items
for delete to authenticated using (public.is_admin());
-- ⑤ 권한 부여
grant usage on schema public to anon, authenticated;
grant select on public.archive_items to anon, authenticated;
grant insert, update, delete on public.archive_items to authenticated;
grant select on public.admins to authenticated;
-- ⑥ 파일 보관함(Storage) 버킷
insert into storage.buckets (id, name, public)
values ('archive', 'archive', true)
on conflict (id) do nothing;
drop policy if exists "archive_files_read" on storage.objects;
create policy "archive_files_read" on storage.objects
for select to anon, authenticated using (bucket_id = 'archive');
drop policy if exists "archive_files_insert" on storage.objects;
create policy "archive_files_insert" on storage.objects
for insert to authenticated
with check (bucket_id = 'archive' and public.is_admin());
drop policy if exists "archive_files_update" on storage.objects;
create policy "archive_files_update" on storage.objects
for update to authenticated
using (bucket_id = 'archive' and public.is_admin())
with check (bucket_id = 'archive' and public.is_admin());
drop policy if exists "archive_files_delete" on storage.objects;
create policy "archive_files_delete" on storage.objects
for delete to authenticated
using (bucket_id = 'archive' and public.is_admin());
-- ⑦ 확인용
select a.email from public.admins a;
select id, public from storage.buckets where id = 'archive';