@dalmore/api-contracts 0.0.0-dev.785b227 → 0.0.0-dev.801385

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 (60) 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/activity.types.ts +1 -1
  6. package/common/types/auth.types.ts +7 -18
  7. package/common/types/bonus-tier.types.ts +33 -0
  8. package/common/types/cart.types.ts +4 -1
  9. package/common/types/common.types.ts +38 -6
  10. package/common/types/contact-us.types.ts +6 -2
  11. package/common/types/covered-person.types.ts +2 -1
  12. package/common/types/dashboard.types.ts +2 -9
  13. package/common/types/disbursements.types.ts +119 -3
  14. package/common/types/escrow-account.types.ts +3 -3
  15. package/common/types/file.types.ts +20 -4
  16. package/common/types/i-will-do-it-later.types.ts +68 -0
  17. package/common/types/index.ts +2 -0
  18. package/common/types/individuals.types.ts +5 -17
  19. package/common/types/investor-account.types.ts +2 -1
  20. package/common/types/invite.types.ts +27 -1
  21. package/common/types/issuer-offering.types.ts +13 -17
  22. package/common/types/issuer-payment-method.types.ts +41 -0
  23. package/common/types/issuer.types.ts +9 -0
  24. package/common/types/legal-entity.types.ts +3 -2
  25. package/common/types/note.types.ts +1 -1
  26. package/common/types/notification.types.ts +515 -29
  27. package/common/types/offering.types.ts +4 -9
  28. package/common/types/site-settings.types.ts +2 -1
  29. package/common/types/site.types.ts +2 -9
  30. package/common/types/{trade-line-item.type.ts → trade-line-item.types.ts} +2 -9
  31. package/common/types/trade.types.ts +48 -2
  32. package/common/types/transaction.types.ts +12 -1
  33. package/common/types/trusted-contact.types.ts +7 -7
  34. package/common/types/user.types.ts +17 -33
  35. package/contracts/clients/cart/index.ts +21 -1
  36. package/contracts/clients/index.ts +6 -0
  37. package/contracts/clients/issuer-payment-methods/index.ts +39 -0
  38. package/contracts/clients/payment-methods/index.ts +85 -0
  39. package/contracts/clients/trade-line-items/index.ts +1 -1
  40. package/contracts/clients/trades/index.ts +1 -1
  41. package/contracts/clients/transactions/index.ts +37 -0
  42. package/contracts/compliance/account-settings/index.ts +59 -0
  43. package/contracts/compliance/auth/index.ts +4 -3
  44. package/contracts/compliance/bonus-tiers/index.ts +21 -2
  45. package/contracts/compliance/index.ts +4 -0
  46. package/contracts/compliance/invites/index.ts +4 -12
  47. package/contracts/compliance/notification-channels/index.ts +251 -0
  48. package/contracts/compliance/trade-line-items/index.ts +1 -1
  49. package/contracts/compliance/trades/index.ts +19 -0
  50. package/contracts/compliance/users/index.ts +21 -0
  51. package/contracts/investors/bonus-tiers/index.ts +18 -0
  52. package/contracts/investors/individuals/index.ts +22 -0
  53. package/contracts/investors/trade-line-items/index.ts +1 -1
  54. package/contracts/issuers/account-settings/index.ts +36 -0
  55. package/contracts/issuers/auth/index.ts +4 -3
  56. package/contracts/issuers/bonus-tiers/index.ts +18 -0
  57. package/contracts/issuers/disbursements/index.ts +48 -12
  58. package/contracts/issuers/index.ts +4 -0
  59. package/contracts/issuers/notification-channels/index.ts +251 -0
  60. 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(),
@@ -1,10 +1,11 @@
1
+ import { z } from 'zod';
2
+ import { extendZodWithOpenApi } from '@anatine/zod-openapi';
1
3
  import { TypeID } from 'typeid-js';
2
4
  import {
3
5
  dateSchema,
4
6
  InvestorAccountType,
5
7
  numberPrecisionSchema,
6
8
  } from './common.types';
7
- import { z } from 'zod';
8
9
  import { IBaseEntity } from './entity.types';
9
10
  import { accountIdSchema } from './account.types';
