@kernhq/module-hr 0.10.2 → 0.10.3
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/migrations/0000_init.sql +36 -36
- package/migrations/0001_rls.sql +37 -3
- package/migrations/0002_leave.sql +48 -28
- package/migrations/0003_attendance.sql +28 -14
- package/migrations/0004_policies.sql +17 -7
- package/package.json +1 -1
package/migrations/0000_init.sql
CHANGED
|
@@ -13,7 +13,7 @@ CREATE EXTENSION IF NOT EXISTS btree_gist;
|
|
|
13
13
|
--> statement-breakpoint
|
|
14
14
|
CREATE SCHEMA IF NOT EXISTS "mod_hr";
|
|
15
15
|
--> statement-breakpoint
|
|
16
|
-
CREATE TABLE "mod_hr"."calendar_days" (
|
|
16
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."calendar_days" (
|
|
17
17
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
18
18
|
"workspace_id" uuid NOT NULL,
|
|
19
19
|
"calendar_id" uuid NOT NULL,
|
|
@@ -27,7 +27,7 @@ CREATE TABLE "mod_hr"."calendar_days" (
|
|
|
27
27
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
28
28
|
);
|
|
29
29
|
--> statement-breakpoint
|
|
30
|
-
CREATE TABLE "mod_hr"."calendars" (
|
|
30
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."calendars" (
|
|
31
31
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
32
32
|
"workspace_id" uuid NOT NULL,
|
|
33
33
|
"name" text NOT NULL,
|
|
@@ -43,7 +43,7 @@ CREATE TABLE "mod_hr"."calendars" (
|
|
|
43
43
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
44
44
|
);
|
|
45
45
|
--> statement-breakpoint
|
|
46
|
-
CREATE TABLE "mod_hr"."cost_centers" (
|
|
46
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."cost_centers" (
|
|
47
47
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
48
48
|
"workspace_id" uuid NOT NULL,
|
|
49
49
|
"code" text NOT NULL,
|
|
@@ -55,7 +55,7 @@ CREATE TABLE "mod_hr"."cost_centers" (
|
|
|
55
55
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
56
56
|
);
|
|
57
57
|
--> statement-breakpoint
|
|
58
|
-
CREATE TABLE "mod_hr"."custom_field_defs" (
|
|
58
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."custom_field_defs" (
|
|
59
59
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
60
60
|
"workspace_id" uuid NOT NULL,
|
|
61
61
|
"key" text NOT NULL,
|
|
@@ -70,7 +70,7 @@ CREATE TABLE "mod_hr"."custom_field_defs" (
|
|
|
70
70
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
71
71
|
);
|
|
72
72
|
--> statement-breakpoint
|
|
73
|
-
CREATE TABLE "mod_hr"."employments" (
|
|
73
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."employments" (
|
|
74
74
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
75
75
|
"workspace_id" uuid NOT NULL,
|
|
76
76
|
"person_id" uuid NOT NULL,
|
|
@@ -88,7 +88,7 @@ CREATE TABLE "mod_hr"."employments" (
|
|
|
88
88
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
89
89
|
);
|
|
90
90
|
--> statement-breakpoint
|
|
91
|
-
CREATE TABLE "mod_hr"."legal_entities" (
|
|
91
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."legal_entities" (
|
|
92
92
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
93
93
|
"workspace_id" uuid NOT NULL,
|
|
94
94
|
"name" text NOT NULL,
|
|
@@ -101,7 +101,7 @@ CREATE TABLE "mod_hr"."legal_entities" (
|
|
|
101
101
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
102
102
|
);
|
|
103
103
|
--> statement-breakpoint
|
|
104
|
-
CREATE TABLE "mod_hr"."office_assignments" (
|
|
104
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."office_assignments" (
|
|
105
105
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
106
106
|
"workspace_id" uuid NOT NULL,
|
|
107
107
|
"person_id" uuid NOT NULL,
|
|
@@ -113,7 +113,7 @@ CREATE TABLE "mod_hr"."office_assignments" (
|
|
|
113
113
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
114
114
|
);
|
|
115
115
|
--> statement-breakpoint
|
|
116
|
-
CREATE TABLE "mod_hr"."offices" (
|
|
116
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."offices" (
|
|
117
117
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
118
118
|
"workspace_id" uuid NOT NULL,
|
|
119
119
|
"name" text NOT NULL,
|
|
@@ -134,7 +134,7 @@ CREATE TABLE "mod_hr"."offices" (
|
|
|
134
134
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
135
135
|
);
|
|
136
136
|
--> statement-breakpoint
|
|
137
|
-
CREATE TABLE "mod_hr"."org_units" (
|
|
137
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."org_units" (
|
|
138
138
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
139
139
|
"workspace_id" uuid NOT NULL,
|
|
140
140
|
"parent_id" uuid,
|
|
@@ -147,7 +147,7 @@ CREATE TABLE "mod_hr"."org_units" (
|
|
|
147
147
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
148
148
|
);
|
|
149
149
|
--> statement-breakpoint
|
|
150
|
-
CREATE TABLE "mod_hr"."people" (
|
|
150
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."people" (
|
|
151
151
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
152
152
|
"workspace_id" uuid NOT NULL,
|
|
153
153
|
"user_id" uuid,
|
|
@@ -166,7 +166,7 @@ CREATE TABLE "mod_hr"."people" (
|
|
|
166
166
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
167
167
|
);
|
|
168
168
|
--> statement-breakpoint
|
|
169
|
-
CREATE TABLE "mod_hr"."people_sensitive" (
|
|
169
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."people_sensitive" (
|
|
170
170
|
"person_id" uuid PRIMARY KEY NOT NULL,
|
|
171
171
|
"workspace_id" uuid NOT NULL,
|
|
172
172
|
"national_id_enc" text,
|
|
@@ -176,7 +176,7 @@ CREATE TABLE "mod_hr"."people_sensitive" (
|
|
|
176
176
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
177
177
|
);
|
|
178
178
|
--> statement-breakpoint
|
|
179
|
-
CREATE TABLE "mod_hr"."person_documents" (
|
|
179
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."person_documents" (
|
|
180
180
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
181
181
|
"workspace_id" uuid NOT NULL,
|
|
182
182
|
"person_id" uuid NOT NULL,
|
|
@@ -189,7 +189,7 @@ CREATE TABLE "mod_hr"."person_documents" (
|
|
|
189
189
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
190
190
|
);
|
|
191
191
|
--> statement-breakpoint
|
|
192
|
-
CREATE TABLE "mod_hr"."person_history" (
|
|
192
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."person_history" (
|
|
193
193
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
194
194
|
"workspace_id" uuid NOT NULL,
|
|
195
195
|
"person_id" uuid NOT NULL,
|
|
@@ -201,7 +201,7 @@ CREATE TABLE "mod_hr"."person_history" (
|
|
|
201
201
|
"source" text DEFAULT 'app' NOT NULL
|
|
202
202
|
);
|
|
203
203
|
--> statement-breakpoint
|
|
204
|
-
CREATE TABLE "mod_hr"."positions" (
|
|
204
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."positions" (
|
|
205
205
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
206
206
|
"workspace_id" uuid NOT NULL,
|
|
207
207
|
"title" text NOT NULL,
|
|
@@ -212,25 +212,25 @@ CREATE TABLE "mod_hr"."positions" (
|
|
|
212
212
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
213
213
|
);
|
|
214
214
|
--> statement-breakpoint
|
|
215
|
-
CREATE INDEX "hr_calendar_days_idx" ON "mod_hr"."calendar_days" USING btree ("workspace_id","calendar_id","date");--> statement-breakpoint
|
|
216
|
-
CREATE UNIQUE INDEX "hr_calendar_days_uq" ON "mod_hr"."calendar_days" USING btree ("calendar_id","date","kind");--> statement-breakpoint
|
|
217
|
-
CREATE INDEX "hr_calendars_ws_idx" ON "mod_hr"."calendars" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
218
|
-
CREATE UNIQUE INDEX "hr_cost_centers_ws_code_uq" ON "mod_hr"."cost_centers" USING btree ("workspace_id","code");--> statement-breakpoint
|
|
219
|
-
CREATE UNIQUE INDEX "hr_fields_ws_key_uq" ON "mod_hr"."custom_field_defs" USING btree ("workspace_id","key");--> statement-breakpoint
|
|
220
|
-
CREATE INDEX "hr_employments_person_idx" ON "mod_hr"."employments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
221
|
-
CREATE INDEX "hr_employments_ws_manager_idx" ON "mod_hr"."employments" USING btree ("workspace_id","manager_person_id");--> statement-breakpoint
|
|
222
|
-
CREATE INDEX "hr_employments_ws_unit_idx" ON "mod_hr"."employments" USING btree ("workspace_id","org_unit_id");--> statement-breakpoint
|
|
223
|
-
CREATE INDEX "hr_entities_ws_idx" ON "mod_hr"."legal_entities" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
224
|
-
CREATE INDEX "hr_office_assign_person_idx" ON "mod_hr"."office_assignments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
225
|
-
CREATE INDEX "hr_office_assign_office_idx" ON "mod_hr"."office_assignments" USING btree ("workspace_id","office_id","effective_from");--> statement-breakpoint
|
|
226
|
-
CREATE INDEX "hr_offices_ws_idx" ON "mod_hr"."offices" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
227
|
-
CREATE INDEX "hr_offices_ws_country_idx" ON "mod_hr"."offices" USING btree ("workspace_id","country");--> statement-breakpoint
|
|
228
|
-
CREATE INDEX "hr_org_units_ws_idx" ON "mod_hr"."org_units" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
229
|
-
CREATE INDEX "hr_people_ws_status_idx" ON "mod_hr"."people" USING btree ("workspace_id","status","display_name");--> statement-breakpoint
|
|
230
|
-
CREATE UNIQUE INDEX "hr_people_ws_user_uq" ON "mod_hr"."people" USING btree ("workspace_id","user_id");--> statement-breakpoint
|
|
231
|
-
CREATE UNIQUE INDEX "hr_people_ws_empno_uq" ON "mod_hr"."people" USING btree ("workspace_id","employee_no");--> statement-breakpoint
|
|
232
|
-
CREATE INDEX "hr_people_sensitive_ws_idx" ON "mod_hr"."people_sensitive" USING btree ("workspace_id");--> statement-breakpoint
|
|
233
|
-
CREATE INDEX "hr_person_docs_idx" ON "mod_hr"."person_documents" USING btree ("workspace_id","person_id","created_at");--> statement-breakpoint
|
|
234
|
-
CREATE INDEX "hr_person_docs_expiry_idx" ON "mod_hr"."person_documents" USING btree ("workspace_id","expires_on");--> statement-breakpoint
|
|
235
|
-
CREATE INDEX "hr_person_history_idx" ON "mod_hr"."person_history" USING btree ("workspace_id","person_id","created_at");--> statement-breakpoint
|
|
236
|
-
CREATE INDEX "hr_positions_ws_idx" ON "mod_hr"."positions" USING btree ("workspace_id","archived_at");
|
|
215
|
+
CREATE INDEX IF NOT EXISTS "hr_calendar_days_idx" ON "mod_hr"."calendar_days" USING btree ("workspace_id","calendar_id","date");--> statement-breakpoint
|
|
216
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_calendar_days_uq" ON "mod_hr"."calendar_days" USING btree ("calendar_id","date","kind");--> statement-breakpoint
|
|
217
|
+
CREATE INDEX IF NOT EXISTS "hr_calendars_ws_idx" ON "mod_hr"."calendars" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
218
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_cost_centers_ws_code_uq" ON "mod_hr"."cost_centers" USING btree ("workspace_id","code");--> statement-breakpoint
|
|
219
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_fields_ws_key_uq" ON "mod_hr"."custom_field_defs" USING btree ("workspace_id","key");--> statement-breakpoint
|
|
220
|
+
CREATE INDEX IF NOT EXISTS "hr_employments_person_idx" ON "mod_hr"."employments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
221
|
+
CREATE INDEX IF NOT EXISTS "hr_employments_ws_manager_idx" ON "mod_hr"."employments" USING btree ("workspace_id","manager_person_id");--> statement-breakpoint
|
|
222
|
+
CREATE INDEX IF NOT EXISTS "hr_employments_ws_unit_idx" ON "mod_hr"."employments" USING btree ("workspace_id","org_unit_id");--> statement-breakpoint
|
|
223
|
+
CREATE INDEX IF NOT EXISTS "hr_entities_ws_idx" ON "mod_hr"."legal_entities" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
224
|
+
CREATE INDEX IF NOT EXISTS "hr_office_assign_person_idx" ON "mod_hr"."office_assignments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
225
|
+
CREATE INDEX IF NOT EXISTS "hr_office_assign_office_idx" ON "mod_hr"."office_assignments" USING btree ("workspace_id","office_id","effective_from");--> statement-breakpoint
|
|
226
|
+
CREATE INDEX IF NOT EXISTS "hr_offices_ws_idx" ON "mod_hr"."offices" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
227
|
+
CREATE INDEX IF NOT EXISTS "hr_offices_ws_country_idx" ON "mod_hr"."offices" USING btree ("workspace_id","country");--> statement-breakpoint
|
|
228
|
+
CREATE INDEX IF NOT EXISTS "hr_org_units_ws_idx" ON "mod_hr"."org_units" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
229
|
+
CREATE INDEX IF NOT EXISTS "hr_people_ws_status_idx" ON "mod_hr"."people" USING btree ("workspace_id","status","display_name");--> statement-breakpoint
|
|
230
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_people_ws_user_uq" ON "mod_hr"."people" USING btree ("workspace_id","user_id");--> statement-breakpoint
|
|
231
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_people_ws_empno_uq" ON "mod_hr"."people" USING btree ("workspace_id","employee_no");--> statement-breakpoint
|
|
232
|
+
CREATE INDEX IF NOT EXISTS "hr_people_sensitive_ws_idx" ON "mod_hr"."people_sensitive" USING btree ("workspace_id");--> statement-breakpoint
|
|
233
|
+
CREATE INDEX IF NOT EXISTS "hr_person_docs_idx" ON "mod_hr"."person_documents" USING btree ("workspace_id","person_id","created_at");--> statement-breakpoint
|
|
234
|
+
CREATE INDEX IF NOT EXISTS "hr_person_docs_expiry_idx" ON "mod_hr"."person_documents" USING btree ("workspace_id","expires_on");--> statement-breakpoint
|
|
235
|
+
CREATE INDEX IF NOT EXISTS "hr_person_history_idx" ON "mod_hr"."person_history" USING btree ("workspace_id","person_id","created_at");--> statement-breakpoint
|
|
236
|
+
CREATE INDEX IF NOT EXISTS "hr_positions_ws_idx" ON "mod_hr"."positions" USING btree ("workspace_id","archived_at");
|
package/migrations/0001_rls.sql
CHANGED
|
@@ -9,84 +9,112 @@
|
|
|
9
9
|
|
|
10
10
|
alter table "mod_hr"."legal_entities" enable row level security;--> statement-breakpoint
|
|
11
11
|
alter table "mod_hr"."legal_entities" force row level security;--> statement-breakpoint
|
|
12
|
+
drop policy if exists "legal_entities_ws_isolation" on "mod_hr"."legal_entities";
|
|
13
|
+
--> statement-breakpoint
|
|
12
14
|
create policy "legal_entities_ws_isolation" on "mod_hr"."legal_entities"
|
|
13
15
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
14
16
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
15
17
|
|
|
16
18
|
alter table "mod_hr"."offices" enable row level security;--> statement-breakpoint
|
|
17
19
|
alter table "mod_hr"."offices" force row level security;--> statement-breakpoint
|
|
20
|
+
drop policy if exists "offices_ws_isolation" on "mod_hr"."offices";
|
|
21
|
+
--> statement-breakpoint
|
|
18
22
|
create policy "offices_ws_isolation" on "mod_hr"."offices"
|
|
19
23
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
20
24
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
21
25
|
|
|
22
26
|
alter table "mod_hr"."cost_centers" enable row level security;--> statement-breakpoint
|
|
23
27
|
alter table "mod_hr"."cost_centers" force row level security;--> statement-breakpoint
|
|
28
|
+
drop policy if exists "cost_centers_ws_isolation" on "mod_hr"."cost_centers";
|
|
29
|
+
--> statement-breakpoint
|
|
24
30
|
create policy "cost_centers_ws_isolation" on "mod_hr"."cost_centers"
|
|
25
31
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
26
32
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
27
33
|
|
|
28
34
|
alter table "mod_hr"."org_units" enable row level security;--> statement-breakpoint
|
|
29
35
|
alter table "mod_hr"."org_units" force row level security;--> statement-breakpoint
|
|
36
|
+
drop policy if exists "org_units_ws_isolation" on "mod_hr"."org_units";
|
|
37
|
+
--> statement-breakpoint
|
|
30
38
|
create policy "org_units_ws_isolation" on "mod_hr"."org_units"
|
|
31
39
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
32
40
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
33
41
|
|
|
34
42
|
alter table "mod_hr"."positions" enable row level security;--> statement-breakpoint
|
|
35
43
|
alter table "mod_hr"."positions" force row level security;--> statement-breakpoint
|
|
44
|
+
drop policy if exists "positions_ws_isolation" on "mod_hr"."positions";
|
|
45
|
+
--> statement-breakpoint
|
|
36
46
|
create policy "positions_ws_isolation" on "mod_hr"."positions"
|
|
37
47
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
38
48
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
39
49
|
|
|
40
50
|
alter table "mod_hr"."people" enable row level security;--> statement-breakpoint
|
|
41
51
|
alter table "mod_hr"."people" force row level security;--> statement-breakpoint
|
|
52
|
+
drop policy if exists "people_ws_isolation" on "mod_hr"."people";
|
|
53
|
+
--> statement-breakpoint
|
|
42
54
|
create policy "people_ws_isolation" on "mod_hr"."people"
|
|
43
55
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
44
56
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
45
57
|
|
|
46
58
|
alter table "mod_hr"."people_sensitive" enable row level security;--> statement-breakpoint
|
|
47
59
|
alter table "mod_hr"."people_sensitive" force row level security;--> statement-breakpoint
|
|
60
|
+
drop policy if exists "people_sensitive_ws_isolation" on "mod_hr"."people_sensitive";
|
|
61
|
+
--> statement-breakpoint
|
|
48
62
|
create policy "people_sensitive_ws_isolation" on "mod_hr"."people_sensitive"
|
|
49
63
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
50
64
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
51
65
|
|
|
52
66
|
alter table "mod_hr"."employments" enable row level security;--> statement-breakpoint
|
|
53
67
|
alter table "mod_hr"."employments" force row level security;--> statement-breakpoint
|
|
68
|
+
drop policy if exists "employments_ws_isolation" on "mod_hr"."employments";
|
|
69
|
+
--> statement-breakpoint
|
|
54
70
|
create policy "employments_ws_isolation" on "mod_hr"."employments"
|
|
55
71
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
56
72
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
57
73
|
|
|
58
74
|
alter table "mod_hr"."office_assignments" enable row level security;--> statement-breakpoint
|
|
59
75
|
alter table "mod_hr"."office_assignments" force row level security;--> statement-breakpoint
|
|
76
|
+
drop policy if exists "office_assignments_ws_isolation" on "mod_hr"."office_assignments";
|
|
77
|
+
--> statement-breakpoint
|
|
60
78
|
create policy "office_assignments_ws_isolation" on "mod_hr"."office_assignments"
|
|
61
79
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
62
80
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
63
81
|
|
|
64
82
|
alter table "mod_hr"."person_history" enable row level security;--> statement-breakpoint
|
|
65
83
|
alter table "mod_hr"."person_history" force row level security;--> statement-breakpoint
|
|
84
|
+
drop policy if exists "person_history_ws_isolation" on "mod_hr"."person_history";
|
|
85
|
+
--> statement-breakpoint
|
|
66
86
|
create policy "person_history_ws_isolation" on "mod_hr"."person_history"
|
|
67
87
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
68
88
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
69
89
|
|
|
70
90
|
alter table "mod_hr"."person_documents" enable row level security;--> statement-breakpoint
|
|
71
91
|
alter table "mod_hr"."person_documents" force row level security;--> statement-breakpoint
|
|
92
|
+
drop policy if exists "person_documents_ws_isolation" on "mod_hr"."person_documents";
|
|
93
|
+
--> statement-breakpoint
|
|
72
94
|
create policy "person_documents_ws_isolation" on "mod_hr"."person_documents"
|
|
73
95
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
74
96
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
75
97
|
|
|
76
98
|
alter table "mod_hr"."custom_field_defs" enable row level security;--> statement-breakpoint
|
|
77
99
|
alter table "mod_hr"."custom_field_defs" force row level security;--> statement-breakpoint
|
|
100
|
+
drop policy if exists "custom_field_defs_ws_isolation" on "mod_hr"."custom_field_defs";
|
|
101
|
+
--> statement-breakpoint
|
|
78
102
|
create policy "custom_field_defs_ws_isolation" on "mod_hr"."custom_field_defs"
|
|
79
103
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
80
104
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
81
105
|
|
|
82
106
|
alter table "mod_hr"."calendars" enable row level security;--> statement-breakpoint
|
|
83
107
|
alter table "mod_hr"."calendars" force row level security;--> statement-breakpoint
|
|
108
|
+
drop policy if exists "calendars_ws_isolation" on "mod_hr"."calendars";
|
|
109
|
+
--> statement-breakpoint
|
|
84
110
|
create policy "calendars_ws_isolation" on "mod_hr"."calendars"
|
|
85
111
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
86
112
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
87
113
|
|
|
88
114
|
alter table "mod_hr"."calendar_days" enable row level security;--> statement-breakpoint
|
|
89
115
|
alter table "mod_hr"."calendar_days" force row level security;--> statement-breakpoint
|
|
116
|
+
drop policy if exists "calendar_days_ws_isolation" on "mod_hr"."calendar_days";
|
|
117
|
+
--> statement-breakpoint
|
|
90
118
|
create policy "calendar_days_ws_isolation" on "mod_hr"."calendar_days"
|
|
91
119
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
92
120
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
@@ -100,13 +128,15 @@ create policy "calendar_days_ws_isolation" on "mod_hr"."calendar_days"
|
|
|
100
128
|
|
|
101
129
|
-- One workspace, one default office. It is where a person with no assignment lands and where the
|
|
102
130
|
-- resolution ladder bottoms out, so two of them would make "which calendar applies" ambiguous.
|
|
103
|
-
|
|
131
|
+
CREATE unique INDEX IF NOT EXISTS "hr_offices_one_default_per_ws"
|
|
104
132
|
on "mod_hr"."offices" (workspace_id)
|
|
105
133
|
where is_default;--> statement-breakpoint
|
|
106
134
|
|
|
107
135
|
-- No two employment rows for one person may overlap. Without this, a backdated correction racing a
|
|
108
136
|
-- forward-dated change leaves two rows in force on the same day, and "what was her FTE in March"
|
|
109
137
|
-- has two answers.
|
|
138
|
+
alter table "mod_hr"."employments" drop constraint if exists "hr_employments_no_overlap";
|
|
139
|
+
--> statement-breakpoint
|
|
110
140
|
alter table "mod_hr"."employments"
|
|
111
141
|
add constraint "hr_employments_no_overlap"
|
|
112
142
|
exclude using gist (
|
|
@@ -115,6 +145,8 @@ alter table "mod_hr"."employments"
|
|
|
115
145
|
);--> statement-breakpoint
|
|
116
146
|
|
|
117
147
|
-- Nor may one person hold the same office twice over an overlapping period.
|
|
148
|
+
alter table "mod_hr"."office_assignments" drop constraint if exists "hr_office_assignments_no_duplicate";
|
|
149
|
+
--> statement-breakpoint
|
|
118
150
|
alter table "mod_hr"."office_assignments"
|
|
119
151
|
add constraint "hr_office_assignments_no_duplicate"
|
|
120
152
|
exclude using gist (
|
|
@@ -126,6 +158,8 @@ alter table "mod_hr"."office_assignments"
|
|
|
126
158
|
-- And exactly one of a person's concurrent assignments may be primary. Only the primary office
|
|
127
159
|
-- decides holidays, timezone and policy; two would mean two answers, which is the one thing the
|
|
128
160
|
-- multi-office model must never allow.
|
|
161
|
+
alter table "mod_hr"."office_assignments" drop constraint if exists "hr_office_assignments_one_primary";
|
|
162
|
+
--> statement-breakpoint
|
|
129
163
|
alter table "mod_hr"."office_assignments"
|
|
130
164
|
add constraint "hr_office_assignments_one_primary"
|
|
131
165
|
exclude using gist (
|
|
@@ -135,5 +169,5 @@ alter table "mod_hr"."office_assignments"
|
|
|
135
169
|
|
|
136
170
|
-- An org unit's ltree path is unique within a workspace: two departments at the same path would
|
|
137
171
|
-- make a subtree query return one of them arbitrarily.
|
|
138
|
-
|
|
139
|
-
|
|
172
|
+
CREATE unique INDEX IF NOT EXISTS "hr_org_units_ws_path_uq" on "mod_hr"."org_units" (workspace_id, path);--> statement-breakpoint
|
|
173
|
+
CREATE INDEX IF NOT EXISTS "hr_org_units_path_gist" on "mod_hr"."org_units" using gist (path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CREATE TABLE "mod_hr"."approval_chains" (
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."approval_chains" (
|
|
2
2
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
3
3
|
"workspace_id" uuid NOT NULL,
|
|
4
4
|
"name" text NOT NULL,
|
|
@@ -10,7 +10,7 @@ CREATE TABLE "mod_hr"."approval_chains" (
|
|
|
10
10
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
11
11
|
);
|
|
12
12
|
--> statement-breakpoint
|
|
13
|
-
CREATE TABLE "mod_hr"."approval_decisions" (
|
|
13
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."approval_decisions" (
|
|
14
14
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
15
15
|
"workspace_id" uuid NOT NULL,
|
|
16
16
|
"step_id" uuid NOT NULL,
|
|
@@ -21,7 +21,7 @@ CREATE TABLE "mod_hr"."approval_decisions" (
|
|
|
21
21
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
22
22
|
);
|
|
23
23
|
--> statement-breakpoint
|
|
24
|
-
CREATE TABLE "mod_hr"."approval_requests" (
|
|
24
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."approval_requests" (
|
|
25
25
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
26
26
|
"workspace_id" uuid NOT NULL,
|
|
27
27
|
"subject_type" text NOT NULL,
|
|
@@ -36,7 +36,7 @@ CREATE TABLE "mod_hr"."approval_requests" (
|
|
|
36
36
|
"version" integer DEFAULT 0 NOT NULL
|
|
37
37
|
);
|
|
38
38
|
--> statement-breakpoint
|
|
39
|
-
CREATE TABLE "mod_hr"."approval_steps" (
|
|
39
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."approval_steps" (
|
|
40
40
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
41
41
|
"workspace_id" uuid NOT NULL,
|
|
42
42
|
"request_id" uuid NOT NULL,
|
|
@@ -50,7 +50,7 @@ CREATE TABLE "mod_hr"."approval_steps" (
|
|
|
50
50
|
"escalated_at" timestamp with time zone
|
|
51
51
|
);
|
|
52
52
|
--> statement-breakpoint
|
|
53
|
-
CREATE TABLE "mod_hr"."delegations" (
|
|
53
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."delegations" (
|
|
54
54
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
55
55
|
"workspace_id" uuid NOT NULL,
|
|
56
56
|
"from_person_id" uuid NOT NULL,
|
|
@@ -62,7 +62,7 @@ CREATE TABLE "mod_hr"."delegations" (
|
|
|
62
62
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
63
63
|
);
|
|
64
64
|
--> statement-breakpoint
|
|
65
|
-
CREATE TABLE "mod_hr"."leave_balance_cursor" (
|
|
65
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."leave_balance_cursor" (
|
|
66
66
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
67
67
|
"workspace_id" uuid NOT NULL,
|
|
68
68
|
"person_id" uuid NOT NULL,
|
|
@@ -74,7 +74,7 @@ CREATE TABLE "mod_hr"."leave_balance_cursor" (
|
|
|
74
74
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
75
75
|
);
|
|
76
76
|
--> statement-breakpoint
|
|
77
|
-
CREATE TABLE "mod_hr"."leave_ledger" (
|
|
77
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."leave_ledger" (
|
|
78
78
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
79
79
|
"workspace_id" uuid NOT NULL,
|
|
80
80
|
"person_id" uuid NOT NULL,
|
|
@@ -91,7 +91,7 @@ CREATE TABLE "mod_hr"."leave_ledger" (
|
|
|
91
91
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
92
92
|
);
|
|
93
93
|
--> statement-breakpoint
|
|
94
|
-
CREATE TABLE "mod_hr"."leave_request_days" (
|
|
94
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."leave_request_days" (
|
|
95
95
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
96
96
|
"workspace_id" uuid NOT NULL,
|
|
97
97
|
"request_id" uuid NOT NULL,
|
|
@@ -102,7 +102,7 @@ CREATE TABLE "mod_hr"."leave_request_days" (
|
|
|
102
102
|
"status" text DEFAULT 'pending' NOT NULL
|
|
103
103
|
);
|
|
104
104
|
--> statement-breakpoint
|
|
105
|
-
CREATE TABLE "mod_hr"."leave_requests" (
|
|
105
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."leave_requests" (
|
|
106
106
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
107
107
|
"workspace_id" uuid NOT NULL,
|
|
108
108
|
"person_id" uuid NOT NULL,
|
|
@@ -124,7 +124,7 @@ CREATE TABLE "mod_hr"."leave_requests" (
|
|
|
124
124
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
125
125
|
);
|
|
126
126
|
--> statement-breakpoint
|
|
127
|
-
CREATE TABLE "mod_hr"."leave_types" (
|
|
127
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."leave_types" (
|
|
128
128
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
129
129
|
"workspace_id" uuid NOT NULL,
|
|
130
130
|
"key" text NOT NULL,
|
|
@@ -143,81 +143,101 @@ CREATE TABLE "mod_hr"."leave_types" (
|
|
|
143
143
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
144
144
|
);
|
|
145
145
|
--> statement-breakpoint
|
|
146
|
-
CREATE INDEX "hr_approval_chains_idx" ON "mod_hr"."approval_chains" USING btree ("workspace_id","subject_type","archived_at");--> statement-breakpoint
|
|
147
|
-
CREATE UNIQUE INDEX "hr_approval_decisions_uq" ON "mod_hr"."approval_decisions" USING btree ("step_id","approver_id");--> statement-breakpoint
|
|
148
|
-
CREATE INDEX "hr_approval_requests_subject_idx" ON "mod_hr"."approval_requests" USING btree ("workspace_id","subject_type","subject_id");--> statement-breakpoint
|
|
149
|
-
CREATE INDEX "hr_approval_requests_status_idx" ON "mod_hr"."approval_requests" USING btree ("workspace_id","status");--> statement-breakpoint
|
|
150
|
-
CREATE UNIQUE INDEX "hr_approval_steps_uq" ON "mod_hr"."approval_steps" USING btree ("request_id","step_index");--> statement-breakpoint
|
|
151
|
-
CREATE INDEX "hr_approval_steps_due_idx" ON "mod_hr"."approval_steps" USING btree ("workspace_id","status","due_at");--> statement-breakpoint
|
|
152
|
-
CREATE INDEX "hr_delegations_idx" ON "mod_hr"."delegations" USING btree ("workspace_id","to_person_id","starts_on");--> statement-breakpoint
|
|
153
|
-
CREATE UNIQUE INDEX "hr_balance_cursor_uq" ON "mod_hr"."leave_balance_cursor" USING btree ("workspace_id","person_id","leave_type_id","period_year");--> statement-breakpoint
|
|
154
|
-
CREATE INDEX "hr_ledger_person_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","person_id","leave_type_id","effective_on");--> statement-breakpoint
|
|
155
|
-
CREATE INDEX "hr_ledger_request_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","request_id");--> statement-breakpoint
|
|
156
|
-
CREATE INDEX "hr_ledger_year_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","period_year");--> statement-breakpoint
|
|
157
|
-
CREATE INDEX "hr_leave_days_person_idx" ON "mod_hr"."leave_request_days" USING btree ("workspace_id","person_id","date");--> statement-breakpoint
|
|
158
|
-
CREATE INDEX "hr_leave_days_request_idx" ON "mod_hr"."leave_request_days" USING btree ("request_id");--> statement-breakpoint
|
|
159
|
-
CREATE INDEX "hr_leave_requests_person_idx" ON "mod_hr"."leave_requests" USING btree ("workspace_id","person_id","starts_on");--> statement-breakpoint
|
|
160
|
-
CREATE INDEX "hr_leave_requests_status_idx" ON "mod_hr"."leave_requests" USING btree ("workspace_id","status","starts_on");--> statement-breakpoint
|
|
161
|
-
CREATE UNIQUE INDEX "hr_leave_requests_idem_uq" ON "mod_hr"."leave_requests" USING btree ("workspace_id","idempotency_key");--> statement-breakpoint
|
|
162
|
-
CREATE UNIQUE INDEX "hr_leave_types_ws_key_uq" ON "mod_hr"."leave_types" USING btree ("workspace_id","key");--> statement-breakpoint
|
|
146
|
+
CREATE INDEX IF NOT EXISTS "hr_approval_chains_idx" ON "mod_hr"."approval_chains" USING btree ("workspace_id","subject_type","archived_at");--> statement-breakpoint
|
|
147
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_approval_decisions_uq" ON "mod_hr"."approval_decisions" USING btree ("step_id","approver_id");--> statement-breakpoint
|
|
148
|
+
CREATE INDEX IF NOT EXISTS "hr_approval_requests_subject_idx" ON "mod_hr"."approval_requests" USING btree ("workspace_id","subject_type","subject_id");--> statement-breakpoint
|
|
149
|
+
CREATE INDEX IF NOT EXISTS "hr_approval_requests_status_idx" ON "mod_hr"."approval_requests" USING btree ("workspace_id","status");--> statement-breakpoint
|
|
150
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_approval_steps_uq" ON "mod_hr"."approval_steps" USING btree ("request_id","step_index");--> statement-breakpoint
|
|
151
|
+
CREATE INDEX IF NOT EXISTS "hr_approval_steps_due_idx" ON "mod_hr"."approval_steps" USING btree ("workspace_id","status","due_at");--> statement-breakpoint
|
|
152
|
+
CREATE INDEX IF NOT EXISTS "hr_delegations_idx" ON "mod_hr"."delegations" USING btree ("workspace_id","to_person_id","starts_on");--> statement-breakpoint
|
|
153
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_balance_cursor_uq" ON "mod_hr"."leave_balance_cursor" USING btree ("workspace_id","person_id","leave_type_id","period_year");--> statement-breakpoint
|
|
154
|
+
CREATE INDEX IF NOT EXISTS "hr_ledger_person_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","person_id","leave_type_id","effective_on");--> statement-breakpoint
|
|
155
|
+
CREATE INDEX IF NOT EXISTS "hr_ledger_request_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","request_id");--> statement-breakpoint
|
|
156
|
+
CREATE INDEX IF NOT EXISTS "hr_ledger_year_idx" ON "mod_hr"."leave_ledger" USING btree ("workspace_id","period_year");--> statement-breakpoint
|
|
157
|
+
CREATE INDEX IF NOT EXISTS "hr_leave_days_person_idx" ON "mod_hr"."leave_request_days" USING btree ("workspace_id","person_id","date");--> statement-breakpoint
|
|
158
|
+
CREATE INDEX IF NOT EXISTS "hr_leave_days_request_idx" ON "mod_hr"."leave_request_days" USING btree ("request_id");--> statement-breakpoint
|
|
159
|
+
CREATE INDEX IF NOT EXISTS "hr_leave_requests_person_idx" ON "mod_hr"."leave_requests" USING btree ("workspace_id","person_id","starts_on");--> statement-breakpoint
|
|
160
|
+
CREATE INDEX IF NOT EXISTS "hr_leave_requests_status_idx" ON "mod_hr"."leave_requests" USING btree ("workspace_id","status","starts_on");--> statement-breakpoint
|
|
161
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_leave_requests_idem_uq" ON "mod_hr"."leave_requests" USING btree ("workspace_id","idempotency_key");--> statement-breakpoint
|
|
162
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_leave_types_ws_key_uq" ON "mod_hr"."leave_types" USING btree ("workspace_id","key");--> statement-breakpoint
|
|
163
163
|
-- ---------------------------------------------------------------------------------------------
|
|
164
164
|
-- Row-level security on the new tenant tables.
|
|
165
165
|
alter table "mod_hr"."leave_types" enable row level security;--> statement-breakpoint
|
|
166
166
|
alter table "mod_hr"."leave_types" force row level security;--> statement-breakpoint
|
|
167
|
+
drop policy if exists "leave_types_ws_isolation" on "mod_hr"."leave_types";
|
|
168
|
+
--> statement-breakpoint
|
|
167
169
|
create policy "leave_types_ws_isolation" on "mod_hr"."leave_types"
|
|
168
170
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
169
171
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
170
172
|
|
|
171
173
|
alter table "mod_hr"."leave_ledger" enable row level security;--> statement-breakpoint
|
|
172
174
|
alter table "mod_hr"."leave_ledger" force row level security;--> statement-breakpoint
|
|
175
|
+
drop policy if exists "leave_ledger_ws_isolation" on "mod_hr"."leave_ledger";
|
|
176
|
+
--> statement-breakpoint
|
|
173
177
|
create policy "leave_ledger_ws_isolation" on "mod_hr"."leave_ledger"
|
|
174
178
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
175
179
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
176
180
|
|
|
177
181
|
alter table "mod_hr"."leave_balance_cursor" enable row level security;--> statement-breakpoint
|
|
178
182
|
alter table "mod_hr"."leave_balance_cursor" force row level security;--> statement-breakpoint
|
|
183
|
+
drop policy if exists "leave_balance_cursor_ws_isolation" on "mod_hr"."leave_balance_cursor";
|
|
184
|
+
--> statement-breakpoint
|
|
179
185
|
create policy "leave_balance_cursor_ws_isolation" on "mod_hr"."leave_balance_cursor"
|
|
180
186
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
181
187
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
182
188
|
|
|
183
189
|
alter table "mod_hr"."leave_requests" enable row level security;--> statement-breakpoint
|
|
184
190
|
alter table "mod_hr"."leave_requests" force row level security;--> statement-breakpoint
|
|
191
|
+
drop policy if exists "leave_requests_ws_isolation" on "mod_hr"."leave_requests";
|
|
192
|
+
--> statement-breakpoint
|
|
185
193
|
create policy "leave_requests_ws_isolation" on "mod_hr"."leave_requests"
|
|
186
194
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
187
195
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
188
196
|
|
|
189
197
|
alter table "mod_hr"."leave_request_days" enable row level security;--> statement-breakpoint
|
|
190
198
|
alter table "mod_hr"."leave_request_days" force row level security;--> statement-breakpoint
|
|
199
|
+
drop policy if exists "leave_request_days_ws_isolation" on "mod_hr"."leave_request_days";
|
|
200
|
+
--> statement-breakpoint
|
|
191
201
|
create policy "leave_request_days_ws_isolation" on "mod_hr"."leave_request_days"
|
|
192
202
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
193
203
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
194
204
|
|
|
195
205
|
alter table "mod_hr"."approval_chains" enable row level security;--> statement-breakpoint
|
|
196
206
|
alter table "mod_hr"."approval_chains" force row level security;--> statement-breakpoint
|
|
207
|
+
drop policy if exists "approval_chains_ws_isolation" on "mod_hr"."approval_chains";
|
|
208
|
+
--> statement-breakpoint
|
|
197
209
|
create policy "approval_chains_ws_isolation" on "mod_hr"."approval_chains"
|
|
198
210
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
199
211
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
200
212
|
|
|
201
213
|
alter table "mod_hr"."approval_requests" enable row level security;--> statement-breakpoint
|
|
202
214
|
alter table "mod_hr"."approval_requests" force row level security;--> statement-breakpoint
|
|
215
|
+
drop policy if exists "approval_requests_ws_isolation" on "mod_hr"."approval_requests";
|
|
216
|
+
--> statement-breakpoint
|
|
203
217
|
create policy "approval_requests_ws_isolation" on "mod_hr"."approval_requests"
|
|
204
218
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
205
219
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
206
220
|
|
|
207
221
|
alter table "mod_hr"."approval_steps" enable row level security;--> statement-breakpoint
|
|
208
222
|
alter table "mod_hr"."approval_steps" force row level security;--> statement-breakpoint
|
|
223
|
+
drop policy if exists "approval_steps_ws_isolation" on "mod_hr"."approval_steps";
|
|
224
|
+
--> statement-breakpoint
|
|
209
225
|
create policy "approval_steps_ws_isolation" on "mod_hr"."approval_steps"
|
|
210
226
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
211
227
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
212
228
|
|
|
213
229
|
alter table "mod_hr"."approval_decisions" enable row level security;--> statement-breakpoint
|
|
214
230
|
alter table "mod_hr"."approval_decisions" force row level security;--> statement-breakpoint
|
|
231
|
+
drop policy if exists "approval_decisions_ws_isolation" on "mod_hr"."approval_decisions";
|
|
232
|
+
--> statement-breakpoint
|
|
215
233
|
create policy "approval_decisions_ws_isolation" on "mod_hr"."approval_decisions"
|
|
216
234
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
217
235
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
218
236
|
|
|
219
237
|
alter table "mod_hr"."delegations" enable row level security;--> statement-breakpoint
|
|
220
238
|
alter table "mod_hr"."delegations" force row level security;--> statement-breakpoint
|
|
239
|
+
drop policy if exists "delegations_ws_isolation" on "mod_hr"."delegations";
|
|
240
|
+
--> statement-breakpoint
|
|
221
241
|
create policy "delegations_ws_isolation" on "mod_hr"."delegations"
|
|
222
242
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
223
243
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
@@ -232,6 +252,6 @@ create policy "delegations_ws_isolation" on "mod_hr"."delegations"
|
|
|
232
252
|
--
|
|
233
253
|
-- Partial on purpose: a cancelled or rejected request must not block rebooking the same day, and a
|
|
234
254
|
-- weekend inside a range is not counted so it does not conflict with anything either.
|
|
235
|
-
|
|
255
|
+
CREATE unique INDEX IF NOT EXISTS "hr_leave_days_no_double_booking"
|
|
236
256
|
on "mod_hr"."leave_request_days" (workspace_id, person_id, date)
|
|
237
257
|
where counted and status in ('pending', 'approved');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CREATE TABLE "mod_hr"."attendance_days" (
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."attendance_days" (
|
|
2
2
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
3
3
|
"workspace_id" uuid NOT NULL,
|
|
4
4
|
"person_id" uuid NOT NULL,
|
|
@@ -19,7 +19,7 @@ CREATE TABLE "mod_hr"."attendance_days" (
|
|
|
19
19
|
"computed_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
20
20
|
);
|
|
21
21
|
--> statement-breakpoint
|
|
22
|
-
CREATE TABLE "mod_hr"."punches" (
|
|
22
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."punches" (
|
|
23
23
|
"id" uuid DEFAULT uuidv7() NOT NULL,
|
|
24
24
|
"workspace_id" uuid NOT NULL,
|
|
25
25
|
"person_id" uuid NOT NULL,
|
|
@@ -48,9 +48,11 @@ CREATE TABLE "mod_hr"."punches" (
|
|
|
48
48
|
-- A partitioned table's primary key must contain the partition column, which is why it is
|
|
49
49
|
-- (id, business_date) rather than (id). Same for the idempotency index: without business_date in it
|
|
50
50
|
-- Postgres refuses to create it at all.
|
|
51
|
-
|
|
51
|
+
alter table "mod_hr"."punches" drop constraint if exists "punches_pkey";
|
|
52
52
|
--> statement-breakpoint
|
|
53
|
-
|
|
53
|
+
alter table "mod_hr"."punches" add constraint "punches_pkey" primary key ("id", "business_date");
|
|
54
|
+
--> statement-breakpoint
|
|
55
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_punches_idem_uq"
|
|
54
56
|
ON "mod_hr"."punches" ("workspace_id", "idempotency_key", "business_date")
|
|
55
57
|
WHERE "idempotency_key" IS NOT NULL;
|
|
56
58
|
--> statement-breakpoint
|
|
@@ -64,11 +66,13 @@ ALTER TABLE "mod_hr"."punches_default" ENABLE ROW LEVEL SECURITY;
|
|
|
64
66
|
--> statement-breakpoint
|
|
65
67
|
ALTER TABLE "mod_hr"."punches_default" FORCE ROW LEVEL SECURITY;
|
|
66
68
|
--> statement-breakpoint
|
|
69
|
+
drop policy if exists "punches_ws_isolation" on "mod_hr"."punches_default";
|
|
70
|
+
--> statement-breakpoint
|
|
67
71
|
CREATE POLICY "punches_ws_isolation" ON "mod_hr"."punches_default"
|
|
68
72
|
USING (workspace_id::text = current_setting('app.workspace_id', true))
|
|
69
73
|
WITH CHECK (workspace_id::text = current_setting('app.workspace_id', true));
|
|
70
74
|
--> statement-breakpoint
|
|
71
|
-
-- Creating a partition is not just `CREATE TABLE ... PARTITION OF`.
|
|
75
|
+
-- Creating a partition is not just `CREATE TABLE IF NOT EXISTS ... PARTITION OF`.
|
|
72
76
|
--
|
|
73
77
|
-- A policy on a partitioned parent applies when you query **through the parent**. Query a partition
|
|
74
78
|
-- directly and its own row-level security setting applies — and a fresh partition has none. Any
|
|
@@ -120,7 +124,7 @@ BEGIN
|
|
|
120
124
|
END LOOP;
|
|
121
125
|
END $$;
|
|
122
126
|
--> statement-breakpoint
|
|
123
|
-
CREATE TABLE "mod_hr"."regularizations" (
|
|
127
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."regularizations" (
|
|
124
128
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
125
129
|
"workspace_id" uuid NOT NULL,
|
|
126
130
|
"person_id" uuid NOT NULL,
|
|
@@ -134,7 +138,7 @@ CREATE TABLE "mod_hr"."regularizations" (
|
|
|
134
138
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
135
139
|
);
|
|
136
140
|
--> statement-breakpoint
|
|
137
|
-
CREATE TABLE "mod_hr"."schedule_assignments" (
|
|
141
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."schedule_assignments" (
|
|
138
142
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
139
143
|
"workspace_id" uuid NOT NULL,
|
|
140
144
|
"person_id" uuid NOT NULL,
|
|
@@ -144,7 +148,7 @@ CREATE TABLE "mod_hr"."schedule_assignments" (
|
|
|
144
148
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
145
149
|
);
|
|
146
150
|
--> statement-breakpoint
|
|
147
|
-
CREATE TABLE "mod_hr"."schedules" (
|
|
151
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."schedules" (
|
|
148
152
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
149
153
|
"workspace_id" uuid NOT NULL,
|
|
150
154
|
"name" text NOT NULL,
|
|
@@ -162,12 +166,12 @@ CREATE TABLE "mod_hr"."schedules" (
|
|
|
162
166
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
163
167
|
);
|
|
164
168
|
--> statement-breakpoint
|
|
165
|
-
CREATE UNIQUE INDEX "hr_attendance_days_uq" ON "mod_hr"."attendance_days" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
166
|
-
CREATE INDEX "hr_attendance_days_date_idx" ON "mod_hr"."attendance_days" USING btree ("workspace_id","business_date","status");--> statement-breakpoint
|
|
167
|
-
CREATE INDEX "hr_punches_person_idx" ON "mod_hr"."punches" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
168
|
-
CREATE INDEX "hr_regularizations_idx" ON "mod_hr"."regularizations" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
169
|
-
CREATE INDEX "hr_schedule_assign_idx" ON "mod_hr"."schedule_assignments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
170
|
-
CREATE INDEX "hr_schedules_ws_idx" ON "mod_hr"."schedules" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
169
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "hr_attendance_days_uq" ON "mod_hr"."attendance_days" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
170
|
+
CREATE INDEX IF NOT EXISTS "hr_attendance_days_date_idx" ON "mod_hr"."attendance_days" USING btree ("workspace_id","business_date","status");--> statement-breakpoint
|
|
171
|
+
CREATE INDEX IF NOT EXISTS "hr_punches_person_idx" ON "mod_hr"."punches" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
172
|
+
CREATE INDEX IF NOT EXISTS "hr_regularizations_idx" ON "mod_hr"."regularizations" USING btree ("workspace_id","person_id","business_date");--> statement-breakpoint
|
|
173
|
+
CREATE INDEX IF NOT EXISTS "hr_schedule_assign_idx" ON "mod_hr"."schedule_assignments" USING btree ("workspace_id","person_id","effective_from");--> statement-breakpoint
|
|
174
|
+
CREATE INDEX IF NOT EXISTS "hr_schedules_ws_idx" ON "mod_hr"."schedules" USING btree ("workspace_id","archived_at");--> statement-breakpoint
|
|
171
175
|
-- ---------------------------------------------------------------------------------------------
|
|
172
176
|
-- Row-level security on the attendance tables.
|
|
173
177
|
--
|
|
@@ -177,30 +181,40 @@ CREATE INDEX "hr_schedules_ws_idx" ON "mod_hr"."schedules" USING btree ("workspa
|
|
|
177
181
|
-- true until a Postgres upgrade says otherwise.
|
|
178
182
|
alter table "mod_hr"."schedules" enable row level security;--> statement-breakpoint
|
|
179
183
|
alter table "mod_hr"."schedules" force row level security;--> statement-breakpoint
|
|
184
|
+
drop policy if exists "schedules_ws_isolation" on "mod_hr"."schedules";
|
|
185
|
+
--> statement-breakpoint
|
|
180
186
|
create policy "schedules_ws_isolation" on "mod_hr"."schedules"
|
|
181
187
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
182
188
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
183
189
|
|
|
184
190
|
alter table "mod_hr"."schedule_assignments" enable row level security;--> statement-breakpoint
|
|
185
191
|
alter table "mod_hr"."schedule_assignments" force row level security;--> statement-breakpoint
|
|
192
|
+
drop policy if exists "schedule_assignments_ws_isolation" on "mod_hr"."schedule_assignments";
|
|
193
|
+
--> statement-breakpoint
|
|
186
194
|
create policy "schedule_assignments_ws_isolation" on "mod_hr"."schedule_assignments"
|
|
187
195
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
188
196
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
189
197
|
|
|
190
198
|
alter table "mod_hr"."punches" enable row level security;--> statement-breakpoint
|
|
191
199
|
alter table "mod_hr"."punches" force row level security;--> statement-breakpoint
|
|
200
|
+
drop policy if exists "punches_ws_isolation" on "mod_hr"."punches";
|
|
201
|
+
--> statement-breakpoint
|
|
192
202
|
create policy "punches_ws_isolation" on "mod_hr"."punches"
|
|
193
203
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
194
204
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
195
205
|
|
|
196
206
|
alter table "mod_hr"."attendance_days" enable row level security;--> statement-breakpoint
|
|
197
207
|
alter table "mod_hr"."attendance_days" force row level security;--> statement-breakpoint
|
|
208
|
+
drop policy if exists "attendance_days_ws_isolation" on "mod_hr"."attendance_days";
|
|
209
|
+
--> statement-breakpoint
|
|
198
210
|
create policy "attendance_days_ws_isolation" on "mod_hr"."attendance_days"
|
|
199
211
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
200
212
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
201
213
|
|
|
202
214
|
alter table "mod_hr"."regularizations" enable row level security;--> statement-breakpoint
|
|
203
215
|
alter table "mod_hr"."regularizations" force row level security;--> statement-breakpoint
|
|
216
|
+
drop policy if exists "regularizations_ws_isolation" on "mod_hr"."regularizations";
|
|
217
|
+
--> statement-breakpoint
|
|
204
218
|
create policy "regularizations_ws_isolation" on "mod_hr"."regularizations"
|
|
205
219
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
206
220
|
with check (workspace_id::text = current_setting('app.workspace_id', true));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CREATE TABLE "mod_hr"."periods" (
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."periods" (
|
|
2
2
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
3
3
|
"workspace_id" uuid NOT NULL,
|
|
4
4
|
"kind" text DEFAULT 'payroll' NOT NULL,
|
|
@@ -12,7 +12,7 @@ CREATE TABLE "mod_hr"."periods" (
|
|
|
12
12
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
13
13
|
);
|
|
14
14
|
--> statement-breakpoint
|
|
15
|
-
CREATE TABLE "mod_hr"."policies" (
|
|
15
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."policies" (
|
|
16
16
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
17
17
|
"workspace_id" uuid NOT NULL,
|
|
18
18
|
"kind" text NOT NULL,
|
|
@@ -28,7 +28,7 @@ CREATE TABLE "mod_hr"."policies" (
|
|
|
28
28
|
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
29
29
|
);
|
|
30
30
|
--> statement-breakpoint
|
|
31
|
-
CREATE TABLE "mod_hr"."policy_assignments" (
|
|
31
|
+
CREATE TABLE IF NOT EXISTS "mod_hr"."policy_assignments" (
|
|
32
32
|
"id" uuid PRIMARY KEY DEFAULT uuidv7() NOT NULL,
|
|
33
33
|
"workspace_id" uuid NOT NULL,
|
|
34
34
|
"policy_id" uuid NOT NULL,
|
|
@@ -40,25 +40,31 @@ CREATE TABLE "mod_hr"."policy_assignments" (
|
|
|
40
40
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
41
41
|
);
|
|
42
42
|
--> statement-breakpoint
|
|
43
|
-
CREATE INDEX "hr_periods_idx" ON "mod_hr"."periods" USING btree ("workspace_id","kind","starts_on");--> statement-breakpoint
|
|
44
|
-
CREATE INDEX "hr_policies_ws_kind_idx" ON "mod_hr"."policies" USING btree ("workspace_id","kind","effective_from");--> statement-breakpoint
|
|
45
|
-
CREATE INDEX "hr_policy_assign_idx" ON "mod_hr"."policy_assignments" USING btree ("workspace_id","subject_kind","subject_id");--> statement-breakpoint
|
|
46
|
-
CREATE INDEX "hr_policy_assign_policy_idx" ON "mod_hr"."policy_assignments" USING btree ("workspace_id","policy_id");--> statement-breakpoint
|
|
43
|
+
CREATE INDEX IF NOT EXISTS "hr_periods_idx" ON "mod_hr"."periods" USING btree ("workspace_id","kind","starts_on");--> statement-breakpoint
|
|
44
|
+
CREATE INDEX IF NOT EXISTS "hr_policies_ws_kind_idx" ON "mod_hr"."policies" USING btree ("workspace_id","kind","effective_from");--> statement-breakpoint
|
|
45
|
+
CREATE INDEX IF NOT EXISTS "hr_policy_assign_idx" ON "mod_hr"."policy_assignments" USING btree ("workspace_id","subject_kind","subject_id");--> statement-breakpoint
|
|
46
|
+
CREATE INDEX IF NOT EXISTS "hr_policy_assign_policy_idx" ON "mod_hr"."policy_assignments" USING btree ("workspace_id","policy_id");--> statement-breakpoint
|
|
47
47
|
-- Row-level security on the policy and period tables.
|
|
48
48
|
alter table "mod_hr"."policies" enable row level security;--> statement-breakpoint
|
|
49
49
|
alter table "mod_hr"."policies" force row level security;--> statement-breakpoint
|
|
50
|
+
drop policy if exists "policies_ws_isolation" on "mod_hr"."policies";
|
|
51
|
+
--> statement-breakpoint
|
|
50
52
|
create policy "policies_ws_isolation" on "mod_hr"."policies"
|
|
51
53
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
52
54
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
53
55
|
|
|
54
56
|
alter table "mod_hr"."policy_assignments" enable row level security;--> statement-breakpoint
|
|
55
57
|
alter table "mod_hr"."policy_assignments" force row level security;--> statement-breakpoint
|
|
58
|
+
drop policy if exists "policy_assignments_ws_isolation" on "mod_hr"."policy_assignments";
|
|
59
|
+
--> statement-breakpoint
|
|
56
60
|
create policy "policy_assignments_ws_isolation" on "mod_hr"."policy_assignments"
|
|
57
61
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
58
62
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
59
63
|
|
|
60
64
|
alter table "mod_hr"."periods" enable row level security;--> statement-breakpoint
|
|
61
65
|
alter table "mod_hr"."periods" force row level security;--> statement-breakpoint
|
|
66
|
+
drop policy if exists "periods_ws_isolation" on "mod_hr"."periods";
|
|
67
|
+
--> statement-breakpoint
|
|
62
68
|
create policy "periods_ws_isolation" on "mod_hr"."periods"
|
|
63
69
|
using (workspace_id::text = current_setting('app.workspace_id', true))
|
|
64
70
|
with check (workspace_id::text = current_setting('app.workspace_id', true));--> statement-breakpoint
|
|
@@ -68,6 +74,8 @@ create policy "periods_ws_isolation" on "mod_hr"."periods"
|
|
|
68
74
|
-- Without this, two overlapping assignments at the same priority resolve arbitrarily: the ladder
|
|
69
75
|
-- has a tie it cannot break, and which policy applies depends on row order. That is the kind of bug
|
|
70
76
|
-- that shows up as two people on the same terms accruing differently.
|
|
77
|
+
alter table "mod_hr"."policy_assignments" drop constraint if exists "hr_policy_assign_no_overlap";
|
|
78
|
+
--> statement-breakpoint
|
|
71
79
|
alter table "mod_hr"."policy_assignments"
|
|
72
80
|
add constraint "hr_policy_assign_no_overlap"
|
|
73
81
|
exclude using gist (
|
|
@@ -79,6 +87,8 @@ alter table "mod_hr"."policy_assignments"
|
|
|
79
87
|
|
|
80
88
|
-- Two periods of a kind may not cover the same day for the same entity: "is this date locked" has
|
|
81
89
|
-- to have exactly one answer.
|
|
90
|
+
alter table "mod_hr"."periods" drop constraint if exists "hr_periods_no_overlap";
|
|
91
|
+
--> statement-breakpoint
|
|
82
92
|
alter table "mod_hr"."periods"
|
|
83
93
|
add constraint "hr_periods_no_overlap"
|
|
84
94
|
exclude using gist (
|