@loomcore/api 0.1.77 → 0.1.78
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/dist/__tests__/postgres-test-migrations/postgres-test-schema.js +25 -0
- package/dist/databases/operations/__tests__/models/agent.model.d.ts +2 -2
- package/dist/databases/operations/__tests__/models/client-report.model.d.ts +13 -8
- package/dist/databases/operations/__tests__/models/client-report.model.js +1 -1
- package/dist/databases/operations/__tests__/models/person.model.d.ts +4 -4
- package/dist/databases/operations/__tests__/models/person.model.js +2 -2
- package/dist/databases/operations/__tests__/models/policy.model.d.ts +9 -2
- package/dist/databases/operations/__tests__/models/policy.model.js +3 -1
- package/dist/databases/operations/__tests__/models/premium.model.d.ts +12 -0
- package/dist/databases/operations/__tests__/models/premium.model.js +8 -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/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/package.json +1 -1
|
@@ -222,6 +222,31 @@ export const getPostgresTestSchema = (config) => {
|
|
|
222
222
|
await pool.query('DROP TABLE IF EXISTS "agents_policies"');
|
|
223
223
|
}
|
|
224
224
|
});
|
|
225
|
+
migrations.push({
|
|
226
|
+
name: '00000000000105_9_schema-premiums',
|
|
227
|
+
up: async ({ context: pool }) => {
|
|
228
|
+
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
229
|
+
await pool.query(`
|
|
230
|
+
CREATE TABLE IF NOT EXISTS "premiums" (
|
|
231
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
232
|
+
${orgColumnDef}
|
|
233
|
+
"policy_id" INTEGER NOT NULL,
|
|
234
|
+
"amount" NUMERIC NOT NULL,
|
|
235
|
+
"date" DATE NOT NULL,
|
|
236
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
237
|
+
"_createdBy" INTEGER NOT NULL,
|
|
238
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
239
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
240
|
+
"_deleted" TIMESTAMPTZ,
|
|
241
|
+
"_deletedBy" INTEGER,
|
|
242
|
+
CONSTRAINT fk_premiums_policy_id FOREIGN KEY ("policy_id") REFERENCES policies("_id") ON DELETE CASCADE
|
|
243
|
+
)
|
|
244
|
+
`);
|
|
245
|
+
},
|
|
246
|
+
down: async ({ context: pool }) => {
|
|
247
|
+
await pool.query('DROP TABLE IF EXISTS "premiums"');
|
|
248
|
+
}
|
|
249
|
+
});
|
|
225
250
|
migrations.push({
|
|
226
251
|
name: '00000000000106_schema-email-addresses',
|
|
227
252
|
up: async ({ context: pool }) => {
|
|
@@ -10,12 +10,12 @@ export declare const agentSchema: import("@sinclair/typebox").TObject<{
|
|
|
10
10
|
first_name: import("@sinclair/typebox").TString;
|
|
11
11
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
12
12
|
last_name: import("@sinclair/typebox").TString;
|
|
13
|
-
|
|
13
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
14
14
|
phone_number: import("@sinclair/typebox").TString;
|
|
15
15
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
16
16
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
17
17
|
}>>;
|
|
18
|
-
|
|
18
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
19
19
|
person_id: import("@sinclair/typebox").TNumber;
|
|
20
20
|
email_address: import("@sinclair/typebox").TString;
|
|
21
21
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
@@ -5,19 +5,19 @@ import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
|
5
5
|
export interface IClientReportsModel extends IEntity, IAuditable {
|
|
6
6
|
client_person: IPersonModel;
|
|
7
7
|
agent?: IAgentModel;
|
|
8
|
-
|
|
8
|
+
client_policies?: IPolicyModel[];
|
|
9
9
|
}
|
|
10
10
|
export declare const clientReportsSchema: import("@sinclair/typebox").TObject<{
|
|
11
11
|
client_person: import("@sinclair/typebox").TObject<{
|
|
12
12
|
first_name: import("@sinclair/typebox").TString;
|
|
13
13
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
14
14
|
last_name: import("@sinclair/typebox").TString;
|
|
15
|
-
|
|
15
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
16
16
|
phone_number: import("@sinclair/typebox").TString;
|
|
17
17
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
18
18
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
19
19
|
}>>;
|
|
20
|
-
|
|
20
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
21
21
|
person_id: import("@sinclair/typebox").TNumber;
|
|
22
22
|
email_address: import("@sinclair/typebox").TString;
|
|
23
23
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
@@ -29,19 +29,19 @@ export declare const clientReportsSchema: import("@sinclair/typebox").TObject<{
|
|
|
29
29
|
first_name: import("@sinclair/typebox").TString;
|
|
30
30
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
31
31
|
last_name: import("@sinclair/typebox").TString;
|
|
32
|
-
|
|
32
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
33
33
|
phone_number: import("@sinclair/typebox").TString;
|
|
34
34
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
35
35
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
36
36
|
}>>;
|
|
37
|
-
|
|
37
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
38
38
|
person_id: import("@sinclair/typebox").TNumber;
|
|
39
39
|
email_address: import("@sinclair/typebox").TString;
|
|
40
40
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
41
41
|
}>>;
|
|
42
42
|
}>>;
|
|
43
43
|
}>>;
|
|
44
|
-
|
|
44
|
+
client_policies: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
45
45
|
client_id: import("@sinclair/typebox").TNumber;
|
|
46
46
|
amount: import("@sinclair/typebox").TNumber;
|
|
47
47
|
frequency: import("@sinclair/typebox").TString;
|
|
@@ -51,18 +51,23 @@ export declare const clientReportsSchema: import("@sinclair/typebox").TObject<{
|
|
|
51
51
|
first_name: import("@sinclair/typebox").TString;
|
|
52
52
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
53
53
|
last_name: import("@sinclair/typebox").TString;
|
|
54
|
-
|
|
54
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
55
55
|
phone_number: import("@sinclair/typebox").TString;
|
|
56
56
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
57
57
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
58
58
|
}>>;
|
|
59
|
-
|
|
59
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
60
60
|
person_id: import("@sinclair/typebox").TNumber;
|
|
61
61
|
email_address: import("@sinclair/typebox").TString;
|
|
62
62
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
63
63
|
}>>;
|
|
64
64
|
}>>;
|
|
65
65
|
}>>>;
|
|
66
|
+
policy_premiums: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
67
|
+
policy_id: import("@sinclair/typebox").TNumber;
|
|
68
|
+
amount: import("@sinclair/typebox").TNumber;
|
|
69
|
+
date: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TDate, import("@sinclair/typebox").TString]>;
|
|
70
|
+
}>>>;
|
|
66
71
|
}>>>;
|
|
67
72
|
}>;
|
|
68
73
|
export declare const clientReportsModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
@@ -6,6 +6,6 @@ import { Type } from "@sinclair/typebox";
|
|
|
6
6
|
export const clientReportsSchema = Type.Object({
|
|
7
7
|
client_person: personSchema,
|
|
8
8
|
agent: Type.Optional(agentSchema),
|
|
9
|
-
|
|
9
|
+
client_policies: Type.Optional(Type.Array(policySchema))
|
|
10
10
|
});
|
|
11
11
|
export const clientReportsModelSpec = entityUtils.getModelSpec(clientReportsSchema, { isAuditable: true });
|
|
@@ -6,20 +6,20 @@ export interface IPersonModel extends IEntity, IAuditable {
|
|
|
6
6
|
first_name: string;
|
|
7
7
|
middle_name: string | null;
|
|
8
8
|
last_name: string;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
client_email_addresses: IEmailAddressModel[];
|
|
10
|
+
client_phone_numbers: IPhoneNumberModel[];
|
|
11
11
|
school?: ISchoolModel;
|
|
12
12
|
}
|
|
13
13
|
export declare const personSchema: import("@sinclair/typebox").TObject<{
|
|
14
14
|
first_name: import("@sinclair/typebox").TString;
|
|
15
15
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
16
16
|
last_name: import("@sinclair/typebox").TString;
|
|
17
|
-
|
|
17
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
18
18
|
phone_number: import("@sinclair/typebox").TString;
|
|
19
19
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
20
20
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
21
21
|
}>>;
|
|
22
|
-
|
|
22
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
23
23
|
person_id: import("@sinclair/typebox").TNumber;
|
|
24
24
|
email_address: import("@sinclair/typebox").TString;
|
|
25
25
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
@@ -6,7 +6,7 @@ export const personSchema = Type.Object({
|
|
|
6
6
|
first_name: Type.String(),
|
|
7
7
|
middle_name: Type.Optional(Type.String()),
|
|
8
8
|
last_name: Type.String(),
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
client_phone_numbers: Type.Array(phoneNumberSchema),
|
|
10
|
+
client_email_addresses: Type.Array(emailAddressSchema),
|
|
11
11
|
});
|
|
12
12
|
export const personModelSpec = entityUtils.getModelSpec(personSchema, { isAuditable: true });
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
2
2
|
import { IAgentModel } from "./agent.model.js";
|
|
3
|
+
import { IPremiumModel } from "./premium.model.js";
|
|
3
4
|
export interface IPolicyModel extends IEntity, IAuditable {
|
|
4
5
|
client_id: number;
|
|
5
6
|
amount: number;
|
|
6
7
|
frequency: string;
|
|
7
8
|
agents?: IAgentModel[];
|
|
9
|
+
policy_premiums?: IPremiumModel[];
|
|
8
10
|
}
|
|
9
11
|
export declare const policySchema: import("@sinclair/typebox").TObject<{
|
|
10
12
|
client_id: import("@sinclair/typebox").TNumber;
|
|
@@ -16,17 +18,22 @@ export declare const policySchema: import("@sinclair/typebox").TObject<{
|
|
|
16
18
|
first_name: import("@sinclair/typebox").TString;
|
|
17
19
|
middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
18
20
|
last_name: import("@sinclair/typebox").TString;
|
|
19
|
-
|
|
21
|
+
client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
20
22
|
phone_number: import("@sinclair/typebox").TString;
|
|
21
23
|
phone_number_type: import("@sinclair/typebox").TString;
|
|
22
24
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
23
25
|
}>>;
|
|
24
|
-
|
|
26
|
+
client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
25
27
|
person_id: import("@sinclair/typebox").TNumber;
|
|
26
28
|
email_address: import("@sinclair/typebox").TString;
|
|
27
29
|
is_default: import("@sinclair/typebox").TBoolean;
|
|
28
30
|
}>>;
|
|
29
31
|
}>>;
|
|
30
32
|
}>>>;
|
|
33
|
+
policy_premiums: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
34
|
+
policy_id: import("@sinclair/typebox").TNumber;
|
|
35
|
+
amount: import("@sinclair/typebox").TNumber;
|
|
36
|
+
date: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TDate, import("@sinclair/typebox").TString]>;
|
|
37
|
+
}>>>;
|
|
31
38
|
}>;
|
|
32
39
|
export declare const policyModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { entityUtils } from "@loomcore/common/utils";
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
3
|
import { agentSchema } from "./agent.model.js";
|
|
4
|
+
import { premiumSchema } from "./premium.model.js";
|
|
4
5
|
export const policySchema = Type.Object({
|
|
5
6
|
client_id: Type.Number(),
|
|
6
7
|
amount: Type.Number(),
|
|
7
8
|
frequency: Type.String(),
|
|
8
|
-
agents: Type.Optional(Type.Array(agentSchema))
|
|
9
|
+
agents: Type.Optional(Type.Array(agentSchema)),
|
|
10
|
+
policy_premiums: Type.Optional(Type.Array(premiumSchema))
|
|
9
11
|
});
|
|
10
12
|
export const policyModelSpec = entityUtils.getModelSpec(policySchema, { isAuditable: true });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IAuditable, IEntity } from "@loomcore/common/models";
|
|
2
|
+
export interface IPremiumModel extends IEntity, IAuditable {
|
|
3
|
+
policy_id: number;
|
|
4
|
+
amount: number;
|
|
5
|
+
date: Date | string;
|
|
6
|
+
}
|
|
7
|
+
export declare const premiumSchema: 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 premiumModelSpec: 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 premiumSchema = Type.Object({
|
|
4
|
+
policy_id: Type.Number(),
|
|
5
|
+
amount: Type.Number(),
|
|
6
|
+
date: Type.Union([Type.Date(), Type.String()])
|
|
7
|
+
});
|
|
8
|
+
export const premiumModelSpec = entityUtils.getModelSpec(premiumSchema, { 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;
|