-- ============================================================================ -- Phase V2-2: Auth 트리거 + updated_at 자동 갱신 -- ============================================================================ -- ============================================================================ -- handle_new_user: auth.users → public.profiles + public.subscriptions 생성 -- ============================================================================ CREATE OR REPLACE FUNCTION public.handle_new_user() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ BEGIN INSERT INTO public.profiles (id, name, avatar_url, locale) VALUES ( NEW.id, COALESCE( NEW.raw_user_meta_data->>'full_name', NEW.raw_user_meta_data->>'name', split_part(NEW.email, '@', 1) ), NEW.raw_user_meta_data->>'avatar_url', COALESCE(NEW.raw_user_meta_data->>'locale', 'ko') ); INSERT INTO public.subscriptions (user_id, tier, status) VALUES (NEW.id, 'free', 'active'); RETURN NEW; END; $$; CREATE TRIGGER on_auth_user_created AFTER INSERT ON auth.users FOR EACH ROW EXECUTE FUNCTION public.handle_new_user(); -- ============================================================================ -- handle_user_deleted: auth.users 삭제 시 cleanup -- (FK CASCADE로 자동이지만 추가 정리 지점으로 남겨둠) -- ============================================================================ -- 현재는 FK CASCADE에 의존, 필요 시 확장. -- ============================================================================ -- moddatetime: updated_at 자동 갱신 트리거 함수 -- ============================================================================ CREATE OR REPLACE FUNCTION public.moddatetime() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$; -- 각 테이블에 트리거 부착 ---------------------------------------------------- CREATE TRIGGER set_updated_at_profiles BEFORE UPDATE ON public.profiles FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_teams BEFORE UPDATE ON public.teams FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_meetings BEFORE UPDATE ON public.meetings FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_meeting_documents BEFORE UPDATE ON public.meeting_documents FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_transcripts BEFORE UPDATE ON public.transcripts FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_history BEFORE UPDATE ON public.history FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_dictionary BEFORE UPDATE ON public.dictionary FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); CREATE TRIGGER set_updated_at_subscriptions BEFORE UPDATE ON public.subscriptions FOR EACH ROW EXECUTE FUNCTION public.moddatetime(); -- ============================================================================ -- increment_daily_usage: Edge Function에서 호출하는 쿼터 증가 헬퍼 -- service_role 전용 (SECURITY DEFINER) -- ============================================================================ CREATE OR REPLACE FUNCTION public.increment_daily_usage( p_user_id uuid, p_feature text, p_amount integer DEFAULT 1 ) RETURNS integer LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ DECLARE v_new_count integer; BEGIN INSERT INTO public.daily_usage (user_id, date, feature, count) VALUES (p_user_id, CURRENT_DATE, p_feature, p_amount) ON CONFLICT (user_id, date, feature) DO UPDATE SET count = public.daily_usage.count + p_amount RETURNING count INTO v_new_count; RETURN v_new_count; END; $$; -- 일반 유저는 호출 불가, service_role만 허용 REVOKE ALL ON FUNCTION public.increment_daily_usage FROM PUBLIC; REVOKE ALL ON FUNCTION public.increment_daily_usage FROM authenticated; GRANT EXECUTE ON FUNCTION public.increment_daily_usage TO service_role;