@dalmore/api-contracts 0.0.0-dev.7c97041 → 0.0.0-dev.988f3c3

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 (34) hide show
  1. package/common/types/account-setting.types.ts +65 -0
  2. package/common/types/account.types.ts +1 -0
  3. package/common/types/bonus-tier.types.ts +33 -0
  4. package/common/types/cart.types.ts +4 -1
  5. package/common/types/common.types.ts +16 -6
  6. package/common/types/dashboard.types.ts +2 -9
  7. package/common/types/individuals.types.ts +2 -15
  8. package/common/types/issuer-offering.types.ts +11 -17
  9. package/common/types/notification.types.ts +515 -29
  10. package/common/types/offering.types.ts +2 -9
  11. package/common/types/site.types.ts +2 -9
  12. package/common/types/{trade-line-item.type.ts → trade-line-item.types.ts} +2 -9
  13. package/common/types/trade.types.ts +1 -1
  14. package/common/types/transaction.types.ts +12 -1
  15. package/common/types/user.types.ts +15 -28
  16. package/contracts/clients/cart/index.ts +21 -1
  17. package/contracts/clients/index.ts +2 -0
  18. package/contracts/clients/trade-line-items/index.ts +1 -1
  19. package/contracts/clients/trades/index.ts +1 -1
  20. package/contracts/clients/transactions/index.ts +37 -0
  21. package/contracts/compliance/account-settings/index.ts +59 -0
  22. package/contracts/compliance/bonus-tiers/index.ts +21 -2
  23. package/contracts/compliance/index.ts +4 -0
  24. package/contracts/compliance/notification-channels/index.ts +251 -0
  25. package/contracts/compliance/trade-line-items/index.ts +1 -1
  26. package/contracts/compliance/users/index.ts +21 -0
  27. package/contracts/investors/bonus-tiers/index.ts +18 -0
  28. package/contracts/investors/trade-line-items/index.ts +1 -1
  29. package/contracts/issuers/account-settings/index.ts +36 -0
  30. package/contracts/issuers/bonus-tiers/index.ts +18 -0
  31. package/contracts/issuers/disbursements/index.ts +17 -17
  32. package/contracts/issuers/index.ts +4 -0
  33. package/contracts/issuers/notification-channels/index.ts +251 -0
  34. package/package.json +1 -1
@@ -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,11 @@ import {
7
8
  ManagedByType,
8
9
  OfferingType,
9
10
  PortalType,
11
+ StringToBooleanSchema,
10
12
  UserRole,
11
- UserStatus,
12
13
  UserType,
13
14
  } from './common.types';
14
15
  import { dateOrString, IBaseEntity } from './entity.types';
15
- import { extendZodWithOpenApi } from '@anatine/zod-openapi';
16
16
  import { PhoneZodSchema } from './phone.type';
17
17
  import { IInvestorAccount } from './investor-account.types';
18
18
  import { TradeZod } from './trade.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',
@@ -19,6 +19,7 @@ import { sitesContract } from './sites';
19
19
  import { paymentMethodsContract } from './payment-methods';
20
20
  import { issuerPaymentMethodsContract } from './issuer-payment-methods';
21
21
  import { tradeLineItemsContract } from './trade-line-items';
22
+ import { clientsTransactionsContract } from './transactions';
22
23
 
23
24
  const c = initContract();
24
25
 
@@ -45,6 +46,7 @@ export const clientsContract = c.router(
45
46
  sites: sitesContract,
46
47
  tradeLineItems: tradeLineItemsContract,
47
48
  trades: tradesContract,
49
+ transactions: clientsTransactionsContract,
48
50
  },
