-- ═══════════════════════════════════════════════════════════════ -- Clinic Registry: Pre-verified channel database -- ═══════════════════════════════════════════════════════════════ -- 사전 검증된 병원 채널 DB. discover-channels에서 API 검색 전에 -- domain으로 조회하여 검증된 채널을 즉시 반환. -- 미등록 도메인은 기존 API 기반 discovery fallback 사용. CREATE TABLE IF NOT EXISTS clinic_registry ( id UUID DEFAULT gen_random_uuid() PRIMARY KEY, -- 병원 식별 name TEXT NOT NULL, -- 한국어 병원명 (ex: "아이디병원") name_aliases TEXT[] DEFAULT '{}', -- 별칭 (ex: {"아이디성형외과", "ID Hospital"}) domain TEXT UNIQUE NOT NULL, -- 도메인 (www 제외, lookup key) website_url TEXT NOT NULL, -- 전체 URL -- 기본 정보 brand_group TEXT, -- 그룹/카테고리 (ex: "프리미엄/하이타깃 후보") district TEXT, -- 지역구 (ex: "강남", "서초") branches TEXT, -- 분점 정보 founded_year INT, -- 개원 연도 -- 영문 사이트 website_en TEXT, -- 소셜 채널 (사전 검증 완료) youtube_url TEXT, instagram_url TEXT, instagram_en_url TEXT, facebook_url TEXT, tiktok_url TEXT, naver_blog_url TEXT, naver_place_url TEXT, gangnam_unni_url TEXT, google_maps_url TEXT, -- 메타 verified_by TEXT DEFAULT 'scrape', -- 'manual' | 'scrape' | 'llm' verified_at TIMESTAMPTZ DEFAULT now(), is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); -- 인덱스: domain lookup (primary query path) CREATE INDEX IF NOT EXISTS idx_clinic_registry_domain ON clinic_registry (domain); -- GIN 인덱스: 별칭 검색 CREATE INDEX IF NOT EXISTS idx_clinic_registry_aliases ON clinic_registry USING gin (name_aliases); -- 지역 필터 CREATE INDEX IF NOT EXISTS idx_clinic_registry_district ON clinic_registry (district); -- RLS (서비스 키로만 접근, 프론트엔드에서는 Edge Function 통해서만) ALTER TABLE clinic_registry ENABLE ROW LEVEL SECURITY; -- 서비스 역할만 CRUD 가능 CREATE POLICY "service_role_full_access" ON clinic_registry FOR ALL USING (auth.role() = 'service_role'); -- anon/authenticated는 읽기만 CREATE POLICY "public_read_registry" ON clinic_registry FOR SELECT USING (true);