@dalmore/api-contracts 0.0.0-dev.0fb0042 → 0.0.0-dev.15e31bc

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.
Files changed (43) hide show
  1. package/common/types/account-contact.types.ts +2 -1
  2. package/common/types/account-manager.types.ts +3 -7
  3. package/common/types/account-setting.types.ts +65 -0
  4. package/common/types/account.types.ts +1 -0
  5. package/common/types/auth.types.ts +7 -18
  6. package/common/types/bonus-tier.types.ts +33 -0
  7. package/common/types/common.types.ts +32 -6
  8. package/common/types/contact-us.types.ts +6 -2
  9. package/common/types/covered-person.types.ts +2 -1
  10. package/common/types/dashboard.types.ts +2 -9
  11. package/common/types/escrow-account.types.ts +3 -3
  12. package/common/types/individuals.types.ts +3 -2
  13. package/common/types/investor-account.types.ts +2 -1
  14. package/common/types/invite.types.ts +27 -1
  15. package/common/types/issuer-offering.types.ts +11 -17
  16. package/common/types/legal-entity.types.ts +3 -2
  17. package/common/types/notification.types.ts +515 -29
  18. package/common/types/offering.types.ts +2 -9
  19. package/common/types/site-settings.types.ts +2 -1
  20. package/common/types/site.types.ts +2 -9
  21. package/common/types/{trade-line-item.type.ts → trade-line-item.types.ts} +2 -9
  22. package/common/types/trade.types.ts +48 -2
  23. package/common/types/trusted-contact.types.ts +7 -7
  24. package/common/types/user.types.ts +11 -32
  25. package/contracts/clients/trade-line-items/index.ts +1 -1
  26. package/contracts/clients/trades/index.ts +1 -1
  27. package/contracts/compliance/account-settings/index.ts +59 -0
  28. package/contracts/compliance/auth/index.ts +4 -3
  29. package/contracts/compliance/bonus-tiers/index.ts +21 -2
  30. package/contracts/compliance/index.ts +4 -0
  31. package/contracts/compliance/invites/index.ts +4 -12
  32. package/contracts/compliance/notification-channels/index.ts +251 -0
  33. package/contracts/compliance/trade-line-items/index.ts +1 -1
  34. package/contracts/compliance/trades/index.ts +19 -0
  35. package/contracts/investors/bonus-tiers/index.ts +18 -0
  36. package/contracts/investors/trade-line-items/index.ts +1 -1
  37. package/contracts/issuers/account-settings/index.ts +36 -0
  38. package/contracts/issuers/auth/index.ts +4 -3
  39. package/contracts/issuers/bonus-tiers/index.ts +18 -0
  40. package/contracts/issuers/disbursements/index.ts +17 -17
  41. package/contracts/issuers/index.ts +4 -0
  42. package/contracts/issuers/notification-channels/index.ts +251 -0
  43. package/package.json +1 -1
@@ -22,12 +22,13 @@ import {
22
22
  AccountStatus,
23
23
  SavedQuery,
24
24
  } from './common.types';
25
- import { offeringIdSchema } from './offering.types';
25
+ import { IOffering, offeringIdSchema } from './offering.types';
26
26
  import { IBaseEntity } from './entity.types';
27
27
  import { extendZodWithOpenApi } from '@anatine/zod-openapi';
28
28
  import { TypeID } from 'typeid-js';
29
29
  import {
30
30
  paymentMethodIdSchema,
31
+ PaymentMethodResponse,
31
32
  PaymentMethodType,
32
33
  } from './payment-methods.types';
33
34
  import {
@@ -35,11 +36,12 @@ import {
35
36
  InvestorAccountExportFilters,
36
37
  ComplianceInvestorAccountExportFilters,
37
38
  RegisteredInvestorUserRawZod,
39
+ IInvestorAccount,
38
40
  } from './investor-account.types';
39
41
  import {
40
42
  tradeLineItemIdSchema,
41
43
  TradeLineItemZod,
42
- } from './trade-line-item.type';
44
+ } from './trade-line-item.types';
43
45
  import { TradeAdjustmentZod } from './trade-adjustment.type';