49
51
  {
50
52
  pathPrefix: '/clients/api/v1/',
@@ -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
+ );
@@ -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,
@@ -0,0 +1,251 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import {
4
+ CreateChannelInputSchema,
5
+ CreateTriggerInputSchema,
6
+ IAvailableTriggersResponse,
7
+ INotificationChannelTriggerZod,
8
+ INotificationChannelZod,
9
+ INotificationRecordZod,
10
+ IPaginatedNotificationChannel,
11
+ IPaginatedNotificationRecord,
12
+ NotificationChannelFilters,
13
+ NotificationChannelsIncludeQuery,
14
+ notificationChannelIdSchema,
15
+ notificationChannelTriggerIdSchema,
16
+ NotificationRecordFilters,
17
+ NotificationRecordsIncludeQuery,
18
+ notificationRecordIdSchema,
19
+ UpdateChannelInputSchema,
20
+ } from '../../../common/types/notification.types';
21
+ import {
22
+ BadRequestError,
23
+ InternalError,
24
+ NotFoundError,
25
+ PaginationOptionsZod,
26
+ UnauthorizedError,
27
+ } from '../../../common/types';
28
+
29
+ const c = initContract();
30
+
31
+ export const notificationChannelsContract = c.router(
32
+ {
33
+ getChannels: {
34
+ summary: 'Get notification channels',
35
+ method: 'GET',
36
+ path: '',
37
+ metadata: {
38
+ auth: true,
39
+ },
40
+ query: PaginationOptionsZod.merge(NotificationChannelFilters).merge(
41
+ NotificationChannelsIncludeQuery,
42
+ ),
43
+ responses: {
44
+ 200: IPaginatedNotificationChannel,
45
+ 401: UnauthorizedError,
46
+ 500: InternalError,
47
+ },
48
+ },
49
+ getChannel: {
50
+ summary: 'Get notification channel by id',
51
+ method: 'GET',
52
+ path: '/:id',
53
+ metadata: {
54
+ auth: true,
55
+ },
56
+ pathParams: z.object({
57
+ id: notificationChannelIdSchema,
58
+ }),
59
+ query: z.object({}).merge(NotificationChannelsIncludeQuery),
60
+ responses: {
61
+ 200: INotificationChannelZod,
62
+ 401: UnauthorizedError,
63
+ 404: NotFoundError,
64
+ 500: InternalError,
65
+ },
66
+ },
67
+ createChannel: {
68
+ summary: 'Create notification channel',
69
+ method: 'POST',
70
+ path: '',
71
+ metadata: {
72
+ auth: true,
73
+ },
74
+ body: CreateChannelInputSchema,
75
+ responses: {
76
+ 201: INotificationChannelZod,
77
+ 400: BadRequestError,
78
+ 401: UnauthorizedError,
79
+ 500: InternalError,
80
+ },
81
+ },
82
+ updateChannel: {
83
+ summary: 'Update notification channel',
84
+ method: 'PATCH',
85
+ path: '/:id',
86
+ metadata: {
87
+ auth: true,
88
+ },
89
+ pathParams: z.object({
90
+ id: notificationChannelIdSchema,
91
+ }),
92
+ body: UpdateChannelInputSchema,
93
+ responses: {
94
+ 200: INotificationChannelZod,
95
+ 400: BadRequestError,
96
+ 401: UnauthorizedError,
97
+ 404: NotFoundError,
98
+ 500: InternalError,
99
+ },
100
+ },
101
+ deleteChannel: {
102
+ summary: 'Delete notification channel',
103
+ method: 'DELETE',
104
+ path: '/:id',
105
+ metadata: {
106
+ auth: true,
107
+ },
108
+ pathParams: z.object({
109
+ id: notificationChannelIdSchema,
110
+ }),
111
+ body: z.object({}),
112
+ responses: {
113
+ 200: z.object({ success: z.boolean() }),
114
+ 401: UnauthorizedError,
115
+ 404: NotFoundError,
116
+ 500: InternalError,
117
+ },
118
+ },
119
+ createTrigger: {
120
+ summary: 'Create notification channel trigger',
121
+ method: 'POST',
122
+ path: '/:id/triggers',
123
+ metadata: {
124
+ auth: true,
125
+ },
126
+ pathParams: z.object({
127
+ id: notificationChannelIdSchema,
128
+ }),
129
+ body: CreateTriggerInputSchema.omit({ notificationChannelId: true }),
130
+ responses: {
131
+ 201: INotificationChannelTriggerZod,
132
+ 400: BadRequestError,
133
+ 401: UnauthorizedError,
134
+ 404: NotFoundError,
135
+ 500: InternalError,
136
+ },
137
+ },
138
+ getAvailableTriggers: {
139
+ summary: 'Get all available triggers for a channel',
140
+ method: 'GET',
141
+ path: '/:id/triggers/available',
142
+ metadata: {
143
+ auth: true,
144
+ },
145
+ pathParams: z.object({
146
+ id: notificationChannelIdSchema,
147
+ }),
148
+ responses: {
149
+ 200: IAvailableTriggersResponse,
150
+ 401: UnauthorizedError,
151
+ 404: NotFoundError,
152
+ 500: InternalError,
153
+ },
154
+ },
155
+ updateTrigger: {
156
+ summary: 'Update notification channel trigger',
157
+ method: 'PATCH',
158
+ path: '/:id/triggers/:triggerId',
159
+ metadata: {
160
+ auth: true,
161
+ },
162
+ pathParams: z.object({
163
+ id: notificationChannelIdSchema,
164
+ triggerId: notificationChannelTriggerIdSchema,
165
+ }),
166
+ body: z.object({ enabled: z.boolean() }),
167
+ responses: {
168
+ 200: INotificationChannelTriggerZod,
169
+ 400: BadRequestError,
170
+ 401: UnauthorizedError,
171
+ 404: NotFoundError,
172
+ 500: InternalError,
173
+ },
174
+ },
175
+ deleteTrigger: {
176
+ summary: 'Delete notification channel trigger',
177
+ method: 'DELETE',
178
+ path: '/:id/triggers/:triggerId',
179
+ metadata: {
180
+ auth: true,
181
+ },
182
+ pathParams: z.object({
183
+ id: notificationChannelIdSchema,
184
+ triggerId: notificationChannelTriggerIdSchema,
185
+ }),
186
+ body: z.object({}),
187
+ responses: {
188
+ 200: z.object({ success: z.boolean() }),
189
+ 401: UnauthorizedError,
190
+ 404: NotFoundError,
191
+ 500: InternalError,
192
+ },
193
+ },
194
+ getRecords: {
195
+ summary: 'Get notification records',
196
+ method: 'GET',
197
+ path: '/records',
198
+ metadata: {
199
+ auth: true,
200
+ },
201
+ query: PaginationOptionsZod.merge(NotificationRecordFilters).merge(
202
+ NotificationRecordsIncludeQuery,
203
+ ),
204
+ responses: {
205
+ 200: IPaginatedNotificationRecord,
206
+ 401: UnauthorizedError,
207
+ 500: InternalError,
208
+ },
209
+ },
210
+ getRecord: {
211
+ summary: 'Get notification record by id',
212
+ method: 'GET',
213
+ path: '/records/:recordId',
214
+ metadata: {
215
+ auth: true,
216
+ },
217
+ pathParams: z.object({
218
+ recordId: notificationRecordIdSchema,
219
+ }),
220
+ query: z.object({}).merge(NotificationRecordsIncludeQuery),
221
+ responses: {
222
+ 200: INotificationRecordZod,
223
+ 401: UnauthorizedError,
224
+ 404: NotFoundError,
225
+ 500: InternalError,
226
+ },
227
+ },
228
+ retryRecord: {
229
+ summary: 'Retry failed notification record',
230
+ method: 'POST',
231
+ path: '/records/:recordId/retry',
232
+ metadata: {
233
+ auth: true,
234
+ },
235
+ pathParams: z.object({
236
+ recordId: notificationRecordIdSchema,
237
+ }),
238
+ body: z.object({}),
239
+ responses: {
240
+ 200: INotificationRecordZod,
241
+ 400: BadRequestError,
242
+ 401: UnauthorizedError,
243
+ 404: NotFoundError,
244
+ 500: InternalError,
245
+ },
246
+ },
247
+ },
248
+ {
249
+ pathPrefix: 'notification-channels',
250
+ },
251
+ );
@@ -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