@loomcore/api 0.1.76 → 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.
@@ -146,104 +146,105 @@ export const getPostgresTestSchema = (config) => {
146
146
  }
147
147
  });
148
148
  migrations.push({
149
- name: '00000000000105_6_schema-policies',
149
+ name: '00000000000105_6_schema-clients',
150
150
  up: async ({ context: pool }) => {
151
151
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
152
152
  await pool.query(`
153
- CREATE TABLE IF NOT EXISTS "policies" (
153
+ CREATE TABLE IF NOT EXISTS "clients" (
154
154
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
155
155
  ${orgColumnDef}
156
- "amount" NUMERIC NOT NULL,
157
- "frequency" VARCHAR NOT NULL,
156
+ "external_id" VARCHAR UNIQUE,
157
+ "person_id" INTEGER NOT NULL UNIQUE,
158
+ "agent_id" INTEGER,
158
159
  "_created" TIMESTAMPTZ NOT NULL,
159
160
  "_createdBy" INTEGER NOT NULL,
160
161
  "_updated" TIMESTAMPTZ NOT NULL,
161
162
  "_updatedBy" INTEGER NOT NULL,
162
163
  "_deleted" TIMESTAMPTZ,
163
- "_deletedBy" INTEGER
164
+ "_deletedBy" INTEGER,
165
+ CONSTRAINT fk_clients_person_id FOREIGN KEY ("person_id") REFERENCES persons("_id") ON DELETE CASCADE,
166
+ CONSTRAINT fk_clients_agent_id FOREIGN KEY ("agent_id") REFERENCES agents("_id") ON DELETE SET NULL
164
167
  )
165
168
  `);
166
169
  },
167
170
  down: async ({ context: pool }) => {
168
- await pool.query('DROP TABLE IF EXISTS "policies"');
171
+ await pool.query('DROP TABLE IF EXISTS "clients"');
169
172
  }
170
173
  });
171
174
  migrations.push({
172
- name: '00000000000105_7_schema-clients',
175
+ name: '00000000000105_7_schema-policies',
173
176
  up: async ({ context: pool }) => {
174
177
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
175
178
  await pool.query(`
176
- CREATE TABLE IF NOT EXISTS "clients" (
179
+ CREATE TABLE IF NOT EXISTS "policies" (
177
180
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
178
181
  ${orgColumnDef}
179
- "external_id" VARCHAR UNIQUE,
180
- "person_id" INTEGER NOT NULL UNIQUE,
181
- "agent_id" INTEGER,
182
+ "client_id" INTEGER NOT NULL,
183
+ "amount" NUMERIC NOT NULL,
184
+ "frequency" VARCHAR NOT NULL,
182
185
  "_created" TIMESTAMPTZ NOT NULL,
183
186
  "_createdBy" INTEGER NOT NULL,
184
187
  "_updated" TIMESTAMPTZ NOT NULL,
185
188
  "_updatedBy" INTEGER NOT NULL,
186
189
  "_deleted" TIMESTAMPTZ,
187
190
  "_deletedBy" INTEGER,
188
- CONSTRAINT fk_clients_person_id FOREIGN KEY ("person_id") REFERENCES persons("_id") ON DELETE CASCADE,
189
- CONSTRAINT fk_clients_agent_id FOREIGN KEY ("agent_id") REFERENCES agents("_id") ON DELETE SET NULL
191
+ CONSTRAINT fk_policies_client_id FOREIGN KEY ("client_id") REFERENCES clients("_id") ON DELETE CASCADE
190
192
  )
191
193
  `);
192
194
  },
193
195
  down: async ({ context: pool }) => {
194
- await pool.query('DROP TABLE IF EXISTS "clients"');
196
+ await pool.query('DROP TABLE IF EXISTS "policies"');
195
197
  }
196
198
  });
197
199
  migrations.push({
198
- name: '00000000000105_8_schema-clients-policies',
200
+ name: '00000000000105_8_schema-agents-policies',
199
201
  up: async ({ context: pool }) => {
200
202
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
201
203
  await pool.query(`
202
- CREATE TABLE IF NOT EXISTS clients_policies (
204
+ CREATE TABLE IF NOT EXISTS agents_policies (
203
205
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
204
206
  ${orgColumnDef}
205
- "client_id" INTEGER NOT NULL,
206
207
  "policy_id" INTEGER NOT NULL,
208
+ "agent_id" INTEGER NOT NULL,
207
209
  "_created" TIMESTAMPTZ NOT NULL,
208
210
  "_createdBy" INTEGER NOT NULL,
209
211
  "_updated" TIMESTAMPTZ NOT NULL,
210
212
  "_updatedBy" INTEGER NOT NULL,
211
213
  "_deleted" TIMESTAMPTZ,
212
214
  "_deletedBy" INTEGER,
213
- CONSTRAINT fk_clients_policies_client_id FOREIGN KEY ("client_id") REFERENCES clients("_id") ON DELETE CASCADE,
214
- CONSTRAINT fk_clients_policies_policy_id FOREIGN KEY ("policy_id") REFERENCES policies("_id") ON DELETE CASCADE,
215
- CONSTRAINT uk_clients_policies_client_policy UNIQUE ("client_id", "policy_id")
215
+ CONSTRAINT fk_agents_policies_policy_id FOREIGN KEY ("policy_id") REFERENCES policies("_id") ON DELETE CASCADE,
216
+ CONSTRAINT fk_agents_policies_agent_id FOREIGN KEY ("agent_id") REFERENCES agents("_id") ON DELETE CASCADE,
217
+ CONSTRAINT uk_agents_policies_policy_agent UNIQUE ("policy_id", "agent_id")
216
218
  )
217
219
  `);
218
220
  },
219
221
  down: async ({ context: pool }) => {
220
- await pool.query('DROP TABLE IF EXISTS "clients_policies"');
222
+ await pool.query('DROP TABLE IF EXISTS "agents_policies"');
221
223
  }
222
224
  });