44
46
  import { TransactionZod } from './transaction.types';
45
47
  import { accountIdSchema } from './account.types';
@@ -132,6 +134,7 @@ export const CheckResultsSchema = z.object({
132
134
  export type CheckResults = z.infer<typeof CheckResultsSchema>;
133
135
 
134
136
  export const TradeIdPrefix = 'trade';
137
+ export const TradeSnapshotIdPrefix = 'trade_snapshot';
135
138
 
136
139
  export const tradeIdSchema = z.string().refine(
137
140
  (value) => {
@@ -170,6 +173,21 @@ export const tradeIdOrTidSchema = z.union([
170
173
  .openapi({ example: 'tid_00041061050r3gg28a1c60t3gf' }),
171
174
  ]);
172
175
 
176
+ export const tradeSnapshotIdSchema = z.string().refine(
177
+ (value) => {
178
+ try {
179
+ const tid = TypeID.fromString(value);
180
+ return tid.getType() === TradeSnapshotIdPrefix;
181
+ } catch {
182
+ return false;
183
+ }
184
+ },
185
+ {
186
+ message:
187
+ 'Invalid trade snapshot ID format. Must be a valid TypeID with "trade_snapshot" prefix. ex: trade_snapshot_00041061050r3gg28a1c60t3gf',
188
+ },
189
+ );
190
+
173
191
  export enum SaStatus {
174
192
  PENDING = BaseStatus.PENDING,
175
193
  SIGNED = BaseStatus.SIGNED,
@@ -274,9 +292,21 @@ export type TradeBalanceResultZod = z.infer<typeof TradeBalanceResultZod>;
274
292
 
275
293
  export const TradeZod = IBaseEntity.extend({
276
294
  investorAccountId: z.lazy(() => investorAccountIdSchema.nullable()),
295
+ investorAccount: z
296
+ .lazy(() => IInvestorAccount)
297
+ .optional()
298
+ .nullable(),
299
+ offering: z
300
+ .lazy(() => IOffering)
301
+ .optional()
302
+ .nullable(),
277
303
  accountId: accountIdSchema.nullable(),
278
304
  offeringId: z.lazy(() => offeringIdSchema.nullable()),
279
305
  paymentMethodId: z.lazy(() => paymentMethodIdSchema).nullable(),
306
+ paymentMethod: z
307
+ .lazy(() => PaymentMethodResponse)
308
+ .optional()
309
+ .nullable(),
280
310
  userId: z.lazy(() => userIdSchema.nullable()),
281
311
  tradeNumber: z.string(),
282
312
  ip: z.string().nullable(),
@@ -342,6 +372,21 @@ export const TradeZod = IBaseEntity.extend({
342
372
  });
343
373
  export type TradeZod = z.infer<typeof TradeZod>;
344
374
 
375
+ export enum SnapshotEvent {
376
+ COMPLIANCE_APPROVED = 'COMPLIANCE_APPROVED',
377
+ COMPLIANCE_REJECTED = 'COMPLIANCE_REJECTED',
378
+ CANCELLED = 'CANCELLED',
379
+ PLACED = 'PLACED',
380
+ SETTLED = 'SETTLED',
381
+ }
382
+
383
+ export const GetTradeSnapshotEventsResponse = z.object({
384
+ events: z.array(z.nativeEnum(SnapshotEvent)),
385
+ });
386
+ export type GetTradeSnapshotEventsResponse = z.infer<
387
+ typeof GetTradeSnapshotEventsResponse
388
+ >;
389
+
345
390
  export const IPaginatedTrade = z.object({
346
391
  items: z.array(TradeZod),
347
392
  meta: IPaginationMeta,
@@ -424,6 +469,7 @@ export const TradeFiltersZod = z.object({
424
469
  .openapi({
425
470
  example: 'issuer_01jfw4q6qef30s6fpqtsxw94ya',
426
471
  }),
472
+ snapshotEvent: z.nativeEnum(SnapshotEvent).optional(),
427
473
  offeringType: z.nativeEnum(OfferingType).optional(),
428
474
  managedBy: z.nativeEnum(ManagedByType).optional(),
429
475
  platform: z.nativeEnum(Platforms).optional(),
@@ -2,7 +2,11 @@ import { extendZodWithOpenApi } from '@anatine/zod-openapi';
2
2
  import { TypeID } from 'typeid-js';
3
3
  import { z } from 'zod';
4
4
  import { IBaseEntity } from './entity.types';
5
- import { IPaginationMeta, TrustedContactRelationship } from './common.types';
5
+ import {
6
+ EmailSchema,
7
+ IPaginationMeta,
8
+ TrustedContactRelationship,
9
+ } from './common.types';
6
10
  import { PhoneZodSchema } from './phone.type';
7
11
  import { AddressSchema } from './address.types';
8
12
  import { investorAccountIdSchema } from './investor-account.types';
@@ -68,7 +72,7 @@ export const PostTrustedContactZod = z
68
72
  .object({
69
73
  firstName: z.string().min(1).max(255).openapi({ example: 'John' }),
70
74
  lastName: z.string().min(1).max(255).openapi({ example: 'Doe' }),
71
- email: z.string().email().openapi({ example: 'john.doe@example.com' }),
75
+ email: EmailSchema.openapi({ example: 'john.doe@example.com' }),
72
76
  phone: PhoneZodSchema.nullable().optional(),
73
77
  relationship: z
74
78
  .nativeEnum(TrustedContactRelationship)
@@ -92,11 +96,7 @@ export const PatchTrustedContactZod = z
92
96
  .optional()
93
97
  .openapi({ example: 'John' }),
94
98
  lastName: z.string().min(1).max(255).optional().openapi({ example: 'Doe' }),
95
- email: z
96
- .string()
97
- .email()
98
- .optional()
99
- .openapi({ example: 'john.doe@example.com' }),
99
+ email: EmailSchema.optional(),
100
100
  phone: PhoneZodSchema.nullable().optional(),
101
101
  relationship: z.nativeEnum(TrustedContactRelationship).optional().openapi({
102
102
  example: TrustedContactRelationship.CHILD,
@@ -8,9 +8,10 @@ import {
8
8
  ManagedByType,
9
9
  OfferingType,
10
10
  PortalType,
11
+ StringToBooleanSchema,
11
12
  UserRole,
12
- UserStatus,
13
13
  UserType,
14
+ EmailSchema,
14
15
  } from './common.types';
15
16
  import { dateOrString, IBaseEntity } from './entity.types';
16
17
  import { PhoneZodSchema } from './phone.type';
@@ -64,7 +65,7 @@ export const GetMeResponse = IBaseEntity.extend({
64
65
  email: z.string().email(),
65
66
  provider: z.string(),
66
67
  active: z.boolean(),
67
- status: z.lazy(() => z.nativeEnum(UserStatus)),
68
+ locked: z.boolean(),
68
69
  lastLoginAt: dateOrString.nullable(),
69
70
  loginCount: z.number(),
70
71
  role: z.string(),
@@ -147,11 +148,7 @@ export const UserMeUpdateZod = z.object({
147
148
  firstName: z.string().optional(),
148
149
  lastName: z.string().optional(),
149
150
  password: z.string().min(6).optional(),
150
- email: z
151
- .string()
152
- .email()
153
- .transform((val) => val.toLowerCase())
154
- .optional(),
151
+ email: EmailSchema.optional(),
155
152
  });
156
153
 
157
154
  export const UserZod = IBaseEntity.extend({
@@ -162,7 +159,7 @@ export const UserZod = IBaseEntity.extend({
162
159
  onboarding: z.string().nullable(),
163
160
  account: AccountWithoutUsersZod.optional(),
164
161
  active: z.boolean(),
165
- status: z.nativeEnum(UserStatus),
162
+ locked: z.boolean(),
166
163
  userLogin: IBaseEntity.extend({
167
164
  firstName: z.string(),
168
165
  lastName: z.string(),
@@ -184,27 +181,9 @@ export const UserFiltersZod = z.object({
184
181
  search: z.string().max(50).optional(),
185
182
  role: z.nativeEnum(UserRole).optional(),
186
183
  portal: z.string().optional(),
187
- status: z.nativeEnum(UserStatus).optional(),
188
- active: z
189
- .string()
190
- .optional()
191
- .refine((v) => !v || v === 'true' || v === 'false', {
192
- message: 'active must be a boolean string',
193
- })
194
- .transform((v) => {
195
- if (!v) return undefined;
196
- return v === 'true';
197
- }),
198
- twoFactorEnabled: z
199
- .string()
200
- .optional()
201
- .refine((v) => !v || v === 'true' || v === 'false', {
202
- message: 'twoFactorEnabled must be a boolean string',
203
- })
204
- .transform((v) => {
205
- if (!v) return undefined;
206
- return v === 'true';
207
- }),
184
+ locked: StringToBooleanSchema.optional(),
185
+ active: StringToBooleanSchema.optional(),
186
+ twoFactorEnabled: StringToBooleanSchema.optional(),
208
187
  });
209
188
 
210
189
  const usersInclude = z.enum(['account', 'role']);
@@ -279,7 +258,7 @@ export type IssuerUsersStatusUpdateResponse = z.infer<
279
258
  >;
280
259
 
281
260
  export const UpdateLockedStatus = z.object({
282
- status: z.nativeEnum(UserStatus),
261
+ locked: z.boolean(),
283
262
  });
284
263
 
285
264
  export type UpdateLockedStatus = z.infer<typeof UpdateLockedStatus>;
@@ -290,7 +269,7 @@ export const UsersSummaryFilterZod = z.object({
290
269
  portalType: z.nativeEnum(PortalType).optional(),
291
270
  search: z.string().trim().max(50).optional(),
292
271
  selectRole: z.nativeEnum(UserRole).optional(),
293
- status: z.nativeEnum(UserStatus).optional(),
272
+ locked: StringToBooleanSchema.optional(),
294
273
  });
295
274
  export type UsersSummaryFilterZod = z.infer<typeof UsersSummaryFilterZod>;
296
275
 
@@ -304,7 +283,7 @@ export const UsersSummaryZod = z.object({
304
283
  portalType: z.string(),
305
284
  loginCount: z.number().int(),
306
285
  lastLogin: z.date(),
307
- status: z.nativeEnum(UserStatus),
286
+ locked: z.boolean(),
308
287
  });
309
288
  export type UsersSummaryZod = z.infer<typeof UsersSummaryZod>;
310
289
 
@@ -14,7 +14,7 @@ import {
14
14
  TradeLineItemQuery,
15
15
  TradeLineItemResponse,
16
16
  TradeLineItemUpdate,
17
- } from '../../../common/types/trade-line-item.type';
17
+ } from '../../../common/types/trade-line-item.types';
18
18
 
19
19
  const c = initContract();
20
20
 
@@ -26,7 +26,7 @@ import {
26
26
  PostTradeLineItem,
27
27
  TradeLineItemQuery,
28
28
  TradeLineItemResponse,
29
- } from '../../../common/types/trade-line-item.type';
29
+ } from '../../../common/types/trade-line-item.types';
30
30
 
31
31
  const c = initContract();
32
32
 
@@ -0,0 +1,59 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import {
4
+ accountSettingIdSchema,
5
+ AccountSettingsFilters,
6
+ AccountSettingsIncludeQuery,
7
+ IAccountSettingZod,
8
+ IPaginatedAccountSetting,
9
+ } from '../../../common/types/account-setting.types';
10
+ import {
11
+ InternalError,
12
+ NotFoundError,
13
+ PaginationOptionsZod,
14
+ UnauthorizedError,
15
+ } from '../../../common/types';
16
+
17
+ const c = initContract();
18
+
19
+ export const accountSettingsContract = c.router(
20
+ {
21
+ getAccountSettings: {
22
+ summary: 'Get account settings',
23
+ method: 'GET',
24
+ path: '',
25
+ metadata: {
26
+ auth: true,
27
+ },
28
+ query: PaginationOptionsZod.merge(AccountSettingsFilters).merge(
29
+ AccountSettingsIncludeQuery,
30
+ ),
31
+ responses: {
32
+ 200: IPaginatedAccountSetting,
33
+ 401: UnauthorizedError,
34
+ 500: InternalError,
35
+ },
36
+ },
37
+ getAccountSetting: {
38
+ summary: 'Get account setting by id',
39
+ method: 'GET',
40
+ path: '/:id',
41
+ metadata: {
42
+ auth: true,
43
+ },
44
+ pathParams: z.object({
45
+ id: accountSettingIdSchema,
46
+ }),
47
+ query: z.object({}).merge(AccountSettingsIncludeQuery),
48
+ responses: {
49
+ 200: IAccountSettingZod,
50
+ 401: UnauthorizedError,
51
+ 404: NotFoundError,
52
+ 500: InternalError,
53
+ },
54
+ },
55
+ },
56
+ {
57
+ pathPrefix: 'account-settings',
58
+ },
59
+ );
@@ -10,6 +10,7 @@ import {
10
10
  LoginBody2FA,
11
11
  NotFoundError,
12
12
  UnauthorizedError,
13
+ EmailSchema,
13
14
  } from '../../../common/types';
14
15
  import { z } from 'zod';
15
16
 
@@ -49,7 +50,7 @@ export const authContract = c.router(
49
50
  method: 'POST',
50
51
  path: 'forgot-password',
51
52
  body: z.object({
52
- email: z.string().email(),
53
+ email: EmailSchema,
53
54
  }),
54
55
  responses: {
55
56
  200: null,
@@ -75,7 +76,7 @@ export const authContract = c.router(
75
76
  method: 'POST',
76
77
  path: 'reset-password/verify',
77
78
  body: z.object({
78
- email: z.string().email(),
79
+ email: EmailSchema,
79
80
  code: z.string(),
80
81
  }),
81
82
  responses: {
@@ -90,7 +91,7 @@ export const authContract = c.router(
90
91
  method: 'POST',
91
92
  path: 'reset-password',
92
93
  body: z.object({
93
- email: z.string().email(),
94
+ email: EmailSchema,
94
95
  code: z.string(),
95
96
  password: z.string().min(6),
96
97
  }),
@@ -6,10 +6,12 @@ import {
6
6
  UnauthorizedError,
7
7
  } from '../../../common/types';
8
8
  import {
9
+ ComplianceEstimateBonusTierCalculationZod,
9
10
  CompliancePostBonusTierZod,
10
11
  EstimateBonusTierCalculationResponseZod,
11
- EstimateBonusTierCalculationZod,
12
12
  IBonusTierList,
13
+ PurchaseCalculationResponseZod,
14
+ PurchaseCalculationZod,
13
15
  } from '../../../common/types/bonus-tier.types';
14
16
 
15
17
  const c = initContract();
@@ -23,7 +25,7 @@ export const bonusTiersContract = c.router(
23
25
  metadata: {
24
26
  auth: true,
25
27
  },
26
- body: EstimateBonusTierCalculationZod,
28
+ body: ComplianceEstimateBonusTierCalculationZod,
27
29
  responses: {
28
30
  200: EstimateBonusTierCalculationResponseZod,
29
31
  400: BadRequestError,
@@ -32,6 +34,23 @@ export const bonusTiersContract = c.router(
32
34
  500: InternalError,
33
35
  },
34
36
  },
37
+ purchaseCalculation: {
38
+ summary:
39
+ '[ADMIN] Calculate the bonus shares that would be awarded for a trade',
40
+ method: 'POST',
41
+ path: '/purchase-calculation',
42
+ metadata: {
43
+ auth: true,
44
+ },
45
+ body: PurchaseCalculationZod,
46
+ responses: {
47
+ 200: PurchaseCalculationResponseZod,
48
+ 400: BadRequestError,
49
+ 401: UnauthorizedError,
50
+ 403: ForbiddenError,
51
+ 500: InternalError,
52
+ },
53
+ },
35
54
  postBonusTier: {
36
55
  summary: 'Create a new bonus tier',
37
56
  method: 'POST',
@@ -1,6 +1,7 @@
1
1
  import { accountsContract } from './accounts';
2
2
  import { accountContactsContract } from './account-contacts';
3
3
  import { accountManagersContract } from './account-managers';
4
+ import { accountSettingsContract } from './account-settings';
4
5
  import { activitiesContract } from './activities';
5
6
  import { apiKeysContract } from './api-keys';
6
7
  import { assetsContract } from './assets';
@@ -31,6 +32,7 @@ import { kycsContract } from './kyc';
31
32
  import { legalEntitiesContract } from './legal-entities';
32
33
  import { loginHistoriesContract } from './login-histories';
33
34
  import { notesContract } from './notes';
35
+ import { notificationChannelsContract } from './notification-channels';
34
36
  import { offeringsContract } from './offerings';
35
37
  import { pagesContract } from './pages';
36
38
  import { paymentMethodsContract } from './payment-methods';
@@ -75,6 +77,7 @@ export const complianceContract = c.router(
75
77
  accounts: accountsContract,
76
78
  accountContacts: accountContactsContract,
77
79
  accountManagers: accountManagersContract,
80
+ accountSettings: accountSettingsContract,
78
81
  activities: activitiesContract,
79
82
  apiKeys: apiKeysContract,
80
83
  assets: assetsContract,
@@ -112,6 +115,7 @@ export const complianceContract = c.router(
112
115
  legalEntities: legalEntitiesContract,
113
116
  loginHistories: loginHistoriesContract,
114
117
  notes: notesContract,
118
+ notificationChannels: notificationChannelsContract,
115
119
  offerings: offeringsContract,
116
120
  pages: pagesContract,
117
121
  paymentMethods: paymentMethodsContract,
@@ -1,6 +1,7 @@
1
1
  import { initContract } from '@ts-rest/core';
2
2
  import {
3
3
  BadRequestError,
4
+ CompliancePostInviteZod,
4
5
  ForbiddenError,
5
6
  InternalError,
6
7
  inviteIdSchema,
@@ -10,9 +11,8 @@ import {
10
11
  NotFoundError,
11
12
  PaginationOptionsZod,
12
13
  PatchInviteForComplianceZod,
13
- PortalType,
14
+ PostInviteZod,
14
15
  UnauthorizedError,
15
- UserRole,
16
16
  } from '../../../common/types';
17
17
  import { z } from 'zod';
18
18
 
@@ -42,12 +42,7 @@ export const invitesContract = c.router(
42
42
  metadata: {
43
43
  auth: true,
44
44
  },
45
- body: z.object({
46
- email: z.string().email(),
47
- role: z.nativeEnum(UserRole),
48
- accountId: z.string().optional(),
49
- portalType: z.nativeEnum(PortalType).optional(),
50
- }),
45
+ body: PostInviteZod,
51
46
  responses: {
52
47
  201: InviteWithUrl,
53
48
  400: BadRequestError,
@@ -62,10 +57,7 @@ export const invitesContract = c.router(
62
57
  metadata: {
63
58
  auth: true,
64
59
  },
65
- body: z.object({
66
- email: z.string().email(),
67
- role: z.nativeEnum(UserRole),
68
- }),
60
+ body: CompliancePostInviteZod,
69
61
  responses: {
70
62
  201: InviteWithUrl,
71
63
  400: BadRequestError,