@loomcore/api 0.1.77 → 0.1.79
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 +1 -1
- package/dist/__tests__/common-test.utils.js +5 -3
- package/dist/__tests__/postgres-test-migrations/postgres-test-schema.js +25 -0
- package/dist/__tests__/postgres.test-database.js +2 -2
- package/dist/__tests__/test-objects.d.ts +6 -1
- package/dist/__tests__/test-objects.js +50 -4
- package/dist/controllers/auth.controller.d.ts +2 -0
- package/dist/controllers/auth.controller.js +9 -4
- package/dist/databases/mongo-db/migrations/mongo-initial-schema.js +23 -5
- package/dist/databases/operations/__tests__/models/{agent.model.d.ts → test-agent.model.d.ts} +7 -7
- package/dist/databases/operations/__tests__/models/test-agent.model.js +8 -0
- package/dist/databases/operations/__tests__/models/{client-report.model.d.ts → test-client-report.model.d.ts} +21 -16
- package/dist/databases/operations/__tests__/models/test-client-report.model.js +11 -0
- package/dist/databases/operations/__tests__/models/test-district.model.d.ts +12 -0
- package/dist/databases/operations/__tests__/models/{district.model.js → test-district.model.js} +2 -2
- package/dist/databases/operations/__tests__/models/{email-address.model.d.ts → test-email-address.model.d.ts} +3 -3
- package/dist/databases/operations/__tests__/models/{email-address.model.js → test-email-address.model.js} +2 -2
- package/dist/databases/operations/__tests__/models/test-person.model.d.ts +28 -0
- package/dist/databases/operations/__tests__/models/test-person.model.js +12 -0
- package/dist/databases/operations/__tests__/models/{phone-number.model.d.ts → test-phone-number.model.d.ts} +3 -3
- package/dist/databases/operations/__tests__/models/{phone-number.model.js → test-phone-number.model.js} +2 -2
- package/dist/databases/operations/__tests__/models/{policy.model.d.ts → test-policy.model.d.ts} +14 -7
- package/dist/databases/operations/__tests__/models/test-policy.model.js +12 -0
- package/dist/databases/operations/__tests__/models/test-premium.model.d.ts +12 -0
- package/dist/databases/operations/__tests__/models/test-premium.model.js +8 -0
- package/dist/databases/operations/__tests__/models/test-school.model.d.ts +12 -0
- package/dist/databases/operations/__tests__/models/{school.model.js → test-school.model.js} +2 -2
- package/dist/databases/operations/__tests__/models/test-state.model.d.ts +8 -0
- package/dist/databases/operations/__tests__/models/test-state.model.js +6 -0
- package/dist/databases/operations/join-many.operation.js +3 -0
- package/dist/databases/operations/join-through-many.operation.js +3 -0
- package/dist/databases/operations/join-through.operation.js +3 -0
- package/dist/databases/operations/join.operation.js +3 -0
- package/dist/databases/postgres/migrations/postgres-initial-schema.js +54 -16
- package/dist/databases/postgres/utils/build-join-clauses.js +282 -272
- package/dist/databases/postgres/utils/build-select-clause.js +19 -34
- package/dist/databases/postgres/utils/transform-join-results.js +198 -194
- package/dist/services/auth.service.d.ts +3 -2
- package/dist/services/auth.service.js +15 -1
- package/dist/services/person.service.d.ts +6 -0
- package/dist/services/person.service.js +7 -0
- package/package.json +3 -3
- package/dist/databases/operations/__tests__/models/agent.model.js +0 -8
- package/dist/databases/operations/__tests__/models/client-report.model.js +0 -11
- package/dist/databases/operations/__tests__/models/district.model.d.ts +0 -12
- package/dist/databases/operations/__tests__/models/person.model.d.ts +0 -28
- package/dist/databases/operations/__tests__/models/person.model.js +0 -12
- package/dist/databases/operations/__tests__/models/policy.model.js +0 -10
- package/dist/databases/operations/__tests__/models/school.model.d.ts +0 -12
- package/dist/databases/operations/__tests__/models/state.model.d.ts +0 -8
- package/dist/databases/operations/__tests__/models/state.model.js +0 -6
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { entityUtils } from "@loomcore/common/utils";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
import { testAgentSchema } from "./test-agent.model.js";
|
|
4
|
+
import { testPremiumSchema } from "./test-premium.model.js";
|
|
5
|
+
export const testPolicySchema = Type.Object({
|
|
6
|
+
client_id: Type.Number(),
|
|
7
|
+
amount: Type.Number(),
|
|
8
|
+
frequency: Type.String(),
|
|
9
|
+
agents: Type.Optional(Type.Array(testAgentSchema)),
|
|
10
|
+
policy_premiums: Type.Optional(Type.Array(testPremiumSchema))
|
|
11
|
+
});
|
|
12
|
+
export const testPolicyModelSpec = entityUtils.getModelSpec(testPolicySchema, { isAuditable: true });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
2
|
+
export interface ITestPremiumModel extends IEntity, IAuditable {
|
|
3
|
+
policy_id: number;
|
|
4
|
+
amount: number;
|
|
5
|
+
date: Date | string;
|
|
6
|
+
}
|
|
7
|
+
export declare const testPremiumSchema: import("@sinclair/typebox").TObject<{
|
|
8
|
+
policy_id: import("@sinclair/typebox").TNumber;
|
|
9
|
+
amount: import("@sinclair/typebox").TNumber;
|
|
10
|
+
date: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TDate, import("@sinclair/typebox").TString]>;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const testPremiumModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { entityUtils } from "@loomcore/common/utils";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
export const testPremiumSchema = Type.Object({
|
|
4
|
+
policy_id: Type.Number(),
|
|
5
|
+
amount: Type.Number(),
|
|
6
|
+
date: Type.Union([Type.Date(), Type.String()])
|
|
7
|
+
});
|
|
8
|
+
export const testPremiumModelSpec = entityUtils.getModelSpec(testPremiumSchema, { isAuditable: true });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
2
|
+
import { ITestDistrictModel } from "./test-district.model.js";
|
|
3
|
+
export interface ITestSchoolModel extends IEntity, IAuditable {
|
|
4
|
+
name: string;
|
|
5
|
+
district_id: number;
|
|
6
|
+
district?: ITestDistrictModel;
|
|
7
|
+
}
|
|
8
|
+
export declare const testSchoolSchema: import("@sinclair/typebox").TObject<{
|
|
9
|
+
name: import("@sinclair/typebox").TString;
|
|
10
|
+
district_id: import("@sinclair/typebox").TNumber;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const testSchoolModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { entityUtils } from "@loomcore/common/utils";
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
|
-
export const
|
|
3
|
+
export const testSchoolSchema = Type.Object({
|
|
4
4
|
name: Type.String(),
|
|
5
5
|
district_id: Type.Number(),
|
|
6
6
|
});
|
|
7
|
-
export const
|
|
7
|
+
export const testSchoolModelSpec = entityUtils.getModelSpec(testSchoolSchema, { isAuditable: true });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
2
|
+
export interface ITestStateModel extends IEntity, IAuditable {
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const testStateSchema: import("@sinclair/typebox").TObject<{
|
|
6
|
+
name: import("@sinclair/typebox").TString;
|
|
7
|
+
}>;
|
|
8
|
+
export declare const testStateModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { entityUtils } from "@loomcore/common/utils";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
export const testStateSchema = Type.Object({
|
|
4
|
+
name: Type.String(),
|
|
5
|
+
});
|
|
6
|
+
export const testStateModelSpec = entityUtils.getModelSpec(testStateSchema, { isAuditable: true });
|
|
@@ -4,6 +4,9 @@ export class JoinMany {
|
|
|
4
4
|
foreignField;
|
|
5
5
|
as;
|
|
6
6
|
constructor(from, localField, foreignField, as) {
|
|
7
|
+
if (from === as) {
|
|
8
|
+
throw new Error(`JoinMany alias "${as}" must be different from table name "${from}". The alias is used to identify the join result and must be unique.`);
|
|
9
|
+
}
|
|
7
10
|
this.from = from;
|
|
8
11
|
this.localField = localField;
|
|
9
12
|
this.foreignField = foreignField;
|
|
@@ -7,6 +7,9 @@ export class JoinThroughMany {
|
|
|
7
7
|
foreignField;
|
|
8
8
|
as;
|
|
9
9
|
constructor(from, through, localField, throughLocalField, throughForeignField, foreignField, as) {
|
|
10
|
+
if (from === as) {
|
|
11
|
+
throw new Error(`JoinThroughMany alias "${as}" must be different from table name "${from}". The alias is used to identify the join result and must be unique.`);
|
|
12
|
+
}
|
|
10
13
|
this.from = from;
|
|
11
14
|
this.through = through;
|
|
12
15
|
this.localField = localField;
|
|
@@ -7,6 +7,9 @@ export class JoinThrough {
|
|
|
7
7
|
foreignField;
|
|
8
8
|
as;
|
|
9
9
|
constructor(from, through, localField, throughLocalField, throughForeignField, foreignField, as) {
|
|
10
|
+
if (from === as) {
|
|
11
|
+
throw new Error(`JoinThrough alias "${as}" must be different from table name "${from}". The alias is used to identify the join result and must be unique.`);
|
|
12
|
+
}
|
|
10
13
|
this.from = from;
|
|
11
14
|
this.through = through;
|
|
12
15
|
this.localField = localField;
|
|
@@ -4,6 +4,9 @@ export class Join {
|
|
|
4
4
|
foreignField;
|
|
5
5
|
as;
|
|
6
6
|
constructor(from, localField, foreignField, as) {
|
|
7
|
+
if (from === as) {
|
|
8
|
+
throw new Error(`Join alias "${as}" must be different from table name "${from}". The alias is used to identify the join result and must be unique.`);
|
|
9
|
+
}
|
|
7
10
|
this.from = from;
|
|
8
11
|
this.localField = localField;
|
|
9
12
|
this.foreignField = foreignField;
|
|
@@ -43,21 +43,54 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
43
43
|
}
|
|
44
44
|
if (isAuthEnabled)
|
|
45
45
|
migrations.push({
|
|
46
|
-
name: '00000000000002_schema-
|
|
46
|
+
name: '00000000000002_schema-persons',
|
|
47
47
|
up: async ({ context: pool }) => {
|
|
48
48
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
49
|
-
|
|
49
|
+
await pool.query(`
|
|
50
|
+
CREATE TABLE IF NOT EXISTS "persons" (
|
|
51
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
52
|
+
${orgColumnDef}
|
|
53
|
+
"externalId" VARCHAR(255) UNIQUE,
|
|
54
|
+
"firstName" VARCHAR(255) NOT NULL,
|
|
55
|
+
"middleName" VARCHAR(255),
|
|
56
|
+
"lastName" VARCHAR(255) NOT NULL,
|
|
57
|
+
"dateOfBirth" DATE,
|
|
58
|
+
"isAgent" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
59
|
+
"isClient" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
60
|
+
"isEmployee" BOOLEAN NOT NULL DEFAULT FALSE,
|
|
61
|
+
"extendedTypes" INTEGER NOT NULL DEFAULT 0,
|
|
62
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
63
|
+
"_createdBy" INTEGER NOT NULL,
|
|
64
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
65
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
66
|
+
"_deleted" TIMESTAMPTZ,
|
|
67
|
+
"_deletedBy" INTEGER
|
|
68
|
+
)
|
|
69
|
+
`);
|
|
70
|
+
},
|
|
71
|
+
down: async ({ context: pool }) => {
|
|
72
|
+
await pool.query('DROP TABLE IF EXISTS "persons"');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (isAuthEnabled)
|
|
76
|
+
migrations.push({
|
|
77
|
+
name: '00000000000003_schema-users',
|
|
78
|
+
up: async ({ context: pool }) => {
|
|
79
|
+
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
80
|
+
let uniqueConstraint = isMultiTenant
|
|
50
81
|
? 'CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")'
|
|
51
82
|
: 'CONSTRAINT "uk_users_email" UNIQUE ("email")';
|
|
83
|
+
uniqueConstraint += `,
|
|
84
|
+
CONSTRAINT "fk_users_personId" FOREIGN KEY("personId") REFERENCES "persons"("_id") ON DELETE CASCADE`;
|
|
52
85
|
await pool.query(`
|
|
53
86
|
CREATE TABLE IF NOT EXISTS "users" (
|
|
54
87
|
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
55
88
|
${orgColumnDef}
|
|
89
|
+
"externalId" VARCHAR(255) UNIQUE,
|
|
56
90
|
"email" VARCHAR(255) NOT NULL,
|
|
57
|
-
"firstName" VARCHAR(255),
|
|
58
|
-
"lastName" VARCHAR(255),
|
|
59
91
|
"displayName" VARCHAR(255),
|
|
60
92
|
"password" VARCHAR(255) NOT NULL,
|
|
93
|
+
"personId" INTEGER UNIQUE,
|
|
61
94
|
"_lastLoggedIn" TIMESTAMPTZ,
|
|
62
95
|
"_lastPasswordChange" TIMESTAMPTZ,
|
|
63
96
|
"_created" TIMESTAMPTZ NOT NULL,
|
|
@@ -76,7 +109,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
76
109
|
});
|
|
77
110
|
if (isAuthEnabled)
|
|
78
111
|
migrations.push({
|
|
79
|
-
name: '
|
|
112
|
+
name: '00000000000004_schema-refresh-tokens',
|
|
80
113
|
up: async ({ context: pool }) => {
|
|
81
114
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
82
115
|
await pool.query(`
|
|
@@ -99,7 +132,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
99
132
|
});
|
|
100
133
|
if (isAuthEnabled)
|
|
101
134
|
migrations.push({
|
|
102
|
-
name: '
|
|
135
|
+
name: '00000000000005_schema-password-reset-tokens',
|
|
103
136
|
up: async ({ context: pool }) => {
|
|
104
137
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
105
138
|
const uniqueConstraint = isMultiTenant
|
|
@@ -128,7 +161,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
128
161
|
});
|
|
129
162
|
if (isAuthEnabled)
|
|
130
163
|
migrations.push({
|
|
131
|
-
name: '
|
|
164
|
+
name: '00000000000006_schema-roles',
|
|
132
165
|
up: async ({ context: pool }) => {
|
|
133
166
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
134
167
|
const uniqueConstraint = isMultiTenant
|
|
@@ -150,7 +183,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
150
183
|
});
|
|
151
184
|
if (isAuthEnabled)
|
|
152
185
|
migrations.push({
|
|
153
|
-
name: '
|
|
186
|
+
name: '00000000000007_schema-user-roles',
|
|
154
187
|
up: async ({ context: pool }) => {
|
|
155
188
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
156
189
|
const uniqueConstraint = isMultiTenant
|
|
@@ -180,7 +213,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
180
213
|
});
|
|
181
214
|
if (isAuthEnabled)
|
|
182
215
|
migrations.push({
|
|
183
|
-
name: '
|
|
216
|
+
name: '00000000000008_schema-features',
|
|
184
217
|
up: async ({ context: pool }) => {
|
|
185
218
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
186
219
|
const uniqueConstraint = isMultiTenant
|
|
@@ -202,7 +235,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
202
235
|
});
|
|
203
236
|
if (isAuthEnabled)
|
|
204
237
|
migrations.push({
|
|
205
|
-
name: '
|
|
238
|
+
name: '00000000000009_schema-authorizations',
|
|
206
239
|
up: async ({ context: pool }) => {
|
|
207
240
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
208
241
|
const uniqueConstraint = isMultiTenant
|
|
@@ -235,7 +268,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
235
268
|
});
|
|
236
269
|
if (isMultiTenant) {
|
|
237
270
|
migrations.push({
|
|
238
|
-
name: '
|
|
271
|
+
name: '00000000000010_data-meta-org',
|
|
239
272
|
up: async ({ context: pool }) => {
|
|
240
273
|
const result = await pool.query(`
|
|
241
274
|
INSERT INTO "organizations" ("name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
@@ -254,7 +287,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
254
287
|
}
|
|
255
288
|
if (isAuthEnabled) {
|
|
256
289
|
migrations.push({
|
|
257
|
-
name: '
|
|
290
|
+
name: '00000000000011_data-admin-user',
|
|
258
291
|
up: async ({ context: pool }) => {
|
|
259
292
|
const client = await pool.connect();
|
|
260
293
|
try {
|
|
@@ -273,14 +306,19 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
273
306
|
const userData = {
|
|
274
307
|
email: config.auth?.adminUser?.email,
|
|
275
308
|
password: config.auth?.adminUser?.password,
|
|
276
|
-
firstName: 'Admin',
|
|
277
|
-
lastName: 'User',
|
|
278
309
|
displayName: 'Admin User',
|
|
279
310
|
};
|
|
280
311
|
if (isMultiTenant && systemUserContext.organization?._id) {
|
|
281
312
|
userData._orgId = systemUserContext.organization._id;
|
|
282
313
|
}
|
|
283
|
-
|
|
314
|
+
const personData = {
|
|
315
|
+
firstName: 'Admin',
|
|
316
|
+
lastName: 'User',
|
|
317
|
+
};
|
|
318
|
+
if (isMultiTenant && systemUserContext.organization?._id) {
|
|
319
|
+
personData._orgId = systemUserContext.organization._id;
|
|
320
|
+
}
|
|
321
|
+
await authService.createUser(systemUserContext, userData, personData);
|
|
284
322
|
}
|
|
285
323
|
finally {
|
|
286
324
|
client.release();
|
|
@@ -295,7 +333,7 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
295
333
|
}
|
|
296
334
|
if (config.auth) {
|
|
297
335
|
migrations.push({
|
|
298
|
-
name: '
|
|
336
|
+
name: '00000000000012_data-admin-authorizations',
|
|
299
337
|
up: async ({ context: pool }) => {
|
|
300
338
|
const client = await pool.connect();
|
|
301
339
|
try {
|