223
225
  migrations.push({
224
- name: '00000000000105_8_schema-agents-policies',
226
+ name: '00000000000105_9_schema-premiums',
225
227
  up: async ({ context: pool }) => {
226
228
  const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
227
229
  await pool.query(`
228
- CREATE TABLE IF NOT EXISTS agents_policies (
230
+ CREATE TABLE IF NOT EXISTS "premiums" (
229
231
  "_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
230
232
  ${orgColumnDef}
231
233
  "policy_id" INTEGER NOT NULL,
232
- "agent_id" INTEGER NOT NULL,
234
+ "amount" NUMERIC NOT NULL,
235
+ "date" DATE NOT NULL,
233
236
  "_created" TIMESTAMPTZ NOT NULL,
234
237
  "_createdBy" INTEGER NOT NULL,
235
238
  "_updated" TIMESTAMPTZ NOT NULL,
236
239
  "_updatedBy" INTEGER NOT NULL,
237
240
  "_deleted" TIMESTAMPTZ,
238
241
  "_deletedBy" INTEGER,
239
- CONSTRAINT fk_agents_policies_policy_id FOREIGN KEY ("policy_id") REFERENCES policies("_id") ON DELETE CASCADE,
240
- CONSTRAINT fk_agents_policies_agent_id FOREIGN KEY ("agent_id") REFERENCES agents("_id") ON DELETE CASCADE,
241
- CONSTRAINT uk_agents_policies_policy_agent UNIQUE ("policy_id", "agent_id")
242
+ CONSTRAINT fk_premiums_policy_id FOREIGN KEY ("policy_id") REFERENCES policies("_id") ON DELETE CASCADE
242
243
  )
243
244
  `);
244
245
  },
245
246
  down: async ({ context: pool }) => {
246
- await pool.query('DROP TABLE IF EXISTS "agents_policies"');
247
+ await pool.query('DROP TABLE IF EXISTS "premiums"');
247
248
  }
248
249
  });
249
250
  migrations.push({
@@ -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
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- policies?: IPolicyModel[];
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
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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,20 @@ 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
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- policies: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
44
+ client_policies: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
45
+ client_id: import("@sinclair/typebox").TNumber;
45
46
  amount: import("@sinclair/typebox").TNumber;
46
47
  frequency: import("@sinclair/typebox").TString;
47
48
  agents: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
@@ -50,18 +51,23 @@ export declare const clientReportsSchema: import("@sinclair/typebox").TObject<{
50
51
  first_name: import("@sinclair/typebox").TString;
51
52
  middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
52
53
  last_name: import("@sinclair/typebox").TString;
53
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
54
+ client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
54
55
  phone_number: import("@sinclair/typebox").TString;
55
56
  phone_number_type: import("@sinclair/typebox").TString;
56
57
  is_default: import("@sinclair/typebox").TBoolean;
57
58
  }>>;
58
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
59
+ client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
59
60
  person_id: import("@sinclair/typebox").TNumber;
60
61
  email_address: import("@sinclair/typebox").TString;
61
62
  is_default: import("@sinclair/typebox").TBoolean;
62
63
  }>>;
63
64
  }>>;
64
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
+ }>>>;
65
71
  }>>>;
66
72
  }>;
67
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
- policies: Type.Optional(Type.Array(policySchema))
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
- email_addresses: IEmailAddressModel[];
10
- phone_numbers: IPhoneNumberModel[];
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
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
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
- phone_numbers: Type.Array(phoneNumberSchema),
10
- email_addresses: Type.Array(emailAddressSchema),
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,11 +1,15 @@
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 {
5
+ client_id: number;
4
6
  amount: number;
5
7
  frequency: string;
6
8
  agents?: IAgentModel[];
9
+ policy_premiums?: IPremiumModel[];
7
10
  }
8
11
  export declare const policySchema: import("@sinclair/typebox").TObject<{
12
+ client_id: import("@sinclair/typebox").TNumber;
9
13
  amount: import("@sinclair/typebox").TNumber;
10
14
  frequency: import("@sinclair/typebox").TString;
11
15
  agents: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
@@ -14,17 +18,22 @@ export declare const policySchema: import("@sinclair/typebox").TObject<{
14
18
  first_name: import("@sinclair/typebox").TString;
15
19
  middle_name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
16
20
  last_name: import("@sinclair/typebox").TString;
17
- phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
21
+ client_phone_numbers: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
18
22
  phone_number: import("@sinclair/typebox").TString;
19
23
  phone_number_type: import("@sinclair/typebox").TString;
20
24
  is_default: import("@sinclair/typebox").TBoolean;
21
25
  }>>;
22
- email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
26
+ client_email_addresses: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
23
27
  person_id: import("@sinclair/typebox").TNumber;
24
28
  email_address: import("@sinclair/typebox").TString;
25
29
  is_default: import("@sinclair/typebox").TBoolean;
26
30
  }>>;
27
31
  }>>;
28
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
+ }>>>;
29
38
  }>;
30
39
  export declare const policyModelSpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
@@ -1,9 +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({
6
+ client_id: Type.Number(),
5
7
  amount: Type.Number(),
6
8
  frequency: Type.String(),
7
- agents: Type.Optional(Type.Array(agentSchema))
9
+ agents: Type.Optional(Type.Array(agentSchema)),
10
+ policy_premiums: Type.Optional(Type.Array(premiumSchema))
8
11
  });
9
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;