@fayz-ai/plugin-forms 0.2.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/tables.d.ts +7 -0
- package/dist/data/tables.d.ts.map +1 -0
- package/dist/index.cjs +27 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -19
- package/dist/index.js.map +1 -1
- package/dist/migrations/index.d.ts +8 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -4
- package/src/data/supabase.ts +20 -19
- package/src/data/tables.ts +7 -0
- package/src/index.ts +2 -1
- package/src/migrations/000_plg_rename.sql +21 -0
- package/src/migrations/001_frm_base.sql +92 -56
- package/src/migrations/002_document_archetype.sql +130 -42
- package/src/migrations/index.ts +433 -0
- package/src/types.ts +4 -4
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
-- ============================================================
|
|
2
|
-
-- Document Archetype —
|
|
2
|
+
-- Document Archetype — public.documents
|
|
3
3
|
-- A document is any record associated with a person (or standalone):
|
|
4
4
|
-- forms, images, attachments, prescriptions, contracts, etc.
|
|
5
5
|
-- The `kind` column discriminates the type.
|
|
6
|
+
--
|
|
7
|
+
-- DATA SAFETY (converted pools): plg_forms_documents may already hold REAL
|
|
8
|
+
-- rows in its PRE-archetype shape (its own `id` PK, no `document_id` column —
|
|
9
|
+
-- see 001_frm_base.sql). This migration MIGRATES those rows into the new
|
|
10
|
+
-- document archetype instead of dropping them:
|
|
11
|
+
-- * pre-archetype + rows -> copy each legacy row into public.documents
|
|
12
|
+
-- (reusing its id) + into the new extension
|
|
13
|
+
-- table, migrate its files, then drop legacy.
|
|
14
|
+
-- * pre-archetype + empty -> plain drop + create (fresh shape).
|
|
15
|
+
-- * already new shape -> no-op.
|
|
6
16
|
-- ============================================================
|
|
7
17
|
|
|
8
|
-
CREATE TABLE IF NOT EXISTS
|
|
18
|
+
CREATE TABLE IF NOT EXISTS public.documents (
|
|
9
19
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
10
|
-
tenant_id uuid NOT NULL REFERENCES
|
|
20
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
11
21
|
kind text NOT NULL DEFAULT 'attachment',
|
|
12
22
|
-- kind: 'form', 'image', 'attachment', 'prescription', 'contract', etc.
|
|
13
|
-
person_id uuid REFERENCES
|
|
23
|
+
person_id uuid REFERENCES public.people(id) ON DELETE SET NULL,
|
|
14
24
|
title text,
|
|
15
25
|
description text,
|
|
16
26
|
status text NOT NULL DEFAULT 'draft',
|
|
@@ -29,39 +39,63 @@ CREATE TABLE IF NOT EXISTS saas_core.documents (
|
|
|
29
39
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
30
40
|
);
|
|
31
41
|
|
|
32
|
-
ALTER TABLE
|
|
42
|
+
ALTER TABLE public.documents ENABLE ROW LEVEL SECURITY;
|
|
33
43
|
|
|
34
|
-
CREATE INDEX IF NOT EXISTS idx_documents_tenant ON
|
|
35
|
-
CREATE INDEX IF NOT EXISTS idx_documents_person ON
|
|
36
|
-
CREATE INDEX IF NOT EXISTS idx_documents_status ON
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_documents_tenant ON public.documents(tenant_id, kind);
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_documents_person ON public.documents(person_id);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_documents_status ON public.documents(tenant_id, status);
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
DROP POLICY IF EXISTS "documents_select" ON public.documents;
|
|
49
|
+
CREATE POLICY "documents_select" ON public.documents
|
|
39
50
|
FOR SELECT TO authenticated
|
|
40
51
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
41
|
-
|
|
52
|
+
DROP POLICY IF EXISTS "documents_insert" ON public.documents;
|
|
53
|
+
CREATE POLICY "documents_insert" ON public.documents
|
|
42
54
|
FOR INSERT TO authenticated
|
|
43
55
|
WITH CHECK (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
44
|
-
|
|
56
|
+
DROP POLICY IF EXISTS "documents_update" ON public.documents;
|
|
57
|
+
CREATE POLICY "documents_update" ON public.documents
|
|
45
58
|
FOR UPDATE TO authenticated
|
|
46
59
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
47
|
-
|
|
60
|
+
DROP POLICY IF EXISTS "documents_delete" ON public.documents;
|
|
61
|
+
CREATE POLICY "documents_delete" ON public.documents
|
|
48
62
|
FOR DELETE TO authenticated
|
|
49
63
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
50
64
|
|
|
51
65
|
-- ============================================================
|
|
52
|
-
--
|
|
66
|
+
-- Reconcile plg_forms_documents / plg_forms_document_files with the archetype.
|
|
53
67
|
-- ============================================================
|
|
54
68
|
|
|
55
|
-
--
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
-- Step 1: if a PRE-archetype plg_forms_documents is present (no document_id
|
|
70
|
+
-- column), rename it (and its files table + dependent view) out of the way so
|
|
71
|
+
-- the new archetype-shaped tables can be created and — when it holds rows —
|
|
72
|
+
-- its data copied across. Fully guarded, so already-migrated pools skip this.
|
|
73
|
+
DO $$
|
|
74
|
+
BEGIN
|
|
75
|
+
IF to_regclass('public.plg_forms_documents') IS NOT NULL
|
|
76
|
+
AND NOT EXISTS (
|
|
77
|
+
SELECT 1 FROM information_schema.columns
|
|
78
|
+
WHERE table_schema = 'public'
|
|
79
|
+
AND table_name = 'plg_forms_documents'
|
|
80
|
+
AND column_name = 'document_id'
|
|
81
|
+
) THEN
|
|
82
|
+
DROP VIEW IF EXISTS public.v_frm_documents;
|
|
83
|
+
ALTER TABLE public.plg_forms_documents RENAME TO plg_forms_documents_legacy;
|
|
84
|
+
IF to_regclass('public.plg_forms_document_files') IS NOT NULL THEN
|
|
85
|
+
ALTER TABLE public.plg_forms_document_files RENAME TO plg_forms_document_files_legacy;
|
|
86
|
+
END IF;
|
|
87
|
+
END IF;
|
|
88
|
+
END $$;
|
|
59
89
|
|
|
60
|
-
--
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
90
|
+
-- Step 2: create the new archetype-shaped extension tables. IF NOT EXISTS makes
|
|
91
|
+
-- this a no-op on pools already migrated to the new shape; after Step 1 the
|
|
92
|
+
-- names are free on pre-archetype pools.
|
|
93
|
+
|
|
94
|
+
-- plg_forms_documents: extension table for form-type documents
|
|
95
|
+
CREATE TABLE IF NOT EXISTS public.plg_forms_documents (
|
|
96
|
+
document_id uuid PRIMARY KEY REFERENCES public.documents(id) ON DELETE CASCADE,
|
|
97
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
98
|
+
template_id uuid NOT NULL REFERENCES public.plg_forms_templates(id),
|
|
65
99
|
data jsonb NOT NULL DEFAULT '{}',
|
|
66
100
|
signed_at timestamptz,
|
|
67
101
|
signed_by uuid,
|
|
@@ -69,28 +103,32 @@ CREATE TABLE public.frm_documents (
|
|
|
69
103
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
70
104
|
);
|
|
71
105
|
|
|
72
|
-
ALTER TABLE public.
|
|
106
|
+
ALTER TABLE public.plg_forms_documents ENABLE ROW LEVEL SECURITY;
|
|
73
107
|
|
|
74
|
-
CREATE INDEX IF NOT EXISTS
|
|
108
|
+
CREATE INDEX IF NOT EXISTS idx_plg_forms_documents_template ON public.plg_forms_documents(template_id);
|
|
75
109
|
|
|
76
|
-
|
|
110
|
+
DROP POLICY IF EXISTS "plg_forms_documents_select" ON public.plg_forms_documents;
|
|
111
|
+
CREATE POLICY "plg_forms_documents_select" ON public.plg_forms_documents
|
|
77
112
|
FOR SELECT TO authenticated
|
|
78
113
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
79
|
-
|
|
114
|
+
DROP POLICY IF EXISTS "plg_forms_documents_insert" ON public.plg_forms_documents;
|
|
115
|
+
CREATE POLICY "plg_forms_documents_insert" ON public.plg_forms_documents
|
|
80
116
|
FOR INSERT TO authenticated
|
|
81
117
|
WITH CHECK (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
82
|
-
|
|
118
|
+
DROP POLICY IF EXISTS "plg_forms_documents_update" ON public.plg_forms_documents;
|
|
119
|
+
CREATE POLICY "plg_forms_documents_update" ON public.plg_forms_documents
|
|
83
120
|
FOR UPDATE TO authenticated
|
|
84
121
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
85
|
-
|
|
122
|
+
DROP POLICY IF EXISTS "plg_forms_documents_delete" ON public.plg_forms_documents;
|
|
123
|
+
CREATE POLICY "plg_forms_documents_delete" ON public.plg_forms_documents
|
|
86
124
|
FOR DELETE TO authenticated
|
|
87
125
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
88
126
|
|
|
89
|
-
--
|
|
90
|
-
CREATE TABLE public.
|
|
127
|
+
-- plg_forms_document_files: file attachments for form fields
|
|
128
|
+
CREATE TABLE IF NOT EXISTS public.plg_forms_document_files (
|
|
91
129
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
92
|
-
tenant_id uuid NOT NULL REFERENCES
|
|
93
|
-
document_id uuid NOT NULL REFERENCES
|
|
130
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
131
|
+
document_id uuid NOT NULL REFERENCES public.documents(id) ON DELETE CASCADE,
|
|
94
132
|
field_key text NOT NULL,
|
|
95
133
|
file_url text NOT NULL,
|
|
96
134
|
file_name text,
|
|
@@ -101,23 +139,73 @@ CREATE TABLE public.frm_document_files (
|
|
|
101
139
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
102
140
|
);
|
|
103
141
|
|
|
104
|
-
ALTER TABLE public.
|
|
142
|
+
ALTER TABLE public.plg_forms_document_files ENABLE ROW LEVEL SECURITY;
|
|
105
143
|
|
|
106
|
-
CREATE INDEX IF NOT EXISTS
|
|
144
|
+
CREATE INDEX IF NOT EXISTS idx_plg_forms_document_files_document ON public.plg_forms_document_files(document_id);
|
|
107
145
|
|
|
108
|
-
|
|
146
|
+
DROP POLICY IF EXISTS "plg_forms_document_files_select" ON public.plg_forms_document_files;
|
|
147
|
+
CREATE POLICY "plg_forms_document_files_select" ON public.plg_forms_document_files
|
|
109
148
|
FOR SELECT TO authenticated
|
|
110
149
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
111
|
-
|
|
150
|
+
DROP POLICY IF EXISTS "plg_forms_document_files_insert" ON public.plg_forms_document_files;
|
|
151
|
+
CREATE POLICY "plg_forms_document_files_insert" ON public.plg_forms_document_files
|
|
112
152
|
FOR INSERT TO authenticated
|
|
113
153
|
WITH CHECK (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
114
|
-
|
|
154
|
+
DROP POLICY IF EXISTS "plg_forms_document_files_update" ON public.plg_forms_document_files;
|
|
155
|
+
CREATE POLICY "plg_forms_document_files_update" ON public.plg_forms_document_files
|
|
115
156
|
FOR UPDATE TO authenticated
|
|
116
157
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
117
|
-
|
|
158
|
+
DROP POLICY IF EXISTS "plg_forms_document_files_delete" ON public.plg_forms_document_files;
|
|
159
|
+
CREATE POLICY "plg_forms_document_files_delete" ON public.plg_forms_document_files
|
|
118
160
|
FOR DELETE TO authenticated
|
|
119
161
|
USING (tenant_id IN (SELECT public.user_tenant_ids()));
|
|
120
162
|
|
|
163
|
+
-- Step 3: if legacy rows exist, migrate them, then drop the quarantined legacy
|
|
164
|
+
-- tables. Reusing each legacy id as the documents.id keeps every legacy file's
|
|
165
|
+
-- document_id FK valid after the copy. ON CONFLICT DO NOTHING makes a partial
|
|
166
|
+
-- re-run safe.
|
|
167
|
+
DO $$
|
|
168
|
+
BEGIN
|
|
169
|
+
IF to_regclass('public.plg_forms_documents_legacy') IS NOT NULL THEN
|
|
170
|
+
-- 3a. base document (one per legacy form document; is_active mirrors NOT is_deleted)
|
|
171
|
+
INSERT INTO public.documents (
|
|
172
|
+
id, tenant_id, kind, person_id, title, status, notes, metadata,
|
|
173
|
+
is_active, created_by, updated_by, created_at, updated_at
|
|
174
|
+
)
|
|
175
|
+
SELECT
|
|
176
|
+
id, tenant_id, 'form', person_id, title, status, notes, metadata,
|
|
177
|
+
NOT COALESCE(is_deleted, false), created_by, updated_by, created_at, updated_at
|
|
178
|
+
FROM public.plg_forms_documents_legacy
|
|
179
|
+
ON CONFLICT (id) DO NOTHING;
|
|
180
|
+
|
|
181
|
+
-- 3b. form extension row (keyed by the reused document id)
|
|
182
|
+
INSERT INTO public.plg_forms_documents (
|
|
183
|
+
document_id, tenant_id, template_id, data, signed_at, signed_by, created_at, updated_at
|
|
184
|
+
)
|
|
185
|
+
SELECT
|
|
186
|
+
id, tenant_id, template_id, data, signed_at, signed_by, created_at, updated_at
|
|
187
|
+
FROM public.plg_forms_documents_legacy
|
|
188
|
+
ON CONFLICT (document_id) DO NOTHING;
|
|
189
|
+
|
|
190
|
+
-- 3c. file attachments (document_id already points at the reused id)
|
|
191
|
+
IF to_regclass('public.plg_forms_document_files_legacy') IS NOT NULL THEN
|
|
192
|
+
INSERT INTO public.plg_forms_document_files (
|
|
193
|
+
id, tenant_id, document_id, field_key, file_url, file_name,
|
|
194
|
+
file_size, mime_type, sort_order, metadata, created_at
|
|
195
|
+
)
|
|
196
|
+
SELECT
|
|
197
|
+
id, tenant_id, document_id, field_key, file_url, file_name,
|
|
198
|
+
file_size, mime_type, sort_order, metadata, created_at
|
|
199
|
+
FROM public.plg_forms_document_files_legacy
|
|
200
|
+
ON CONFLICT (id) DO NOTHING;
|
|
201
|
+
END IF;
|
|
202
|
+
END IF;
|
|
203
|
+
|
|
204
|
+
-- Drop legacy remnants now that any data has been copied across.
|
|
205
|
+
DROP TABLE IF EXISTS public.plg_forms_document_files_legacy;
|
|
206
|
+
DROP TABLE IF EXISTS public.plg_forms_documents_legacy;
|
|
207
|
+
END $$;
|
|
208
|
+
|
|
121
209
|
-- View: all documents for a person with form data joined when applicable
|
|
122
210
|
CREATE OR REPLACE VIEW public.v_documents AS
|
|
123
211
|
SELECT
|
|
@@ -129,7 +217,7 @@ SELECT
|
|
|
129
217
|
t.name AS template_name,
|
|
130
218
|
t.category AS template_category,
|
|
131
219
|
p.name AS person_name
|
|
132
|
-
FROM
|
|
133
|
-
LEFT JOIN public.
|
|
134
|
-
LEFT JOIN public.
|
|
135
|
-
LEFT JOIN
|
|
220
|
+
FROM public.documents d
|
|
221
|
+
LEFT JOIN public.plg_forms_documents f ON f.document_id = d.id
|
|
222
|
+
LEFT JOIN public.plg_forms_templates t ON t.id = f.template_id
|
|
223
|
+
LEFT JOIN public.people p ON p.id = d.person_id;
|