@loomcore/api 0.2.11 → 0.2.12

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.
@@ -1,3 +1,3 @@
1
- import { IBaseApiConfig } from '../../models/base-api-config.interface.js';
2
- import { SyntheticMigration } from '../../databases/postgres/migrations/postgres-initial-schema.js';
1
+ import type { SyntheticMigration } from "../../databases/postgres/migrations/postgres-initial-schema.js";
2
+ import type { IBaseApiConfig } from "../../models/base-api-config.interface.js";
3
3
  export declare const getPostgresTestSchema: (config: IBaseApiConfig) => SyntheticMigration[];
@@ -2,9 +2,9 @@ export const getPostgresTestSchema = (config) => {
2
2
  const migrations = [];
3
3
  const isMultiTenant = config.app.isMultiTenant === true;
4
4
  migrations.push({
5
- name: '00000000000100_schema-test-entities',
5
+ name: "00000000000100_schema-test-entities",
6
6
  up: async ({ context: pool }) => {
7
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
7
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
8
8
  await pool.query(`
9
9
  CREATE TABLE IF NOT EXISTS "testEntities" (
10
10
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -25,12 +25,12 @@ export const getPostgresTestSchema = (config) => {
25
25
  },
26
26
  down: async ({ context: pool }) => {
27
27
  await pool.query('DROP TABLE IF EXISTS "testEntities"');
28
- }
28
+ },
29
29
  });
30
30
  migrations.push({
31
- name: '00000000000101_schema-categories',
31
+ name: "00000000000101_schema-categories",
32
32
  up: async ({ context: pool }) => {
33
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
33
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
34
34
  await pool.query(`
35
35
  CREATE TABLE IF NOT EXISTS "categories" (
36
36
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -41,12 +41,12 @@ export const getPostgresTestSchema = (config) => {
41
41
  },
42
42
  down: async ({ context: pool }) => {
43
43
  await pool.query('DROP TABLE IF EXISTS "categories"');
44
- }
44
+ },
45
45
  });
46
46
  migrations.push({
47
- name: '00000000000102_schema-products',
47
+ name: "00000000000102_schema-products",
48
48
  up: async ({ context: pool }) => {
49
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
49
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
50
50
  await pool.query(`
51
51
  CREATE TABLE IF NOT EXISTS "products" (
52
52
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -67,12 +67,12 @@ export const getPostgresTestSchema = (config) => {
67
67
  },
68
68
  down: async ({ context: pool }) => {
69
69
  await pool.query('DROP TABLE IF EXISTS "products"');
70
- }
70
+ },
71
71
  });
72
72
  migrations.push({
73
- name: '00000000000103_schema-test-items',
73
+ name: "00000000000103_schema-test-items",
74
74
  up: async ({ context: pool }) => {
75
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
75
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
76
76
  await pool.query(`
77
77
  CREATE TABLE IF NOT EXISTS "testItems" (
78
78
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -91,12 +91,53 @@ export const getPostgresTestSchema = (config) => {
91
91
  },
92
92
  down: async ({ context: pool }) => {
93
93
  await pool.query('DROP TABLE IF EXISTS "testItems"');
94
- }
94
+ },
95
95
  });
96
96
  migrations.push({
97
- name: '00000000000105_5_schema-agents',
97
+ name: "00000000000104_schema-persons",
98
98
  up: async ({ context: pool }) => {
99
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
99
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
100
+ const personsUniqueConstraints = isMultiTenant
101
+ ? `CONSTRAINT "uk_persons_org_external_id" UNIQUE ("_orgId", "external_id"),
102
+ CONSTRAINT "uk_persons_org_ssn" UNIQUE ("_orgId", "ssn")`
103
+ : `CONSTRAINT "uk_persons_external_id" UNIQUE ("external_id"),
104
+ CONSTRAINT "uk_persons_ssn" UNIQUE ("ssn")`;
105
+ await pool.query(`
106
+ CREATE TABLE IF NOT EXISTS "persons" (
107
+ "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
108
+ ${orgColumnDef}
109
+ "external_id" VARCHAR(255),
110
+ "first_name" VARCHAR(255) NOT NULL,
111
+ "middle_name" VARCHAR(255),
112
+ "last_name" VARCHAR(255) NOT NULL,
113
+ "date_of_birth" DATE,
114
+ "ssn" VARCHAR(255),
115
+ "is_agent" BOOLEAN NOT NULL DEFAULT FALSE,
116
+ "is_client" BOOLEAN NOT NULL DEFAULT FALSE,
117
+ "is_employee" BOOLEAN NOT NULL DEFAULT FALSE,
118
+ "extended_types" INTEGER,
119
+ "_created" TIMESTAMPTZ NOT NULL,
120
+ "_createdBy" INTEGER NOT NULL,
121
+ "_updated" TIMESTAMPTZ,
122
+ "_updatedBy" INTEGER,
123
+ "_deleted" TIMESTAMPTZ,
124
+ "_deletedBy" INTEGER,
125
+ ${personsUniqueConstraints}
126
+ )
127
+ `);
128
+ await pool.query(`CREATE INDEX IF NOT EXISTS "idx_persons_external_id" ON "persons" ("external_id")`);
129
+ await pool.query(`CREATE INDEX IF NOT EXISTS "idx_persons_ssn" ON "persons" ("ssn")`);
130
+ },
131
+ down: async ({ context: pool }) => {
132
+ await pool.query(`DROP INDEX IF EXISTS "idx_persons_external_id"`);
133
+ await pool.query(`DROP INDEX IF EXISTS "idx_persons_ssn"`);
134
+ await pool.query('DROP TABLE IF EXISTS "persons"');
135
+ },
136
+ });
137
+ migrations.push({
138
+ name: "00000000000105_5_schema-agents",
139
+ up: async ({ context: pool }) => {
140
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
100
141
  await pool.query(`
101
142
  CREATE TABLE IF NOT EXISTS "agents" (
102
143
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -114,12 +155,12 @@ export const getPostgresTestSchema = (config) => {
114
155
  },
115
156
  down: async ({ context: pool }) => {
116
157
  await pool.query('DROP TABLE IF EXISTS "agents"');
117
- }
158
+ },
118
159
  });
119
160
  migrations.push({
120
- name: '00000000000105_6_schema-clients',
161
+ name: "00000000000105_6_schema-clients",
121
162
  up: async ({ context: pool }) => {
122
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
163
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
123
164
  await pool.query(`
124
165
  CREATE TABLE IF NOT EXISTS "clients" (
125
166
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -140,12 +181,12 @@ export const getPostgresTestSchema = (config) => {
140
181
  },
141
182
  down: async ({ context: pool }) => {
142
183
  await pool.query('DROP TABLE IF EXISTS "clients"');
143
- }
184
+ },
144
185
  });
145
186
  migrations.push({
146
- name: '00000000000105_7_schema-policies',
187
+ name: "00000000000105_7_schema-policies",
147
188
  up: async ({ context: pool }) => {
148
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
189
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
149
190
  await pool.query(`
150
191
  CREATE TABLE IF NOT EXISTS "policies" (
151
192
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -165,12 +206,12 @@ export const getPostgresTestSchema = (config) => {
165
206
  },
166
207
  down: async ({ context: pool }) => {
167
208
  await pool.query('DROP TABLE IF EXISTS "policies"');
168
- }
209
+ },
169
210
  });
170
211
  migrations.push({
171
- name: '00000000000105_8_schema-agents-policies',
212
+ name: "00000000000105_8_schema-agents-policies",
172
213
  up: async ({ context: pool }) => {
173
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
214
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
174
215
  await pool.query(`
175
216
  CREATE TABLE IF NOT EXISTS agents_policies (
176
217
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -191,12 +232,12 @@ export const getPostgresTestSchema = (config) => {
191
232
  },
192
233
  down: async ({ context: pool }) => {
193
234
  await pool.query('DROP TABLE IF EXISTS "agents_policies"');
194
- }
235
+ },
195
236
  });
196
237
  migrations.push({
197
- name: '00000000000105_9_schema-premiums',
238
+ name: "00000000000105_9_schema-premiums",
198
239
  up: async ({ context: pool }) => {
199
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
240
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
200
241
  await pool.query(`
201
242
  CREATE TABLE IF NOT EXISTS "premiums" (
202
243
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -216,12 +257,12 @@ export const getPostgresTestSchema = (config) => {
216
257
  },
217
258
  down: async ({ context: pool }) => {
218
259
  await pool.query('DROP TABLE IF EXISTS "premiums"');
219
- }
260
+ },
220
261
  });
221
262
  migrations.push({
222
- name: '00000000000106_schema-email-addresses',
263
+ name: "00000000000106_schema-email-addresses",
223
264
  up: async ({ context: pool }) => {
224
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
265
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
225
266
  await pool.query(`
226
267
  CREATE TABLE IF NOT EXISTS email_addresses (
227
268
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -243,12 +284,12 @@ export const getPostgresTestSchema = (config) => {
243
284
  },
244
285
  down: async ({ context: pool }) => {
245
286
  await pool.query('DROP TABLE IF EXISTS "email_addresses"');
246
- }
287
+ },
247
288
  });
248
289
  migrations.push({
249
- name: '00000000000107_schema-phone-numbers',
290
+ name: "00000000000107_schema-phone-numbers",
250
291
  up: async ({ context: pool }) => {
251
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
292
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
252
293
  await pool.query(`
253
294
  CREATE TABLE IF NOT EXISTS phone_numbers (
254
295
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -268,12 +309,12 @@ export const getPostgresTestSchema = (config) => {
268
309
  },
269
310
  down: async ({ context: pool }) => {
270
311
  await pool.query('DROP TABLE IF EXISTS "phone_numbers"');
271
- }
312
+ },
272
313
  });
273
314
  migrations.push({
274
- name: '00000000000108_schema-addresses',
315
+ name: "00000000000108_schema-addresses",
275
316
  up: async ({ context: pool }) => {
276
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
317
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
277
318
  await pool.query(`
278
319
  CREATE TABLE IF NOT EXISTS addresses (
279
320
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -297,12 +338,12 @@ export const getPostgresTestSchema = (config) => {
297
338
  },
298
339
  down: async ({ context: pool }) => {
299
340
  await pool.query('DROP TABLE IF EXISTS "addresses"');
300
- }
341
+ },
301
342
  });
302
343
  migrations.push({
303
- name: '00000000000109_schema-person-addresses',
344
+ name: "00000000000109_schema-person-addresses",
304
345
  up: async ({ context: pool }) => {
305
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
346
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
306
347
  await pool.query(`
307
348
  CREATE TABLE IF NOT EXISTS persons_addresses (
308
349
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -323,12 +364,12 @@ export const getPostgresTestSchema = (config) => {
323
364
  },
324
365
  down: async ({ context: pool }) => {
325
366
  await pool.query('DROP TABLE IF EXISTS "persons_addresses"');
326
- }
367
+ },
327
368
  });
328
369
  migrations.push({
329
- name: '00000000000110_schema-person-phone-numbers',
370
+ name: "00000000000110_schema-person-phone-numbers",
330
371
  up: async ({ context: pool }) => {
331
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
372
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
332
373
  await pool.query(`
333
374
  CREATE TABLE IF NOT EXISTS persons_phone_numbers (
334
375
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -349,12 +390,12 @@ export const getPostgresTestSchema = (config) => {
349
390
  },
350
391
  down: async ({ context: pool }) => {
351
392
  await pool.query('DROP TABLE IF EXISTS "persons_phone_numbers"');
352
- }
393
+ },
353
394
  });
354
395
  migrations.push({
355
- name: '00000000000111_schema-states',
396
+ name: "00000000000111_schema-states",
356
397
  up: async ({ context: pool }) => {
357
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
398
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
358
399
  await pool.query(`
359
400
  CREATE TABLE IF NOT EXISTS states (
360
401
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -371,12 +412,12 @@ export const getPostgresTestSchema = (config) => {
371
412
  },
372
413
  down: async ({ context: pool }) => {
373
414
  await pool.query('DROP TABLE IF EXISTS "states"');
374
- }
415
+ },
375
416
  });
376
417
  migrations.push({
377
- name: '00000000000112_schema-districts',
418
+ name: "00000000000112_schema-districts",
378
419
  up: async ({ context: pool }) => {
379
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
420
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
380
421
  await pool.query(`
381
422
  CREATE TABLE IF NOT EXISTS districts (
382
423
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -395,12 +436,12 @@ export const getPostgresTestSchema = (config) => {
395
436
  },
396
437
  down: async ({ context: pool }) => {
397
438
  await pool.query('DROP TABLE IF EXISTS "districts"');
398
- }
439
+ },
399
440
  });
400
441
  migrations.push({
401
- name: '00000000000113_schema-schools',
442
+ name: "00000000000113_schema-schools",
402
443
  up: async ({ context: pool }) => {
403
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
444
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
404
445
  await pool.query(`
405
446
  CREATE TABLE IF NOT EXISTS schools (
406
447
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -419,12 +460,12 @@ export const getPostgresTestSchema = (config) => {
419
460
  },
420
461
  down: async ({ context: pool }) => {
421
462
  await pool.query('DROP TABLE IF EXISTS "schools"');
422
- }
463
+ },
423
464
  });
424
465
  migrations.push({
425
- name: '00000000000114_schema-person-schools',
466
+ name: "00000000000114_schema-person-schools",
426
467
  up: async ({ context: pool }) => {
427
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
468
+ const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : "";
428
469
  await pool.query(`
429
470
  CREATE TABLE IF NOT EXISTS persons_schools (
430
471
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -445,7 +486,7 @@ export const getPostgresTestSchema = (config) => {
445
486
  },
446
487
  down: async ({ context: pool }) => {
447
488
  await pool.query('DROP TABLE IF EXISTS "persons_schools"');
448
- }
489
+ },
449
490
  });
450
491
  return migrations;
451
492
  };
@@ -28,28 +28,7 @@ export const getMongoInitialSchema = (dbConfig) => {
28
28
  });
29
29
  if (isAuthEnabled)
30
30
  migrations.push({
31
- name: "00000000000002_schema-persons",
32
- up: async ({ context: db }) => {
33
- await db.createCollection("persons");
34
- if (isMultiTenant) {
35
- await db.collection("persons").createIndex({ _orgId: 1 });
36
- await db
37
- .collection("persons")
38
- .createIndex({ _orgId: 1, externalId: 1 }, { unique: true, sparse: true });
39
- }
40
- else {
41
- await db
42
- .collection("persons")
43
- .createIndex({ externalId: 1 }, { unique: true, sparse: true });
44
- }
45
- },
46
- down: async ({ context: db }) => {
47
- await db.collection("persons").drop();
48
- },
49
- });
50
- if (isAuthEnabled)
51
- migrations.push({
52
- name: "00000000000003_schema-users",
31
+ name: "00000000000002_schema-users",
53
32
  up: async ({ context: db }) => {
54
33
  await db.createCollection("users");
55
34
  if (dbConfig.app.isMultiTenant) {
@@ -70,7 +49,7 @@ export const getMongoInitialSchema = (dbConfig) => {
70
49
  });
71
50
  if (isAuthEnabled)
72
51
  migrations.push({
73
- name: "00000000000004_schema-refresh-tokens",
52
+ name: "00000000000003_schema-refresh-tokens",
74
53
  up: async ({ context: db }) => {
75
54
  await db.createCollection("refresh_tokens");
76
55
  await db
@@ -88,7 +67,7 @@ export const getMongoInitialSchema = (dbConfig) => {
88
67
  });
89
68
  if (isAuthEnabled)
90
69
  migrations.push({
91
- name: "00000000000005_schema-password-reset-tokens",
70
+ name: "00000000000004_schema-password-reset-tokens",
92
71
  up: async ({ context: db }) => {
93
72
  await db.createCollection("password_reset_tokens");
94
73
  if (isMultiTenant) {
@@ -111,7 +90,7 @@ export const getMongoInitialSchema = (dbConfig) => {
111
90
  });
112
91
  if (isAuthEnabled)
113
92
  migrations.push({
114
- name: "00000000000006_schema-roles",
93
+ name: "00000000000005_schema-roles",
115
94
  up: async ({ context: db }) => {
116
95
  await db.createCollection("roles");
117
96
  if (isMultiTenant) {
@@ -132,7 +111,7 @@ export const getMongoInitialSchema = (dbConfig) => {
132
111
  });
133
112
  if (isAuthEnabled)
134
113
  migrations.push({
135
- name: "00000000000007_schema-user-roles",
114
+ name: "00000000000006_schema-user-roles",
136
115
  up: async ({ context: db }) => {
137
116
  await db.createCollection("user_roles");
138
117
  if (isMultiTenant) {
@@ -155,7 +134,7 @@ export const getMongoInitialSchema = (dbConfig) => {
155
134
  });
156
135
  if (isAuthEnabled)
157
136
  migrations.push({
158
- name: "00000000000008_schema-features",
137
+ name: "00000000000007_schema-features",
159
138
  up: async ({ context: db }) => {
160
139
  await db.createCollection("features");
161
140
  if (isMultiTenant) {
@@ -176,7 +155,7 @@ export const getMongoInitialSchema = (dbConfig) => {
176
155
  });
177
156
  if (isAuthEnabled)
178
157
  migrations.push({
179
- name: "00000000000009_schema-authorizations",
158
+ name: "00000000000008_schema-authorizations",
180
159
  up: async ({ context: db }) => {
181
160
  await db.createCollection("authorizations");
182
161
  if (isMultiTenant) {
@@ -199,7 +178,7 @@ export const getMongoInitialSchema = (dbConfig) => {
199
178
  });
200
179
  if (isMultiTenant) {
201
180
  migrations.push({
202
- name: "00000000000010_data-meta-org",
181
+ name: "00000000000009_data-meta-org",
203
182
  up: async ({ context: db }) => {
204
183
  const metaOrgDoc = {
205
184
  name: dbConfig.multiTenant.metaOrgName,
@@ -231,11 +210,11 @@ export const getMongoInitialSchema = (dbConfig) => {
231
210
  }
232
211
  if (isAuthEnabled && dbConfig.adminUser) {
233
212
  migrations.push({
234
- name: "00000000000011_data-admin-user",
213
+ name: "00000000000010_data-admin-user",
235
214
  up: async ({ context: db }) => {
236
215
  if (!isSystemUserContextInitialized()) {
237
216
  const errorMessage = isMultiTenant
238
- ? "SystemUserContext has not been initialized. The meta-org migration (00000000000010_data-meta-org) should have run before this migration. " +
217
+ ? "SystemUserContext has not been initialized. The meta-org migration (00000000000009_data-meta-org) should have run before this migration. " +
239
218
  "Please ensure metaOrgName and metaOrgCode are provided in your dbConfig."
240
219
  : "BUG: SystemUserContext has not been initialized. For non-multi-tenant setups, SystemUserContext should be initialized before migrations run.";
241
220
  console.error("❌ Migration Error:", errorMessage);
@@ -247,26 +226,12 @@ export const getMongoInitialSchema = (dbConfig) => {
247
226
  : {};
248
227
  const hashedPassword = await passwordUtils.hashPassword(dbConfig.adminUser.password);
249
228
  const email = dbConfig.adminUser.email.toLowerCase();
250
- const personResult = await db.collection("persons").insertOne({
251
- ...orgDoc,
252
- externalId: "admin-user-person-external-id",
253
- firstName: "Admin",
254
- lastName: "User",
255
- isAgent: false,
256
- isClient: false,
257
- isEmployee: false,
258
- _created: new Date(),
259
- _createdBy: "system",
260
- _updated: new Date(),
261
- _updatedBy: "system",
262
- });
263
229
  await db.collection("users").insertOne({
264
230
  ...orgDoc,
265
231
  externalId: "admin-user-external-id",
266
232
  email,
267
233
  password: hashedPassword,
268
234
  displayName: "Admin User",
269
- personId: personResult.insertedId,
270
235
  _created: new Date(),
271
236
  _createdBy: "system",
272
237
  _updated: new Date(),
@@ -284,7 +249,7 @@ export const getMongoInitialSchema = (dbConfig) => {
284
249
  }
285
250
  if (isAuthEnabled && dbConfig.adminUser) {
286
251
  migrations.push({
287
- name: "00000000000012_data-admin-authorizations",
252
+ name: "00000000000011_data-admin-authorizations",
288
253
  up: async ({ context: db }) => {
289
254
  const database = new MongoDBDatabase(db);
290
255
  const organizationService = new OrganizationService(database);
@@ -55,64 +55,20 @@ export const getPostgresInitialSchema = (dbConfig) => {
55
55
  }
56
56
  if (isAuthEnabled)
57
57
  migrations.push({
58
- name: "00000000000003_schema-persons",
58
+ name: "00000000000003_schema-users",
59
59
  up: async ({ context: pool }) => {
60
60
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
61
- const personsUniqueConstraints = isMultiTenant
62
- ? `CONSTRAINT "uk_persons_org_external_id" UNIQUE ("_orgId", "external_id"),
63
- CONSTRAINT "uk_persons_org_ssn" UNIQUE ("_orgId", "ssn")`
64
- : `CONSTRAINT "uk_persons_external_id" UNIQUE ("external_id"),
65
- CONSTRAINT "uk_persons_ssn" UNIQUE ("ssn")`;
66
- await pool.query(`
67
- CREATE TABLE IF NOT EXISTS "persons" (
68
- "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
69
- ${orgColumnDef}
70
- "external_id" VARCHAR(255),
71
- "first_name" VARCHAR(255) NOT NULL,
72
- "middle_name" VARCHAR(255),
73
- "last_name" VARCHAR(255) NOT NULL,
74
- "date_of_birth" DATE,
75
- "ssn" VARCHAR(255),
76
- "is_agent" BOOLEAN NOT NULL DEFAULT FALSE,
77
- "is_client" BOOLEAN NOT NULL DEFAULT FALSE,
78
- "is_employee" BOOLEAN NOT NULL DEFAULT FALSE,
79
- "extended_types" INTEGER,
80
- "_created" TIMESTAMPTZ NOT NULL,
81
- "_createdBy" INTEGER NOT NULL,
82
- "_updated" TIMESTAMPTZ,
83
- "_updatedBy" INTEGER,
84
- "_deleted" TIMESTAMPTZ,
85
- "_deletedBy" INTEGER,
86
- ${personsUniqueConstraints}
87
- )`);
88
- await pool.query(`CREATE INDEX IF NOT EXISTS "idx_persons_external_id" ON "persons" ("external_id")`);
89
- await pool.query(`CREATE INDEX IF NOT EXISTS "idx_persons_ssn" ON "persons" ("ssn")`);
90
- },
91
- down: async ({ context: pool }) => {
92
- await pool.query(`DROP INDEX IF EXISTS "idx_persons_external_id"`);
93
- await pool.query(`DROP INDEX IF EXISTS "idx_persons_ssn"`);
94
- await pool.query(`DROP TABLE IF EXISTS "persons"`);
95
- },
96
- });
97
- if (isAuthEnabled)
98
- migrations.push({
99
- name: "00000000000004_schema-users",
100
- up: async ({ context: pool }) => {
101
- const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
102
- let uniqueConstraint = isMultiTenant
61
+ const uniqueConstraint = isMultiTenant
103
62
  ? 'CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")'
104
63
  : 'CONSTRAINT "uk_users_email" UNIQUE ("email")';
105
- uniqueConstraint += `,
106
- CONSTRAINT "fk_users_person_id" FOREIGN KEY("person_id") REFERENCES "persons"("_id") ON DELETE CASCADE`;
107
64
  await pool.query(`
108
65
  CREATE TABLE IF NOT EXISTS "users"(
109
66
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
110
67
  ${orgColumnDef}
111
- "external_id" VARCHAR(255) UNIQUE,
68
+ "external_id" VARCHAR(255) UNIQUE,
112
69
  "email" VARCHAR(255) NOT NULL,
113
70
  "display_name" VARCHAR(255),
114
71
  "password" VARCHAR(255) NOT NULL,
115
- "person_id" INTEGER UNIQUE,
116
72
  "_lastLoggedIn" TIMESTAMPTZ,
117
73
  "_lastPasswordChange" TIMESTAMPTZ,
118
74
  "_created" TIMESTAMPTZ NOT NULL,
@@ -125,18 +81,16 @@ export const getPostgresInitialSchema = (dbConfig) => {
125
81
  )`);
126
82
  await pool.query(`CREATE INDEX IF NOT EXISTS "idx_users_external_id" ON "users"("external_id")`);
127
83
  await pool.query(`CREATE INDEX IF NOT EXISTS "idx_users_email" ON "users"("email")`);
128
- await pool.query(`CREATE INDEX IF NOT EXISTS "idx_users_person_id" ON "users"("person_id")`);
129
84
  },
130
85
  down: async ({ context: pool }) => {
131
86
  await pool.query(`DROP INDEX IF EXISTS "idx_users_external_id"`);
132
87
  await pool.query(`DROP INDEX IF EXISTS "idx_users_email"`);
133
- await pool.query(`DROP INDEX IF EXISTS "idx_users_person_id"`);
134
88
  await pool.query(`DROP TABLE IF EXISTS "users"`);
135
89
  },
136
90
  });
137
91
  if (isAuthEnabled)
138
92
  migrations.push({
139
- name: "00000000000005_schema-refresh-tokens",
93
+ name: "00000000000004_schema-refresh-tokens",
140
94
  up: async ({ context: pool }) => {
141
95
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
142
96
  await pool.query(`
@@ -159,7 +113,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
159
113
  });
160
114
  if (isAuthEnabled)
161
115
  migrations.push({
162
- name: "00000000000006_schema-password-reset-tokens",
116
+ name: "00000000000005_schema-password-reset-tokens",
163
117
  up: async ({ context: pool }) => {
164
118
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
165
119
  const uniqueConstraint = isMultiTenant
@@ -188,7 +142,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
188
142
  });
189
143
  if (isAuthEnabled)
190
144
  migrations.push({
191
- name: "00000000000007_schema-roles",
145
+ name: "00000000000006_schema-roles",
192
146
  up: async ({ context: pool }) => {
193
147
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
194
148
  const uniqueConstraint = isMultiTenant
@@ -210,7 +164,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
210
164
  });
211
165
  if (isAuthEnabled)
212
166
  migrations.push({
213
- name: "00000000000008_schema-user-roles",
167
+ name: "00000000000007_schema-user-roles",
214
168
  up: async ({ context: pool }) => {
215
169
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
216
170
  const uniqueConstraint = isMultiTenant
@@ -240,7 +194,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
240
194
  });
241
195
  if (isAuthEnabled)
242
196
  migrations.push({
243
- name: "00000000000009_schema-features",
197
+ name: "00000000000008_schema-features",
244
198
  up: async ({ context: pool }) => {
245
199
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
246
200
  const uniqueConstraint = isMultiTenant
@@ -262,7 +216,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
262
216
  });
263
217
  if (isAuthEnabled)
264
218
  migrations.push({
265
- name: "00000000000010_schema-authorizations",
219
+ name: "00000000000009_schema-authorizations",
266
220
  up: async ({ context: pool }) => {
267
221
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER NOT NULL,' : "";
268
222
  const uniqueConstraint = isMultiTenant
@@ -295,7 +249,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
295
249
  });
296
250
  if (isMultiTenant) {
297
251
  migrations.push({
298
- name: "00000000000011_data-meta-org",
252
+ name: "00000000000010_data-meta-org",
299
253
  up: async ({ context: pool }) => {
300
254
  const result = await pool.query(`
301
255
  INSERT INTO "organizations"("name", "code", "domain", "status", "is_meta_org", "_created", "_createdBy")
@@ -318,11 +272,11 @@ export const getPostgresInitialSchema = (dbConfig) => {
318
272
  }
319
273
  if (isAuthEnabled && dbConfig.adminUser) {
320
274
  migrations.push({
321
- name: "00000000000012_data-admin-user",
275
+ name: "00000000000011_data-admin-user",
322
276
  up: async ({ context: pool }) => {
323
277
  if (!isSystemUserContextInitialized()) {
324
278
  const errorMessage = isMultiTenant
325
- ? "SystemUserContext has not been initialized. The meta-org migration (00000000000011_data-meta-org) should have run before this migration. " +
279
+ ? "SystemUserContext has not been initialized. The meta-org migration (00000000000010_data-meta-org) should have run before this migration. " +
326
280
  "Please ensure metaOrgName and metaOrgCode are provided in your dbConfig."
327
281
  : "BUG: SystemUserContext has not been initialized. For non-multi-tenant setups, SystemUserContext should be initialized before migrations run.";
328
282
  console.error("❌ Migration Error:", errorMessage);
@@ -336,21 +290,13 @@ export const getPostgresInitialSchema = (dbConfig) => {
336
290
  const email = dbConfig.adminUser.email.toLowerCase();
337
291
  const client = await pool.connect();
338
292
  try {
339
- const personResult = isMultiTenant && orgId
340
- ? await client.query(`INSERT INTO "persons"("_orgId", "first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy")
341
- VALUES($1, 'Admin', 'User', false, false, false, NOW(), 0)
342
- RETURNING "_id"`, [orgId])
343
- : await client.query(`INSERT INTO "persons"("first_name", "last_name", "is_agent", "is_client", "is_employee", "_created", "_createdBy")
344
- VALUES('Admin', 'User', false, false, false, NOW(), 0)
345
- RETURNING "_id"`);
346
- const personId = personResult.rows[0]._id;
347
- if (isMultiTenant && orgId) {
348
- await client.query(`INSERT INTO "users"("_orgId", "email", "display_name", "password", "person_id", "_created", "_createdBy")
349
- VALUES($1, $2, 'Admin User', $3, $4, NOW(), 0)`, [orgId, email, hashedPassword, personId]);
293
+ if (isMultiTenant) {
294
+ await client.query(`INSERT INTO "users"("_orgId", "email", "display_name", "password", "_created", "_createdBy")
295
+ VALUES($1, $2, 'Admin User', $3, NOW(), 0)`, [orgId, email, hashedPassword]);
350
296
  }
351
297
  else {
352
- await client.query(`INSERT INTO "users"("email", "display_name", "password", "person_id", "_created", "_createdBy")
353
- VALUES($1, 'Admin User', $2, $3, NOW(), 0)`, [email, hashedPassword, personId]);
298
+ await client.query(`INSERT INTO "users"("email", "display_name", "password", "_created", "_createdBy")
299
+ VALUES($1, 'Admin User', $2, NOW(), 0)`, [email, hashedPassword]);
354
300
  }
355
301
  }
356
302
  finally {
@@ -368,7 +314,7 @@ export const getPostgresInitialSchema = (dbConfig) => {
368
314
  }
369
315
  if (isAuthEnabled && dbConfig.adminUser) {
370
316
  migrations.push({
371
- name: "00000000000013_data-admin-authorizations",
317
+ name: "00000000000012_data-admin-authorizations",
372
318
  up: async ({ context: pool }) => {
373
319
  const client = await pool.connect();
374
320
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "private": false,
5
5
  "description": "Loom Core Api - An opinionated Node.js api using Typescript, Express, and MongoDb or PostgreSQL",
6
6
  "scripts": {