10
11
  import {
@@ -18,7 +19,9 @@ import {
18
19
  investorAccountIdSchema,
19
20
  } from './investor-account.types';
20
21
  import { TransactionStatus, TransactionType } from './common.types';
22
+ import { userIdSchema } from './user.types';
21
23
  export { TransactionStatus, TransactionType };
24
+ extendZodWithOpenApi(z);
22
25
 
23
26
  export enum RefundPaymentMethod {
24
27
  CHECK = 'CHECK',
@@ -115,6 +118,14 @@ export type InvestorPostTransactionZod = z.infer<
115
118
  typeof InvestorPostTransactionZod
116
119
  >;
117
120
 
121
+ export const ClientPostTransactionZod = InvestorPostTransactionZod.extend({
122
+ userId: z
123
+ .lazy(() => userIdSchema)
124
+ .openapi({ example: 'user_01j5y5ghx5fg68d663j1fvy2x7' }),
125
+ });
126
+
127
+ export type ClientPostTransactionZod = z.infer<typeof ClientPostTransactionZod>;
128
+
118
129
  export const refundTransactionIdSchema = z.string().refine(
119
130
  (value) => {
120
131
  try {
@@ -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,
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { extendZodWithOpenApi } from '@anatine/zod-openapi';
2
3
  import {
3
4
  AccountStatus,
4
5
  AccountWithoutUsersZod,
@@ -7,12 +8,12 @@ import {
7
8
  ManagedByType,
8
9
  OfferingType,
9
10
  PortalType,
11
+ StringToBooleanSchema,
10
12
  UserRole,
11
- UserStatus,
12
13
  UserType,
14
+ EmailSchema,
13
15
  } from './common.types';
14
16
  import { dateOrString, IBaseEntity } from './entity.types';
15
- import { extendZodWithOpenApi } from '@anatine/zod-openapi';
16
17
  import { PhoneZodSchema } from './phone.type';
17
18
  import { IInvestorAccount } from './investor-account.types';
18
19
  import { TradeZod } from './trade.types';
@@ -51,6 +52,11 @@ export const UserDeleteResponse = z.object({
51
52
  });
52
53
  export type UserDeleteResponse = z.infer<typeof UserDeleteResponse>;
53
54
 
55
+ export const UserRestoreResponse = z.object({
56
+ message: z.string(),
57
+ });
58
+ export type UserRestoreResponse = z.infer<typeof UserRestoreResponse>;
59
+
54
60
  export const GetMeResponse = IBaseEntity.extend({
55
61
  accountId: z.string().nullable(),
56
62
  accountName: z.string().nullable(),
@@ -59,7 +65,7 @@ export const GetMeResponse = IBaseEntity.extend({
59
65
  email: z.string().email(),
60
66
  provider: z.string(),
61
67
  active: z.boolean(),
62
- status: z.lazy(() => z.nativeEnum(UserStatus)),
68
+ locked: z.boolean(),
63
69
  lastLoginAt: dateOrString.nullable(),
64
70
  loginCount: z.number(),
65
71
  role: z.string(),
@@ -142,11 +148,7 @@ export const UserMeUpdateZod = z.object({
142
148
  firstName: z.string().optional(),
143
149
  lastName: z.string().optional(),
144
150
  password: z.string().min(6).optional(),
145
- email: z
146
- .string()
147
- .email()
148
- .transform((val) => val.toLowerCase())
149
- .optional(),
151
+ email: EmailSchema.optional(),
150
152
  });
151
153
 
152
154
  export const UserZod = IBaseEntity.extend({
@@ -157,7 +159,7 @@ export const UserZod = IBaseEntity.extend({
157
159
  onboarding: z.string().nullable(),
158
160
  account: AccountWithoutUsersZod.optional(),
159
161
  active: z.boolean(),
160
- status: z.nativeEnum(UserStatus),
162
+ locked: z.boolean(),
161
163
  userLogin: IBaseEntity.extend({
162
164
  firstName: z.string(),
163
165
  lastName: z.string(),
@@ -179,27 +181,9 @@ export const UserFiltersZod = z.object({
179
181
  search: z.string().max(50).optional(),
180
182
  role: z.nativeEnum(UserRole).optional(),
181
183
  portal: z.string().optional(),
182
- status: z.nativeEnum(UserStatus).optional(),
183
- active: z
184
- .string()
185
- .optional()
186
- .refine((v) => !v || v === 'true' || v === 'false', {
187
- message: 'active must be a boolean string',
188
- })
189
- .transform((v) => {
190
- if (!v) return undefined;
191
- return v === 'true';
192
- }),
193
- twoFactorEnabled: z
194
- .string()
195
- .optional()
196
- .refine((v) => !v || v === 'true' || v === 'false', {
197
- message: 'twoFactorEnabled must be a boolean string',
198
- })
199
- .transform((v) => {
200
- if (!v) return undefined;
201
- return v === 'true';
202
- }),
184
+ locked: StringToBooleanSchema.optional(),
185
+ active: StringToBooleanSchema.optional(),
186
+ twoFactorEnabled: StringToBooleanSchema.optional(),
203
187
  });
204
188
 
205
189
  const usersInclude = z.enum(['account', 'role']);
@@ -274,7 +258,7 @@ export type IssuerUsersStatusUpdateResponse = z.infer<
274
258
  >;
275
259
 
276
260
  export const UpdateLockedStatus = z.object({
277
- status: z.nativeEnum(UserStatus),
261
+ locked: z.boolean(),
278
262
  });
279
263
 
280
264
  export type UpdateLockedStatus = z.infer<typeof UpdateLockedStatus>;
@@ -285,7 +269,7 @@ export const UsersSummaryFilterZod = z.object({
285
269
  portalType: z.nativeEnum(PortalType).optional(),
286
270
  search: z.string().trim().max(50).optional(),
287
271
  selectRole: z.nativeEnum(UserRole).optional(),
288
- status: z.nativeEnum(UserStatus).optional(),
272
+ locked: StringToBooleanSchema.optional(),
289
273
  });
290
274
  export type UsersSummaryFilterZod = z.infer<typeof UsersSummaryFilterZod>;
291
275
 
@@ -299,7 +283,7 @@ export const UsersSummaryZod = z.object({
299
283
  portalType: z.string(),
300
284
  loginCount: z.number().int(),
301
285
  lastLogin: z.date(),
302
- status: z.nativeEnum(UserStatus),
286
+ locked: z.boolean(),
303
287
  });
304
288
  export type UsersSummaryZod = z.infer<typeof UsersSummaryZod>;
305
289
 
@@ -10,7 +10,11 @@ import {
10
10
  userIdSchema,
11
11
  tradeIdSchema,
12
12
  } from '../../../common/types';
13
- import { PatchCartBody } from '../../../common/types/cart.types';
13
+ import {
14
+ PatchCartBody,
15
+ ClientPlacetradeBody,
16
+ PlaceTradeResponse,
17
+ } from '../../../common/types/cart.types';
14
18
 
15
19
  const c = initContract();
16
20
 
@@ -34,6 +38,22 @@ export const cartContract = c.router(
34
38
  500: InternalError,
35
39
  },
36
40
  },
41
+ postCheckout: {
42
+ summary: 'Place a trade (checkout button)',
43
+ method: 'POST',
44
+ path: '/checkout',
45
+ metadata: {
46
+ auth: true,
47
+ },
48
+ body: ClientPlacetradeBody,
49
+ responses: {
50
+ 200: PlaceTradeResponse,
51
+ 400: BadRequestError,
52
+ 401: UnauthorizedError,
53
+ 403: ForbiddenError,
54
+ 500: InternalError,
55
+ },
56
+ },
37
57
  patchCart: {
38
58
  summary: 'Patch a cart',
39
59
  method: 'PATCH',
@@ -16,7 +16,10 @@ import { secureRequestContract } from './secure-requests';
16
16
  import { aicContract } from './aic';
17
17
  import { authContract } from './auth';
18
18
  import { sitesContract } from './sites';
19
+ import { paymentMethodsContract } from './payment-methods';
20
+ import { issuerPaymentMethodsContract } from './issuer-payment-methods';
19
21
  import { tradeLineItemsContract } from './trade-line-items';
22
+ import { clientsTransactionsContract } from './transactions';
20
23
 
21
24
  const c = initContract();
22
25
 
@@ -34,13 +37,16 @@ export const clientsContract = c.router(
34
37
  filesPublic: filesPublicContract,
35
38
  individuals: individualsContract,
36
39
  investorAccounts: investorAccountsContract,
40
+ issuerPaymentMethods: issuerPaymentMethodsContract,
37
41
  issuers: issuersContract,
38
42
  legalEntities: legalEntityContract,
39
43
  offerings: offeringsContract,
44
+ paymentMethods: paymentMethodsContract,
40
45
  secureRequests: secureRequestContract,
41
46
  sites: sitesContract,
42
47
  tradeLineItems: tradeLineItemsContract,
43
48
  trades: tradesContract,
49
+ transactions: clientsTransactionsContract,
44
50
  },
45
51
  {
46
52
  pathPrefix: '/clients/api/v1/',
@@ -0,0 +1,39 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import {
3
+ ForbiddenError,
4
+ InternalError,
5
+ NotFoundError,
6
+ UnauthorizedError,
7
+ GetIssuerPaymentMethodZod,
8
+ IPaginatedIssuerPaymentMethod,
9
+ IssuerPaymentMethodsIncludeQuery,
10
+ PaginationOptionsZod,
11
+ } from '../../../common/types';
12
+
13
+ const c = initContract();
14
+
15
+ export const issuerPaymentMethodsContract = c.router(
16
+ {
17
+ getIssuerPaymentMethods: {
18
+ summary: 'Get issuer payment methods',
19
+ method: 'GET',
20
+ path: '',
21
+ metadata: {
22
+ auth: true,
23
+ },
24
+ query: PaginationOptionsZod.merge(GetIssuerPaymentMethodZod).merge(
25
+ IssuerPaymentMethodsIncludeQuery,
26
+ ),
27
+ responses: {
28
+ 200: IPaginatedIssuerPaymentMethod,
29
+ 401: UnauthorizedError,
30
+ 403: ForbiddenError,
31
+ 404: NotFoundError,
32
+ 500: InternalError,
33
+ },
34
+ },
35
+ },
36
+ {
37
+ pathPrefix: 'issuer-payment-methods',
38
+ },
39
+ );
@@ -0,0 +1,85 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import {
4
+ UnauthorizedError,
5
+ ForbiddenError,
6
+ NotFoundError,
7
+ userIdSchema,
8
+ BadRequestError,
9
+ InternalError,
10
+ } from '../../../common/types';
11
+ import {
12
+ PaymentMethodResponseArray,
13
+ PaymentMethodResponse,
14
+ PostPaymentMethod,
15
+ PostSetupIntentBody,
16
+ SetupIntentResponse,
17
+ } from '../../../common/types/payment-methods.types';
18
+
19
+ const c = initContract();
20
+
21
+ export const paymentMethodsContract = c.router(
22
+ {
23
+ getPaymentMethods: {
24
+ summary: 'Get payment methods for a user',
25
+ method: 'GET',
26
+ path: '',
27
+ metadata: {
28
+ auth: true,
29
+ },
30
+ query: z.object({
31
+ userId: userIdSchema,
32
+ }),
33
+ responses: {
34
+ 200: PaymentMethodResponseArray,
35
+ 401: UnauthorizedError,
36
+ 403: ForbiddenError,
37
+ 404: NotFoundError,
38
+ 500: InternalError,
39
+ },
40
+ },
41
+ createPaymentMethod: {
42
+ summary: 'Create payment method for a user',
43
+ method: 'POST',
44
+ path: '',
45
+ metadata: {
46
+ auth: true,
47
+ },
48
+ query: z.object({
49
+ userId: userIdSchema,
50
+ }),
51
+ body: PostPaymentMethod,
52
+ responses: {
53
+ 201: PaymentMethodResponse,
54
+ 400: BadRequestError,
55
+ 401: UnauthorizedError,
56
+ 403: ForbiddenError,
57
+ 404: NotFoundError,
58
+ 500: InternalError,
59
+ },
60
+ },
61
+ createSetupIntent: {
62
+ summary: 'Create payment method setup intent for a user',
63
+ method: 'POST',
64
+ path: '/intent',
65
+ metadata: {
66
+ auth: true,
67
+ },
68
+ query: z.object({
69
+ userId: userIdSchema,
70
+ }),
71
+ body: PostSetupIntentBody,
72
+ responses: {
73
+ 201: SetupIntentResponse,
74
+ 400: BadRequestError,
75
+ 401: UnauthorizedError,
76
+ 403: ForbiddenError,
77
+ 404: NotFoundError,
78
+ 500: InternalError,
79
+ },
80
+ },
81
+ },
82
+ {
83
+ pathPrefix: 'payment-methods',
84
+ },
85
+ );
@@ -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,37 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import {
3
+ BadRequestError,
4
+ InternalError,
5
+ NotFoundError,
6
+ UnauthorizedError,
7
+ } from '../../../common/types';
8
+ import {
9
+ ClientPostTransactionZod,
10
+ TransactionZod,
11
+ } from '../../../common/types/transaction.types';
12
+
13
+ const c = initContract();
14
+
15
+ export const clientsTransactionsContract = c.router(
16
+ {
17
+ postTransaction: {
18
+ summary: 'Create a transaction',
19
+ method: 'POST',
20
+ path: '',
21
+ metadata: {
22
+ auth: true,
23
+ },
24
+ body: ClientPostTransactionZod,
25
+ responses: {
26
+ 201: TransactionZod,
27
+ 400: BadRequestError,
28
+ 401: UnauthorizedError,
29
+ 404: NotFoundError,
30
+ 500: InternalError,
31
+ },
32
+ },
33
+ },
34
+ {
35
+ pathPrefix: 'transactions',
36
+ },
37
+ );
@@ -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',