@dalmore/api-contracts 0.0.0-dev.10793c4 → 0.0.0-dev.1cb5ac4

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.
@@ -145,3 +145,27 @@ export const CompliancePostBonusTierZod = PostBonusTierZod.extend({
145
145
  export type CompliancePostBonusTierZod = z.infer<
146
146
  typeof CompliancePostBonusTierZod
147
147
  >;
148
+ export const PurchaseCalculationZod = z.object({
149
+ assetId: assetIdSchema,
150
+ totalAmount: z.number().positive().openapi({ example: 1000 }),
151
+ purchasedShares: z.number().positive().int().openapi({ example: 100 }),
152
+ });
153
+ export type PurchaseCalculationZod = z.infer<typeof PurchaseCalculationZod>;
154
+
155
+ export const PurchaseCalculationResponseZod = z.object({
156
+ bonusTierId: bonusTierIdSchema
157
+ .nullable()
158
+ .openapi({ example: 'bonus_tier_01j5y5ghx5fg68d663j1fvy2x7' }),
159
+ assetId: assetIdSchema.openapi({
160
+ example: 'asset_00041061050r3gg28a1c60t3gf',
161
+ }),
162
+ type: z
163
+ .nativeEnum(BonusType)
164
+ .nullable()
165
+ .openapi({ example: BonusType.PERCENTAGE }),
166
+ bonusShares: z.number().int().openapi({ example: 100 }),
167
+ });
168
+
169
+ export type PurchaseCalculationResponseZod = z.infer<
170
+ typeof PurchaseCalculationResponseZod
171
+ >;
@@ -3,6 +3,7 @@ import { extendZodWithOpenApi } from '@anatine/zod-openapi';
3
3
  import { TradeStatus } from './common.types';
4
4
  import { investorAccountIdSchema } from './investor-account.types';
5
5
  import { paymentMethodIdSchema } from './payment-methods.types';
6
+ import { userIdSchema } from './user.types';
6
7
 
7
8
  extendZodWithOpenApi(z);
8
9
 
@@ -10,7 +11,9 @@ export const PlaceTradeResponse = z.object({
10
11
  tradeStatus: z.nativeEnum(TradeStatus).optional(),
11
12
  });
12
13
  export const PlaceTradeBody = z.object({});
13
-
14
+ export const ClientPlacetradeBody = z.object({
15
+ userId: userIdSchema,
16
+ });
14
17
  export const PatchCartBody = z.object({
15
18
  investorAccountId: investorAccountIdSchema.optional(),
16
19
  paymentMethodId: paymentMethodIdSchema.optional(),
@@ -200,11 +200,6 @@ export enum UserType {
200
200
  DEMO = 'DEMO',
201
201
  }
202
202
 
203
- export enum UserStatus {
204
- ACTIVE = 'ACTIVE',
205
- LOCKED = 'LOCKED',
206
- }
207
-
208
203
  export enum UserRole {
209
204
  API_KEY = 'API_KEY',
210
205
  IMPORT = 'IMPORT',
@@ -306,7 +301,7 @@ export const AuthUserReq = BaseAuthReq.extend({
306
301
  lastName: z.string(),
307
302
  email: z.string().email(),
308
303
  provider: z.string(),
309
- status: z.lazy(() => z.nativeEnum(UserStatus)),
304
+ locked: z.boolean(),
310
305
  lastLoginAt: z.date().nullable(),
311
306
  loginCount: z.number(),
312
307
  requiresTwoFactorSetup: z.boolean().optional(),
@@ -1518,3 +1513,14 @@ export const SUBJECT_TYPE_MAP: Record<BulkExportType, string> = {
1518
1513
  [BulkExportType.SECONDARY_CUSTOMERS]: 'Secondary Customers',
1519
1514
  [BulkExportType.SECONDARY_TRADES]: 'Secondary Trades',
1520
1515
  };
1516
+
1517
+ export const StringToBooleanSchema = z.preprocess(
1518
+ (val) =>
1519
+ val === 'true' || val === '1'
1520
+ ? true
1521
+ : val === 'false' || val === '0'
1522
+ ? false
1523
+ : val,
1524
+ z.boolean(),
1525
+ );
1526
+ export type StringToBooleanSchema = z.infer<typeof StringToBooleanSchema>;
@@ -7,6 +7,7 @@ import {
7
7
  FileLabels,
8
8
  IPaginationMeta,
9
9
  OfferingType,
10
+ StringToBooleanSchema,
10
11
  } from './common.types';
11
12
  import { accountIdSchema } from './account.types';
12
13
 
@@ -330,15 +331,7 @@ export const GetInvestmentDashboardQueryZod = z.object({
330
331
  offerings: OfferingsArrayQueryZod.optional(),
331
332
  offeringTypes: OfferingTypesQueryZod.optional(),
332
333
  timeFilteringType: z.nativeEnum(DashboardTimeFilteringType),
333
- debug: z.preprocess(
334
- (val) =>
335
- val === 'true' || val === '1'
336
- ? true
337
- : val === 'false' || val === '0'
338
- ? false
339
- : val,
340
- z.boolean().optional(),
341
- ),
334
+ debug: StringToBooleanSchema.optional(),
342
335
  });
343
336
  export type GetInvestmentDashboardQueryZod = z.infer<
344
337
  typeof GetInvestmentDashboardQueryZod
@@ -10,6 +10,7 @@ import {
10
10
  ComplianceReview,
11
11
  DurationType,
12
12
  AssetType,
13
+ StringToBooleanSchema,
13
14
  } from './common.types';
14
15
  import { IBaseEntity } from './entity.types';
15
16
  import { IIssuer, issuerIdSchema } from './issuer.types';
@@ -370,15 +371,7 @@ export const IssuerOfferingsFilterZod = z.object({
370
371
  issuerId: z.lazy(() => issuerIdSchema).optional(),
371
372
  type: z.nativeEnum(OfferingType).optional(),
372
373
  status: z.nativeEnum(ComplianceReview).optional(),
373
- enabled: z.preprocess(
374
- (val) =>
375
- val === 'true' || val === '1'
376
- ? true
377
- : val === 'false' || val === '0'
378
- ? false
379
- : val,
380
- z.boolean().optional(),
381
- ),
374
+ enabled: StringToBooleanSchema.optional(),
382
375
  managedBy: z.nativeEnum(ManagedByType).optional(),
383
376
  versioningType: z.nativeEnum(OfferingVersioningType).optional(),
384
377
  combinedStatus: z.nativeEnum(OfferingStatus).optional(),
@@ -17,6 +17,7 @@ import {
17
17
  OfferingOnboardingStatus,
18
18
  AssetType,
19
19
  DurationType,
20
+ StringToBooleanSchema,
20
21
  } from './common.types';
21
22
  import { IBaseEntity } from './entity.types';
22
23
  import { fileIdSchema, FileZod } from './file.types';
@@ -346,15 +347,7 @@ export const OfferingFiltersZod = z.object({
346
347
  issuerId: z.lazy(() => issuerIdSchema).optional(),
347
348
  type: z.nativeEnum(OfferingType).optional(),
348
349
  status: z.nativeEnum(ComplianceReview).optional(),
349
- enabled: z.preprocess(
350
- (val) =>
351
- val === 'true' || val === '1'
352
- ? true
353
- : val === 'false' || val === '0'
354
- ? false
355
- : val,
356
- z.boolean().optional(),
357
- ),
350
+ enabled: StringToBooleanSchema.optional(),
358
351
  managedBy: z.nativeEnum(ManagedByType).optional(),
359
352
  versioningType: z.nativeEnum(OfferingVersioningType).optional(),
360
353
  combinedStatus: z.nativeEnum(OfferingStatus).optional(),
@@ -5,6 +5,7 @@ import {
5
5
  AccountStatus,
6
6
  AccountZod,
7
7
  IPaginationMeta,
8
+ StringToBooleanSchema,
8
9
  UrlSchema,
9
10
  } from './common.types';
10
11
  import { accountIdSchema } from './account.types';
@@ -73,15 +74,7 @@ export const SitesParamSchema = z.object({
73
74
  export const SitesFiltersZod = z.object({
74
75
  url: z.string().optional(),
75
76
  accountId: accountIdSchema.optional(),
76
- enabled: z.preprocess(
77
- (val) =>
78
- val === 'true' || val === '1'
79
- ? true
80
- : val === 'false' || val === '0'
81
- ? false
82
- : val,
83
- z.boolean().optional(),
84
- ),
77
+ enabled: StringToBooleanSchema.optional(),
85
78
  });
86
79
 
87
80
  const sitesInclude = z.enum(['account']);
@@ -8,6 +8,7 @@ import {
8
8
  IPaginationMeta,
9
9
  OfferingType,
10
10
  SignatureStatus,
11
+ StringToBooleanSchema,
11
12
  } from './common.types';
12
13
  import { fileIdSchema } from './file.types';
13
14
  import { accountIdSchema } from './account.types';
@@ -107,15 +108,7 @@ export type TradeLineItemQuery = z.infer<typeof TradeLineItemQuery>;
107
108
 
108
109
  export const TradeLineItemFiltersQuery = z.object({
109
110
  accountId: accountIdSchema.optional(),
110
- hasSubdoc: z.preprocess(
111
- (val) =>
112
- val === 'true' || val === '1'
113
- ? true
114
- : val === 'false' || val === '0'
115
- ? false
116
- : val,
117
- z.boolean().optional(),
118
- ),
111
+ hasSubdoc: StringToBooleanSchema.optional(),
119
112
  saStatus: z.nativeEnum(SignatureStatus).optional(),
120
113
  offeringId: z.lazy(() => offeringIdSchema).optional(),
121
114
  search: z.string().max(50).optional(),
@@ -39,7 +39,7 @@ import {
39
39
  import {
40
40
  tradeLineItemIdSchema,
41
41
  TradeLineItemZod,
42
- } from './trade-line-item.type';
42
+ } from './trade-line-item.types';
43
43
  import { TradeAdjustmentZod } from './trade-adjustment.type';
44
44
  import { TransactionZod } from './transaction.types';
45
45
  import { accountIdSchema } from './account.types';
@@ -8,8 +8,8 @@ import {
8
8
  ManagedByType,
9
9
  OfferingType,
10
10
  PortalType,
11
+ StringToBooleanSchema,
11
12
  UserRole,
12
- UserStatus,
13
13
  UserType,
14
14
  } from './common.types';
15
15
  import { dateOrString, IBaseEntity } from './entity.types';
@@ -51,6 +51,11 @@ export const UserDeleteResponse = z.object({
51
51
  });
52
52
  export type UserDeleteResponse = z.infer<typeof UserDeleteResponse>;
53
53
 
54
+ export const UserRestoreResponse = z.object({
55
+ message: z.string(),
56
+ });
57
+ export type UserRestoreResponse = z.infer<typeof UserRestoreResponse>;
58
+
54
59
  export const GetMeResponse = IBaseEntity.extend({
55
60
  accountId: z.string().nullable(),
56
61
  accountName: z.string().nullable(),
@@ -59,7 +64,7 @@ export const GetMeResponse = IBaseEntity.extend({
59
64
  email: z.string().email(),
60
65
  provider: z.string(),
61
66
  active: z.boolean(),
62
- status: z.lazy(() => z.nativeEnum(UserStatus)),
67
+ locked: z.boolean(),
63
68
  lastLoginAt: dateOrString.nullable(),
64
69
  loginCount: z.number(),
65
70
  role: z.string(),
@@ -157,7 +162,7 @@ export const UserZod = IBaseEntity.extend({
157
162
  onboarding: z.string().nullable(),
158
163
  account: AccountWithoutUsersZod.optional(),
159
164
  active: z.boolean(),
160
- status: z.nativeEnum(UserStatus),
165
+ locked: z.boolean(),
161
166
  userLogin: IBaseEntity.extend({
162
167
  firstName: z.string(),
163
168
  lastName: z.string(),
@@ -179,27 +184,9 @@ export const UserFiltersZod = z.object({
179
184
  search: z.string().max(50).optional(),
180
185
  role: z.nativeEnum(UserRole).optional(),
181
186
  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
- }),
187
+ locked: StringToBooleanSchema.optional(),
188
+ active: StringToBooleanSchema.optional(),
189
+ twoFactorEnabled: StringToBooleanSchema.optional(),
203
190
  });
204
191
 
205
192
  const usersInclude = z.enum(['account', 'role']);
@@ -274,7 +261,7 @@ export type IssuerUsersStatusUpdateResponse = z.infer<
274
261
  >;
275
262
 
276
263
  export const UpdateLockedStatus = z.object({
277
- status: z.nativeEnum(UserStatus),
264
+ locked: z.boolean(),
278
265
  });
279
266
 
280
267
  export type UpdateLockedStatus = z.infer<typeof UpdateLockedStatus>;
@@ -285,7 +272,7 @@ export const UsersSummaryFilterZod = z.object({
285
272
  portalType: z.nativeEnum(PortalType).optional(),
286
273
  search: z.string().trim().max(50).optional(),
287
274
  selectRole: z.nativeEnum(UserRole).optional(),
288
- status: z.nativeEnum(UserStatus).optional(),
275
+ locked: StringToBooleanSchema.optional(),
289
276
  });
290
277
  export type UsersSummaryFilterZod = z.infer<typeof UsersSummaryFilterZod>;
291
278
 
@@ -299,7 +286,7 @@ export const UsersSummaryZod = z.object({
299
286
  portalType: z.string(),
300
287
  loginCount: z.number().int(),
301
288
  lastLogin: z.date(),
302
- status: z.nativeEnum(UserStatus),
289
+ locked: z.boolean(),
303
290
  });
304
291
  export type UsersSummaryZod = z.infer<typeof UsersSummaryZod>;
305
292
 
@@ -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',
@@ -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
 
@@ -10,6 +10,8 @@ import {
10
10
  EstimateBonusTierCalculationResponseZod,
11
11
  EstimateBonusTierCalculationZod,
12
12
  IBonusTierList,
13
+ PurchaseCalculationResponseZod,
14
+ PurchaseCalculationZod,
13
15
  } from '../../../common/types/bonus-tier.types';
14
16
 
15
17
  const c = initContract();
@@ -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',
@@ -13,7 +13,7 @@ import {
13
13
  ReviewTradeLineItemStatus,
14
14
  TradeLineItemFiltersQuery,
15
15
  TradeLineItemResponse,
16
- } from '../../../common/types/trade-line-item.type';
16
+ } from '../../../common/types/trade-line-item.types';
17
17
 
18
18
  import { z } from 'zod';
19
19
  const c = initContract();
@@ -21,6 +21,7 @@ import {
21
21
  IssuersActiveStatusUpdateZod,
22
22
  UpdateLockedStatus,
23
23
  UpdateUserRoleZod,
24
+ UserRestoreResponse,
24
25
  } from '../../../common/types';
25
26
  import { z } from 'zod';
26
27
 
@@ -143,6 +144,26 @@ export const usersContract = c.router(
143
144
  500: InternalError,
144
145
  },
145
146
  },
147
+ restoreUser: {
148
+ summary: 'Restore user by id',
149
+ method: 'POST',
150
+ path: '/:id/restore',
151
+ metadata: {
152
+ auth: true,
153
+ },
154
+ pathParams: z.object({
155
+ id: userIdSchema,
156
+ }),
157
+ body: z.object({}),
158
+ responses: {
159
+ 200: UserRestoreResponse,
160
+ 400: BadRequestError,
161
+ 401: UnauthorizedError,
162
+ 403: ForbiddenError,
163
+ 404: NotFoundError,
164
+ 500: InternalError,
165
+ },
166
+ },
146
167
  updateActiveStatus: {
147
168
  summary: '[Admin] Update user active status',
148
169
  method: 'PATCH',
@@ -8,6 +8,8 @@ import {
8
8
  import {
9
9
  EstimateBonusTierCalculationResponseZod,
10
10
  EstimateBonusTierCalculationZod,
11
+ PurchaseCalculationResponseZod,
12
+ PurchaseCalculationZod,
11
13
  } from '../../../common/types/bonus-tier.types';
12
14
 
13
15
  const c = initContract();
@@ -30,6 +32,22 @@ export const bonusTiersContract = c.router(
30
32
  500: InternalError,
31
33
  },
32
34
  },
35
+ purchaseCalculation: {
36
+ summary: 'Calculate the bonus shares that would be awarded for a trade',
37
+ method: 'POST',
38
+ path: '/purchase-calculation',
39
+ metadata: {
40
+ auth: true,
41
+ },
42
+ body: PurchaseCalculationZod,
43
+ responses: {
44
+ 200: PurchaseCalculationResponseZod,
45
+ 400: BadRequestError,
46
+ 401: UnauthorizedError,
47
+ 403: ForbiddenError,
48
+ 500: InternalError,
49
+ },
50
+ },
33
51
  },
34
52
  {
35
53
  pathPrefix: 'bonus-tiers',
@@ -13,7 +13,7 @@ import {
13
13
  TradeLineItemResponse,
14
14
  TradeLineItemUpdate,
15
15
  TradeLineItemSignStatusUpdate,
16
- } from '../../../common/types/trade-line-item.type';
16
+ } from '../../../common/types/trade-line-item.types';
17
17
 
18
18
  const c = initContract();
19
19
 
@@ -10,6 +10,8 @@ import {
10
10
  EstimateBonusTierCalculationZod,
11
11
  IBonusTierList,
12
12
  PostBonusTierZod,
13
+ PurchaseCalculationResponseZod,
14
+ PurchaseCalculationZod,
13
15
  } from '../../../common/types/bonus-tier.types';
14
16
 
15
17
  const c = initContract();
@@ -32,6 +34,22 @@ export const bonusTiersContract = c.router(
32
34
  500: InternalError,
33
35
  },
34
36
  },
37
+ purchaseCalculation: {
38
+ summary: 'Calculate the bonus shares that would be awarded for a trade',
39
+ method: 'POST',
40
+ path: '/purchase-calculation',
41
+ metadata: {
42
+ auth: true,
43
+ },
44
+ body: PurchaseCalculationZod,
45
+ responses: {
46
+ 200: PurchaseCalculationResponseZod,
47
+ 400: BadRequestError,
48
+ 401: UnauthorizedError,
49
+ 403: ForbiddenError,
50
+ 500: InternalError,
51
+ },
52
+ },
35
53
  postBonusTier: {
36
54
  summary: 'Create a new bonus tier',
37
55
  method: 'POST',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dalmore/api-contracts",
3
- "version": "0.0.0-dev.10793c4",
3
+ "version": "0.0.0-dev.1cb5ac4",
4
4
  "description": "Type-safe API contracts for Dalmore Client Portal",
5
5
  "main": "./contracts/index.ts",
6
6
  "types": "./contracts/index.ts",