diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 321fb7b..229b2b4 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -14,6 +14,80 @@ export type Database = { } public: { Tables: { + archive_categories: { + Row: { + active: boolean + created_at: string + created_by: string | null + id: string + key: string + label: string + sort_order: number + updated_at: string + } + Insert: { + active?: boolean + created_at?: string + created_by?: string | null + id?: string + key: string + label: string + sort_order?: number + updated_at?: string + } + Update: { + active?: boolean + created_at?: string + created_by?: string | null + id?: string + key?: string + label?: string + sort_order?: number + updated_at?: string + } + Relationships: [] + } + archive_records: { + Row: { + batch_id: string | null + category_id: string + created_at: string + created_by: string | null + data: Json + id: string + row_index: number | null + source_filename: string | null + } + Insert: { + batch_id?: string | null + category_id: string + created_at?: string + created_by?: string | null + data?: Json + id?: string + row_index?: number | null + source_filename?: string | null + } + Update: { + batch_id?: string | null + category_id?: string + created_at?: string + created_by?: string | null + data?: Json + id?: string + row_index?: number | null + source_filename?: string | null + } + Relationships: [ + { + foreignKeyName: "archive_records_category_id_fkey" + columns: ["category_id"] + isOneToOne: false + referencedRelation: "archive_categories" + referencedColumns: ["id"] + }, + ] + } call_logs: { Row: { billable: boolean diff --git a/supabase/migrations/20260419175450_b28101a7-eaf4-4b33-9555-3fe0f7810ad8.sql b/supabase/migrations/20260419175450_b28101a7-eaf4-4b33-9555-3fe0f7810ad8.sql new file mode 100644 index 0000000..f22a891 --- /dev/null +++ b/supabase/migrations/20260419175450_b28101a7-eaf4-4b33-9555-3fe0f7810ad8.sql @@ -0,0 +1,62 @@ +-- Categories: list of archive types (cases, time, expenses, plus user-added) +CREATE TABLE public.archive_categories ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + key text NOT NULL UNIQUE, + label text NOT NULL, + sort_order integer NOT NULL DEFAULT 0, + active boolean NOT NULL DEFAULT true, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + created_by uuid +); + +ALTER TABLE public.archive_categories ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "ac_select_auth" ON public.archive_categories + FOR SELECT TO authenticated USING (true); +CREATE POLICY "ac_insert_admin" ON public.archive_categories + FOR INSERT TO authenticated WITH CHECK (public.is_admin(auth.uid())); +CREATE POLICY "ac_update_admin" ON public.archive_categories + FOR UPDATE TO authenticated USING (public.is_admin(auth.uid())); +CREATE POLICY "ac_delete_admin" ON public.archive_categories + FOR DELETE TO authenticated USING (public.is_admin(auth.uid())); + +CREATE TRIGGER trg_ac_updated BEFORE UPDATE ON public.archive_categories + FOR EACH ROW EXECUTE FUNCTION public.tg_set_updated_at(); + +-- Records: one row per CSV row, columns preserved verbatim in `data` JSONB +CREATE TABLE public.archive_records ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + category_id uuid NOT NULL REFERENCES public.archive_categories(id) ON DELETE CASCADE, + data jsonb NOT NULL DEFAULT '{}'::jsonb, + source_filename text, + batch_id uuid, + row_index integer, + created_at timestamptz NOT NULL DEFAULT now(), + created_by uuid +); + +CREATE INDEX idx_archive_records_category ON public.archive_records(category_id, created_at DESC); +CREATE INDEX idx_archive_records_batch ON public.archive_records(batch_id); + +ALTER TABLE public.archive_records ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "ar_select_auth" ON public.archive_records + FOR SELECT TO authenticated USING (true); +CREATE POLICY "ar_insert_admin" ON public.archive_records + FOR INSERT TO authenticated WITH CHECK (public.is_admin(auth.uid())); +CREATE POLICY "ar_delete_admin" ON public.archive_records + FOR DELETE TO authenticated USING (public.is_admin(auth.uid())); + +-- Seed default categories +INSERT INTO public.archive_categories (key, label, sort_order) VALUES + ('cases', 'Cases', 10), + ('time_entries', 'Time Entries', 20), + ('expenses', 'Expenses', 30), + ('invoices', 'Invoices', 40), + ('clients', 'Clients', 50), + ('status_updates', 'Status Updates', 60), + ('contacts', 'Contacts', 70), + ('homeowners', 'Homeowners', 80), + ('call_logs', 'Call Logs', 90), + ('documents', 'Documents', 100); \ No newline at end of file