@dalmore/api-contracts 0.0.0-dev.d8ef117 → 0.0.0-dev.dc7fdf8

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 (196) hide show
  1. package/README.md +23 -19
  2. package/common/types/account-contact.types.ts +2 -1
  3. package/common/types/account-manager.types.ts +3 -7
  4. package/common/types/account-setting.types.ts +65 -0
  5. package/common/types/account.types.ts +1 -0
  6. package/common/types/auth.types.ts +7 -18
  7. package/common/types/bonus-tier.types.ts +9 -0
  8. package/common/types/common.types.ts +38 -6
  9. package/common/types/comply-advantage-api.types.ts +3 -3
  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/escrow-account.types.ts +3 -3
  14. package/common/types/individuals.types.ts +3 -2
  15. package/common/types/investor-account.types.ts +2 -1
  16. package/common/types/invite.types.ts +27 -1
  17. package/common/types/issuer-offering.types.ts +11 -17
  18. package/common/types/legal-entity.types.ts +3 -2
  19. package/common/types/mail-template.types.ts +34 -0
  20. package/common/types/note.types.ts +1 -1
  21. package/common/types/notification.types.ts +525 -29
  22. package/common/types/offering.types.ts +2 -9
  23. package/common/types/site-settings.types.ts +2 -1
  24. package/common/types/site.types.ts +2 -9
  25. package/common/types/{trade-line-item.type.ts → trade-line-item.types.ts} +2 -9
  26. package/common/types/trade.types.ts +50 -2
  27. package/common/types/trusted-contact.types.ts +7 -7
  28. package/common/types/user.types.ts +11 -32
  29. package/common/types/webhook.types.ts +142 -0
  30. package/contracts/clients/trade-line-items/index.ts +1 -1
  31. package/contracts/clients/trades/index.ts +1 -1
  32. package/index.ts +10 -0
  33. package/package.json +23 -32
  34. package/contracts/compliance/account-contacts/index.ts +0 -82
  35. package/contracts/compliance/account-managers/index.ts +0 -142
  36. package/contracts/compliance/accounts/index.ts +0 -187
  37. package/contracts/compliance/activities/index.ts +0 -55
  38. package/contracts/compliance/aic/index.ts +0 -60
  39. package/contracts/compliance/api-keys/index.ts +0 -91
  40. package/contracts/compliance/assets/index.ts +0 -122
  41. package/contracts/compliance/auth/index.ts +0 -134
  42. package/contracts/compliance/batch-jobs/index.ts +0 -62
  43. package/contracts/compliance/bonus-tiers/index.ts +0 -74
  44. package/contracts/compliance/checklist/index.ts +0 -87
  45. package/contracts/compliance/checklist-items/index.ts +0 -86
  46. package/contracts/compliance/covered-persons/index.ts +0 -97
  47. package/contracts/compliance/dashboard/index.ts +0 -111
  48. package/contracts/compliance/data-records/index.ts +0 -116
  49. package/contracts/compliance/data-rooms/index.ts +0 -113
  50. package/contracts/compliance/default-theme-configs/index.ts +0 -95
  51. package/contracts/compliance/disbursement/index.ts +0 -165
  52. package/contracts/compliance/disbursement-approval-users/index.ts +0 -84
  53. package/contracts/compliance/disbursement-transactions/index.ts +0 -37
  54. package/contracts/compliance/domain-filters/index.ts +0 -117
  55. package/contracts/compliance/email-themes/index.ts +0 -284
  56. package/contracts/compliance/escrow-accounts/index.ts +0 -85
  57. package/contracts/compliance/exchange-api-keys/index.ts +0 -129
  58. package/contracts/compliance/exchange-imports/index.ts +0 -137
  59. package/contracts/compliance/files/index.ts +0 -267
  60. package/contracts/compliance/files-public/index.ts +0 -188
  61. package/contracts/compliance/health/index.ts +0 -26
  62. package/contracts/compliance/index.ts +0 -147
  63. package/contracts/compliance/individuals/index.ts +0 -57
  64. package/contracts/compliance/investor-accounts/index.ts +0 -141
  65. package/contracts/compliance/invites/index.ts +0 -137
  66. package/contracts/compliance/issuer-bank-accounts/index.ts +0 -81
  67. package/contracts/compliance/issuer-payment-methods/index.ts +0 -81
  68. package/contracts/compliance/issuers/index.ts +0 -97
  69. package/contracts/compliance/job-items/index.ts +0 -58
  70. package/contracts/compliance/jobs/index.ts +0 -59
  71. package/contracts/compliance/kyb/index.ts +0 -54
  72. package/contracts/compliance/kyc/index.ts +0 -77
  73. package/contracts/compliance/legal-entities/index.ts +0 -57
  74. package/contracts/compliance/login-histories/index.ts +0 -37
  75. package/contracts/compliance/notes/index.ts +0 -69
  76. package/contracts/compliance/notion-databases/index.ts +0 -107
  77. package/contracts/compliance/notion-pages/index.ts +0 -105
  78. package/contracts/compliance/offering-reports/index.ts +0 -149
  79. package/contracts/compliance/offerings/index.ts +0 -233
  80. package/contracts/compliance/pages/index.ts +0 -178
  81. package/contracts/compliance/payment-methods/index.ts +0 -57
  82. package/contracts/compliance/rejection-reasons/index.ts +0 -32
  83. package/contracts/compliance/review/index.ts +0 -169
  84. package/contracts/compliance/roles/index.ts +0 -34
  85. package/contracts/compliance/secondary-customers/index.ts +0 -77
  86. package/contracts/compliance/secondary-orders/index.ts +0 -60
  87. package/contracts/compliance/secondary-trades/index.ts +0 -100
  88. package/contracts/compliance/secure-requests/index.ts +0 -54
  89. package/contracts/compliance/signer/index.ts +0 -369
  90. package/contracts/compliance/site-links/index.ts +0 -128
  91. package/contracts/compliance/site-settings/index.ts +0 -669
  92. package/contracts/compliance/sites/index.ts +0 -56
  93. package/contracts/compliance/state-machine/index.ts +0 -94
  94. package/contracts/compliance/tasks/index.ts +0 -91
  95. package/contracts/compliance/third-parties/index.ts +0 -52
  96. package/contracts/compliance/trade-line-items/index.ts +0 -59
  97. package/contracts/compliance/trades/index.ts +0 -230
  98. package/contracts/compliance/transactions/index.ts +0 -161
  99. package/contracts/compliance/user-manuals/index.ts +0 -271
  100. package/contracts/compliance/user-settings/index.ts +0 -189
  101. package/contracts/compliance/users/index.ts +0 -221
  102. package/contracts/compliance/webhooks/index.ts +0 -41
  103. package/contracts/compliance-apikey/accounts/index.ts +0 -58
  104. package/contracts/compliance-apikey/index.ts +0 -14
  105. package/contracts/index.ts +0 -6
  106. package/contracts/investors/account-contacts/index.ts +0 -58
  107. package/contracts/investors/aic/index.ts +0 -59
  108. package/contracts/investors/assets/index.ts +0 -61
  109. package/contracts/investors/auth/index.ts +0 -116
  110. package/contracts/investors/bonus-tiers/index.ts +0 -55
  111. package/contracts/investors/cart/index.ts +0 -75
  112. package/contracts/investors/contact-us/index.ts +0 -48
  113. package/contracts/investors/data-records/index.ts +0 -113
  114. package/contracts/investors/data-rooms/index.ts +0 -96
  115. package/contracts/investors/files/index.ts +0 -167
  116. package/contracts/investors/files-public/index.ts +0 -185
  117. package/contracts/investors/index.ts +0 -72
  118. package/contracts/investors/individuals/index.ts +0 -121
  119. package/contracts/investors/investor-accounts/index.ts +0 -110
  120. package/contracts/investors/issuer-payment-methods/index.ts +0 -36
  121. package/contracts/investors/issuers/index.ts +0 -30
  122. package/contracts/investors/legal-entities/index.ts +0 -93
  123. package/contracts/investors/notes/index.ts +0 -69
  124. package/contracts/investors/offerings/index.ts +0 -93
  125. package/contracts/investors/pages/index.ts +0 -88
  126. package/contracts/investors/payment-methods/index.ts +0 -149
  127. package/contracts/investors/portfolios/index.ts +0 -53
  128. package/contracts/investors/sites/index.ts +0 -96
  129. package/contracts/investors/tasks/index.ts +0 -111
  130. package/contracts/investors/trade-line-items/index.ts +0 -75
  131. package/contracts/investors/trades/index.ts +0 -114
  132. package/contracts/investors/transactions/index.ts +0 -37
  133. package/contracts/investors/trusted-contacts/index.ts +0 -93
  134. package/contracts/investors/user-manuals/index.ts +0 -62
  135. package/contracts/investors/user-settings/index.ts +0 -170
  136. package/contracts/investors/users/index.ts +0 -45
  137. package/contracts/investors/webhooks/index.ts +0 -30
  138. package/contracts/issuers/account-contacts/index.ts +0 -76
  139. package/contracts/issuers/account-integrations/index.ts +0 -97
  140. package/contracts/issuers/accounts/index.ts +0 -97
  141. package/contracts/issuers/activities/index.ts +0 -54
  142. package/contracts/issuers/aic/index.ts +0 -39
  143. package/contracts/issuers/api-key-logs/index.ts +0 -53
  144. package/contracts/issuers/api-keys/index.ts +0 -93
  145. package/contracts/issuers/assets/index.ts +0 -122
  146. package/contracts/issuers/auth/index.ts +0 -152
  147. package/contracts/issuers/bonus-tiers/index.ts +0 -73
  148. package/contracts/issuers/contact-us/index.ts +0 -48
  149. package/contracts/issuers/covered-persons/index.ts +0 -136
  150. package/contracts/issuers/dashboard/index.ts +0 -72
  151. package/contracts/issuers/data-records/index.ts +0 -257
  152. package/contracts/issuers/data-rooms/index.ts +0 -134
  153. package/contracts/issuers/disbursement-approval-users/index.ts +0 -82
  154. package/contracts/issuers/disbursement-transactions/index.ts +0 -53
  155. package/contracts/issuers/disbursements/index.ts +0 -189
  156. package/contracts/issuers/email-themes/index.ts +0 -242
  157. package/contracts/issuers/escrow-accounts/index.ts +0 -81
  158. package/contracts/issuers/exchange-api-keys/index.ts +0 -144
  159. package/contracts/issuers/files/index.ts +0 -166
  160. package/contracts/issuers/files-public/index.ts +0 -166
  161. package/contracts/issuers/health/index.ts +0 -24
  162. package/contracts/issuers/index.ts +0 -112
  163. package/contracts/issuers/investor-accounts/index.ts +0 -148
  164. package/contracts/issuers/invites/index.ts +0 -129
  165. package/contracts/issuers/issuer/index.ts +0 -94
  166. package/contracts/issuers/issuer-bank-accounts/index.ts +0 -81
  167. package/contracts/issuers/issuer-payment-methods/index.ts +0 -136
  168. package/contracts/issuers/kyc/index.ts +0 -38
  169. package/contracts/issuers/login-histories/index.ts +0 -51
  170. package/contracts/issuers/notes/index.ts +0 -69
  171. package/contracts/issuers/offerings/index.ts +0 -206
  172. package/contracts/issuers/pages/index.ts +0 -138
  173. package/contracts/issuers/payment-methods/index.ts +0 -61
  174. package/contracts/issuers/portfolios/index.ts +0 -36
  175. package/contracts/issuers/rejection-reasons/index.ts +0 -32
  176. package/contracts/issuers/review/index.ts +0 -63
  177. package/contracts/issuers/secondary-customers/index.ts +0 -55
  178. package/contracts/issuers/secondary-orders/index.ts +0 -57
  179. package/contracts/issuers/secondary-trades/index.ts +0 -57
  180. package/contracts/issuers/secure-requests/index.ts +0 -34
  181. package/contracts/issuers/site-links/index.ts +0 -116
  182. package/contracts/issuers/site-settings/index.ts +0 -585
  183. package/contracts/issuers/sites/index.ts +0 -32
  184. package/contracts/issuers/tasks/index.ts +0 -111
  185. package/contracts/issuers/trades/index.ts +0 -132
  186. package/contracts/issuers/transactions/index.ts +0 -158
  187. package/contracts/issuers/user-manuals/index.ts +0 -62
  188. package/contracts/issuers/user-settings/index.ts +0 -170
  189. package/contracts/issuers/users/index.ts +0 -126
  190. package/contracts/secondaries/accounts/index.ts +0 -58
  191. package/contracts/secondaries/index.ts +0 -23
  192. package/contracts/secondaries/secondary-customers/index.ts +0 -55
  193. package/contracts/secondaries/secondary-issuers/index.ts +0 -94
  194. package/contracts/secondaries/secondary-orders/index.ts +0 -56
  195. package/contracts/secondaries/secondary-securities/index.ts +0 -95
  196. package/contracts/secondaries/secondary-trades/index.ts +0 -56
package/README.md CHANGED
@@ -14,32 +14,33 @@ npm install @dalmore/api-contracts@dev
14
14
 
15
15
  ## Usage
16
16
 
17
- ### Import specific contracts (recommended for tree-shaking)
17
+ ### Import from main entry
18
18
 
19
19
  ```typescript
20
- import { complianceContract } from '@dalmore/api-contracts/compliance';
21
- import { investorsContract } from '@dalmore/api-contracts/investors';
22
- import { issuersContract } from '@dalmore/api-contracts/issuers';
23
- import { clientsContract } from '@dalmore/api-contracts/clients';
20
+ import { clientsContract } from '@dalmore/api-contracts';
21
+ import type { IInvestorAccount } from '@dalmore/api-contracts';
24
22
  ```
25
23
 
26
- ### Import types
24
+ ### Import specific subpaths (recommended for tree-shaking)
27
25
 
28
26
  ```typescript
29
- import type { IInvestorAccount } from '@dalmore/api-contracts/types/investor-account.types';
30
- import type { ITrade } from '@dalmore/api-contracts/types/trade.types';
27
+ // Import clients contract
28
+ import { clientsContract } from '@dalmore/api-contracts/clients';
29
+
30
+ // Import types
31
+ import type { IInvestorAccount, ITrade } from '@dalmore/api-contracts/types';
31
32
  ```
32
33
 
33
34
  ### Create a typed client
34
35
 
35
36
  ```typescript
36
- import { complianceContract } from '@dalmore/api-contracts/compliance';
37
+ import { clientsContract } from '@dalmore/api-contracts/clients';
37
38
  import { initClient } from '@ts-rest/core';
38
39
 
39
- const client = initClient(complianceContract, {
40
+ const client = initClient(clientsContract, {
40
41
  baseUrl: 'https://platform.dalmoregroup.com',
41
42
  baseHeaders: {
42
- Authorization: `Bearer ${token}`,
43
+ 'X-API-Key': `${apiKey}`,
43
44
  },
44
45
  });
45
46
 
@@ -53,17 +54,20 @@ const { status, body } = await client.accounts.getAccounts({
53
54
 
54
55
  This package requires the following peer dependencies:
55
56
 
56
- - `@ts-rest/core` ^3.0.0
57
- - `zod` ^3.0.0
57
+ - `@anatine/zod-openapi` ^1.14.2
58
+ - `@ts-rest/core` ^3.52.1
59
+ - `typeid-js` ^1.2.0
60
+ - `zod` ^3.24.4
58
61
 
59
- ## Available Contracts
62
+ ## Available Exports
60
63
 
61
- - `complianceContract` - Compliance portal API
62
- - `investorsContract` - Investor portal API
63
- - `issuersContract` - Issuer portal API
64
64
  - `clientsContract` - Client API (API key auth)
65
- - `secondariesContract` - Secondaries API
66
- - `complianceApiKeyContract` - Compliance API (API key auth)
65
+
66
+ ## Available Subpath Exports
67
+
68
+ - `@dalmore/api-contracts` - Main entry (clients contract and types)
69
+ - `@dalmore/api-contracts/clients` - Clients contract
70
+ - `@dalmore/api-contracts/types` - All common types
67
71
 
68
72
  ## TypeScript Configuration
69
73
 
@@ -6,6 +6,7 @@ import { PhoneZodSchema } from './phone.type';
6
6
  import {
7
7
  AccountContactType,
8
8
  AccountZod,
9
+ EmailSchema,
9
10
  IPaginationMeta,
10
11
  } from './common.types';
11
12
  import { IBaseEntity } from './entity.types';
@@ -60,7 +61,7 @@ export const PatchAccountContactZod = z.object({
60
61
  .openapi({ example: 'Mr' }),
61
62
  firstName: z.string().min(1).max(150).openapi({ example: 'John' }),
62
63
  lastName: z.string().min(1).max(150).openapi({ example: 'Doe' }),
63
- email: z.string().email().openapi({ example: 'john.doe@example.com' }),
64
+ email: EmailSchema.openapi({ example: 'john.doe@example.com' }),
64
65
  phone: PhoneZodSchema.nullable()
65
66
  .optional()
66
67
  .openapi({ example: '+12124567890' }),
@@ -4,7 +4,7 @@ import { TypeID } from 'typeid-js';
4
4
  import { IBaseEntity } from './entity.types';
5
5
  import { PhoneNumberData } from './sms.types';
6
6
  import { userIdSchema, UserZod } from './user.types';
7
- import { IPaginationMeta } from './common.types';
7
+ import { EmailSchema, IPaginationMeta } from './common.types';
8
8
  import { PhoneZodSchema } from './phone.type';
9
9
 
10
10
  extendZodWithOpenApi(z);
@@ -68,7 +68,7 @@ export type IAccountManagerZod = z.infer<typeof IAccountManagerZod>;
68
68
  export const PostAccountManagerZod = z.object({
69
69
  firstName: z.string().min(1).max(255).openapi({ example: 'John' }),
70
70
  lastName: z.string().min(1).max(255).openapi({ example: 'Doe' }),
71
- email: z.string().email().openapi({ example: 'john.doe@example.com' }),
71
+ email: EmailSchema,
72
72
  phone: PhoneZodSchema.nullable()
73
73
  .optional()
74
74
  .openapi({ example: '+12124567890' }),
@@ -80,11 +80,7 @@ export type PostAccountManagerZod = z.infer<typeof PostAccountManagerZod>;
80
80
  export const PatchAccountManagerZod = z.object({
81
81
  firstName: z.string().min(1).max(255).optional().openapi({ example: 'John' }),
82
82
  lastName: z.string().min(1).max(255).optional().openapi({ example: 'Doe' }),
83
- email: z
84
- .string()
85
- .email()
86
- .optional()
87
- .openapi({ example: 'john.doe@example.com' }),
83
+ email: EmailSchema.optional(),
88
84
  phone: PhoneZodSchema.nullable()
89
85
  .optional()
90
86
  .openapi({ example: '+12124567890' }),
@@ -0,0 +1,65 @@
1
+ import { extendZodWithOpenApi } from '@anatine/zod-openapi';
2
+ import { z } from 'zod';
3
+ import { TypeID } from 'typeid-js';
4
+ import { IBaseEntity } from './entity.types';
5
+ import { IPaginationMeta } from './common.types';
6
+ import { accountIdSchema } from './account.types';
7
+
8
+ extendZodWithOpenApi(z);
9
+
10
+ export const accountSettingIdSchema = z.string().refine(
11
+ (value) => {
12
+ try {
13
+ const tid = TypeID.fromString(value);
14
+ return tid.getType() === 'account_setting';
15
+ } catch {
16
+ return false;
17
+ }
18
+ },
19
+ {
20
+ message:
21
+ 'Invalid account setting ID format. Must be a valid TypeID with "account_setting" prefix.',
22
+ },
23
+ );
24
+
25
+ export const IAccountSettingZod = IBaseEntity.extend({
26
+ id: accountSettingIdSchema.openapi({
27
+ example: 'account_setting_01j5y5ghx8fvc83dmx3pznq7hv',
28
+ }),
29
+ accountId: z.string().openapi({
30
+ example: 'account_01j5y5ghx8fvc83dmx3pznq7hv',
31
+ }),
32
+ });
33
+ export type IAccountSettingZod = z.infer<typeof IAccountSettingZod>;
34
+
35
+ export const IPaginatedAccountSetting = z.object({
36
+ items: z.array(IAccountSettingZod),
37
+ meta: IPaginationMeta,
38
+ });
39
+ export type IPaginatedAccountSetting = z.infer<typeof IPaginatedAccountSetting>;
40
+
41
+ export const AccountSettingsFilters = z.object({
42
+ accountId: accountIdSchema.optional(),
43
+ });
44
+ export type AccountSettingsFilters = z.infer<typeof AccountSettingsFilters>;
45
+
46
+ export const accountSettingsInclude = z.enum(['notificationChannels']);
47
+
48
+ export const AccountSettingsIncludeQuery = z.object({
49
+ include: z
50
+ .string()
51
+ .optional()
52
+ .transform((str) => (str ? str.split(',') : []))
53
+ .refine(
54
+ (includes) =>
55
+ includes.every((include) =>
56
+ accountSettingsInclude.options.includes(include as any),
57
+ ),
58
+ {
59
+ message: `Invalid include value. Valid values are: ${accountSettingsInclude.options.join(', ')}`,
60
+ },
61
+ ),
62
+ });
63
+ export type AccountSettingsIncludeQuery = z.infer<
64
+ typeof AccountSettingsIncludeQuery
65
+ >;
@@ -91,6 +91,7 @@ export const AccountFiltersZod = z.object({
91
91
  const accountsInclude = z.enum([
92
92
  'accountManager',
93
93
  'accountIntegrations',
94
+ 'accountSettings',
94
95
  'apiKeys',
95
96
  'assets',
96
97
  'dataRooms',
@@ -8,6 +8,7 @@ import {
8
8
  ManagedByType,
9
9
  UserRole,
10
10
  createUrlSchema,
11
+ EmailSchema,
11
12
  } from './common.types';
12
13
  import { TypeID } from 'typeid-js';
13
14
  import { TwoFactorMethod } from './sms.types';
@@ -60,13 +61,7 @@ const BaseAuthBody = z.object({
60
61
  .openapi({
61
62
  example: 'Armstrong',
62
63
  }),
63
- email: z
64
- .string()
65
- .email()
66
- .transform((val) => val.toLowerCase())
67
- .openapi({
68
- example: 'neil@dalmoregroup.com',
69
- }),
64
+ email: EmailSchema,
70
65
  password: PasswordSchema,
71
66
  });
72
67
 
@@ -99,13 +94,7 @@ export const IChangePasswordBodyZod = z
99
94
  });
100
95
 
101
96
  export const LoginBody = z.object({
102
- email: z
103
- .string()
104
- .email()
105
- .transform((val) => val.toLowerCase())
106
- .openapi({
107
- example: 'neil@dalmoregroup.com',
108
- }),
97
+ email: EmailSchema,
109
98
  password: z.string().openapi({
110
99
  example: 'Secretpassword6#',
111
100
  }),
@@ -297,7 +286,7 @@ export const RegisterBodyInvestors = BaseAuthBody.extend({
297
286
  });
298
287
 
299
288
  export const ResetPasswordVerifyBody = z.object({
300
- email: z.string().email(),
289
+ email: EmailSchema,
301
290
  code: z.string().length(6, 'code is not 6 characters').openapi({
302
291
  example: '123456',
303
292
  }),
@@ -315,7 +304,7 @@ export type ResetPasswordVerifyResponseType = z.infer<
315
304
  >;
316
305
 
317
306
  export const ResetPasswordBody = z.object({
318
- email: z.string().email(),
307
+ email: EmailSchema,
319
308
  code: z.string().length(6, 'code is not 6 characters').openapi({
320
309
  example: '123456',
321
310
  }),
@@ -337,7 +326,7 @@ export type ClientAuthSuccessResponse = z.infer<
337
326
  >;
338
327
 
339
328
  export const AdminForgotPasswordRequestZod = z.object({
340
- email: z.string().email(),
329
+ email: EmailSchema,
341
330
  portal: z.nativeEnum(PortalType),
342
331
  });
343
332
  export type AdminForgotPasswordRequestZod = z.infer<
@@ -345,7 +334,7 @@ export type AdminForgotPasswordRequestZod = z.infer<
345
334
  >;
346
335
 
347
336
  export const InvestorForgotPasswordRequestZod = z.object({
348
- email: z.string().email(),
337
+ email: EmailSchema,
349
338
  url: createUrlSchema({ strict: true }),
350
339
  });
351
340
  export type InvestorForgotPasswordRequestZod = z.infer<
@@ -98,6 +98,15 @@ export type EstimateBonusTierCalculationZod = z.infer<
98
98
  typeof EstimateBonusTierCalculationZod
99
99
  >;
100
100
 
101
+ export const ComplianceEstimateBonusTierCalculationZod =
102
+ EstimateBonusTierCalculationZod.and(
103
+ z.object({
104
+ accountId: accountIdSchema,
105
+ }),
106
+ );
107
+ export type ComplianceEstimateBonusTierCalculationZod = z.infer<
108
+ typeof ComplianceEstimateBonusTierCalculationZod
109
+ >;
101
110
  export const EstimateBonusTierCalculationResponseZod = z.object({
102
111
  bonusTierId: bonusTierIdSchema
103
112
  .nullable()
@@ -69,6 +69,10 @@ export enum BaseStatus {
69
69
  VOIDED = 'VOIDED',
70
70
  JOIN = 'JOIN',
71
71
  RESTORE = 'RESTORE',
72
+ ACTIVE = 'ACTIVE',
73
+ LOCKED = 'LOCKED',
74
+ ENABLED = 'ENABLED',
75
+ DISABLED = 'DISABLED',
72
76
  }
73
77
 
74
78
  export const UserWithoutPasswordAccountZod = IBaseEntity.extend({
@@ -111,6 +115,10 @@ export enum HttpMethod {
111
115
  OPTIONS = 'OPTIONS',
112
116
  }
113
117
 
118
+ export enum UserStatus {
119
+ ACTIVE = 'ACTIVE',
120
+ LOCKED = 'LOCKED',
121
+ }
114
122
  export const SENSITIVE_PATTERNS = [
115
123
  /password/i,
116
124
  /credit.*card/i,
@@ -200,11 +208,6 @@ export enum UserType {
200
208
  DEMO = 'DEMO',
201
209
  }
202
210
 
203
- export enum UserStatus {
204
- ACTIVE = 'ACTIVE',
205
- LOCKED = 'LOCKED',
206
- }
207
-
208
211
  export enum UserRole {
209
212
  API_KEY = 'API_KEY',
210
213
  IMPORT = 'IMPORT',
@@ -306,7 +309,7 @@ export const AuthUserReq = BaseAuthReq.extend({
306
309
  lastName: z.string(),
307
310
  email: z.string().email(),
308
311
  provider: z.string(),
309
- status: z.lazy(() => z.nativeEnum(UserStatus)),
312
+ locked: z.boolean(),
310
313
  lastLoginAt: z.date().nullable(),
311
314
  loginCount: z.number(),
312
315
  requiresTwoFactorSetup: z.boolean().optional(),
@@ -809,6 +812,8 @@ export enum EventField {
809
812
  SA_STATUS = 'saStatus',
810
813
  ONBOARDING_STATUS = 'onboardingStatus',
811
814
  TRANSACTION_STATUS = 'transactionStatus',
815
+ ACTIVE = 'active',
816
+ LOCKED = 'locked',
812
817
  }
813
818
 
814
819
  export enum EventName {
@@ -1518,3 +1523,30 @@ export const SUBJECT_TYPE_MAP: Record<BulkExportType, string> = {
1518
1523
  [BulkExportType.SECONDARY_CUSTOMERS]: 'Secondary Customers',
1519
1524
  [BulkExportType.SECONDARY_TRADES]: 'Secondary Trades',
1520
1525
  };
1526
+
1527
+ export const StringToBooleanSchema = z.preprocess(
1528
+ (val) =>
1529
+ val === 'true' || val === '1'
1530
+ ? true
1531
+ : val === 'false' || val === '0'
1532
+ ? false
1533
+ : val,
1534
+ z.boolean(),
1535
+ );
1536
+ export type StringToBooleanSchema = z.infer<typeof StringToBooleanSchema>;
1537
+
1538
+ /**
1539
+ * Reusable email schema that validates email format, transforms to lowercase,
1540
+ * and includes OpenAPI metadata.
1541
+ *
1542
+ * @example
1543
+ * EmailSchema.parse('John.Doe@EXAMPLE.COM'); // returns 'john.doe@example.com'
1544
+ * EmailSchema.optional().parse(undefined); // returns undefined
1545
+ */
1546
+ export const EmailSchema = z
1547
+ .string()
1548
+ .email()
1549
+ .transform((val) => val.toLowerCase())
1550
+ .openapi({
1551
+ example: 'neil@dalmoregroup.com',
1552
+ });
@@ -30,7 +30,7 @@ export const CreateSearchRequestSchema = z.object({
30
30
  .optional(),
31
31
  })
32
32
  .optional(),
33
- tags: z.record(z.string()).optional(),
33
+ tags: z.union([z.record(z.string()), z.array(z.any())]).optional(),
34
34
  share_url: z.union([z.literal(0), z.literal(1)]).optional(),
35
35
  exact_match: z.boolean().optional(),
36
36
  });
@@ -268,7 +268,7 @@ export const GetSearchDetailsResponseSchema = z.object({
268
268
  total_matches: z.number(),
269
269
  updated_at: z.string(),
270
270
  created_at: z.string(),
271
- tags: z.record(z.string()).optional(),
271
+ tags: z.union([z.record(z.string()), z.array(z.any())]).optional(),
272
272
  labels: z
273
273
  .array(
274
274
  z.object({
@@ -310,7 +310,7 @@ export const UpdateSearchRequestSchema = z.object({
310
310
  risk_level: z.enum(['low', 'medium', 'high', 'unknown']).optional(),
311
311
  assignee_id: z.number().optional(),
312
312
  limit: z.number().int().max(100).optional(),
313
- tags: z.record(z.string()).optional(),
313
+ tags: z.union([z.record(z.string()), z.array(z.any())]).optional(),
314
314
  });
315
315
 
316
316
  export type UpdateSearchRequest = z.infer<typeof UpdateSearchRequestSchema>;
@@ -1,7 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  import { extendZodWithOpenApi } from '@anatine/zod-openapi';
3
3
  import { TypeID } from 'typeid-js';
4
- import { BaseContactUsOptions, createUrlSchema } from './common.types';
4
+ import {
5
+ BaseContactUsOptions,
6
+ createUrlSchema,
7
+ EmailSchema,
8
+ } from './common.types';
5
9
  extendZodWithOpenApi(z);
6
10
 
7
11
  export const contactUsIdSchema = z.string().refine(
@@ -55,7 +59,7 @@ export const InvestorPostContactUsZod = PostContactUsZod.extend({
55
59
  export type InvestorPostContactUsZod = z.infer<typeof InvestorPostContactUsZod>;
56
60
 
57
61
  export const PublicInvestorContactUsZod = PostContactUsZod.extend({
58
- email: z.string().email().openapi({ example: 'email@example.com' }),
62
+ email: EmailSchema,
59
63
  firstName: z.string().min(1).max(100).openapi({ example: 'John' }),
60
64
  lastName: z.string().min(1).max(100).openapi({ example: 'Doe' }),
61
65
  contactOption: z.nativeEnum(InvestorContactOptions).openapi({
@@ -6,6 +6,7 @@ import {
6
6
  ComplianceReview,
7
7
  CoveredPersonsRoleType,
8
8
  CoveredPersonsStatus,
9
+ EmailSchema,
9
10
  IDType,
10
11
  IPaginationMeta,
11
12
  } from './common.types';
@@ -137,7 +138,7 @@ export const PatchCoveredPersonsZod = z
137
138
  .openapi({ example: CoveredPersonsRoleType.ACCOUNTING }),
138
139
 
139
140
  ownership: z.number().min(0).max(100).openapi({ example: 15 }).optional(),
140
- email: z.string().nullable().optional(),
141
+ email: EmailSchema.nullable().optional(),
141
142
  idType: z
142
143
  .nativeEnum(IDType)
143
144
  .optional()
@@ -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
@@ -1,6 +1,6 @@
1
1
  import { extendZodWithOpenApi } from '@anatine/zod-openapi';
2
2
  import { z } from 'zod';
3
- import { AccountZod, IPaginationMeta } from './common.types';
3
+ import { AccountZod, EmailSchema, IPaginationMeta } from './common.types';
4
4
  import { IBaseEntity } from './entity.types';
5
5
  import { TypeID } from 'typeid-js';
6
6
  import { accountIdSchema } from './account.types';
@@ -43,7 +43,7 @@ export const PostEscrowAccount = z.object({
43
43
  accountNumber: z.string().optional().nullable(),
44
44
  routingNumber: z.string().min(9).max(9).optional().nullable(),
45
45
  agentName: z.string().min(2).max(50),
46
- agentEmail: z.string().email(),
46
+ agentEmail: EmailSchema,
47
47
  });
48
48
 
49
49
  export type PostEscrowAccount = z.infer<typeof PostEscrowAccount>;
@@ -65,7 +65,7 @@ export const PatchEscrowAccount = z.object({
65
65
  accountNumber: z.string().min(10).max(18).optional().nullable().optional(),
66
66
  routingNumber: z.string().min(9).max(9).optional().nullable().optional(),
67
67
  agentName: z.string().min(2).max(50).optional(),
68
- agentEmail: z.string().email().optional(),
68
+ agentEmail: EmailSchema.optional(),
69
69
  });
70
70
 
71
71
  export type PatchEscrowAccount = z.infer<typeof PatchEscrowAccount>;
@@ -16,6 +16,7 @@ import {
16
16
  EmploymentStatus,
17
17
  SourceOfIncome,
18
18
  AMLProvider,
19
+ EmailSchema,
19
20
  } from './common.types';
20
21
  import { IBaseEntity } from './entity.types';
21
22
  import { IInvestorAccount } from './investor-account.types';
@@ -288,7 +289,7 @@ export const PostIndividualBodySchema = z
288
289
  .string()
289
290
  .length(3, 'currencyCode must be 3 digits')
290
291
  .optional(),
291
- email: z.string().email().optional(),
292
+ email: EmailSchema.optional(),
292
293
  role: z.nativeEnum(IndividualRole),
293
294
  phone: PhoneZodSchema.openapi({ example: '+12124567890' }).optional(),
294
295
  ownership: z.coerce
@@ -387,7 +388,7 @@ export const UpdateIndividualBodySchema = z
387
388
  .length(3, 'currencyCode must be 3 digits')
388
389
  .optional(),
389
390
  phone: PhoneZodSchema.openapi({ example: '+12124567890' }).optional(),
390
- email: z.string().email().optional(),
391
+ email: EmailSchema.optional(),
391
392
  ownership: z.coerce
392
393
  .number()
393
394
  .min(0, 'Ownership is less than 0')
@@ -24,6 +24,7 @@ import {
24
24
  SortBy,
25
25
  SortOrder,
26
26
  AMLProvider,
27
+ EmailSchema,
27
28
  } from './common.types';
28
29
  import { accountIdSchema } from './account.types';
29
30
  import { SaStatus, tradeIdSchema, TradeZod } from './trade.types';
@@ -131,7 +132,7 @@ export type PostClientInvestorAccountBody = z.infer<
131
132
 
132
133
  export const UpdateInvestorAccountBodySchema = z.object({
133
134
  name: z.string().optional(),
134
- email: z.string().email().optional(),
135
+ email: EmailSchema.optional(),
135
136
  });
136
137
  export type UpdateInvestorAccountBody = z.infer<
137
138
  typeof UpdateInvestorAccountBodySchema
@@ -3,7 +3,9 @@ import {
3
3
  AccountZod,
4
4
  IPaginationMeta,
5
5
  IssuerRole,
6
+ PortalType,
6
7
  UserRole,
8
+ EmailSchema,
7
9
  } from './common.types';
8
10
  import { extendZodWithOpenApi } from '@anatine/zod-openapi';
9
11
  import { TypeID } from 'typeid-js';
@@ -48,7 +50,7 @@ export const InviteWithUrl = InviteWithoutSecretZod.extend({
48
50
  export type InviteWithUrl = z.infer<typeof InviteWithUrl>;
49
51
 
50
52
  export const PostIssuerInviteZod = z.object({
51
- email: z.string().email(),
53
+ email: EmailSchema,
52
54
  role: z.nativeEnum(IssuerRole),
53
55
  });
54
56
 
@@ -131,3 +133,27 @@ export const PatchInviteForComplianceZod = PatchInviteRoleZod.extend({
131
133
  export type PatchInviteForComplianceZod = z.infer<
132
134
  typeof PatchInviteForComplianceZod
133
135
  >;
136
+
137
+ export const PostInviteZod = z.object({
138
+ email: EmailSchema,
139
+ role: z.nativeEnum(UserRole).openapi({
140
+ example: UserRole.ADMIN,
141
+ }),
142
+ accountId: z.string().optional().openapi({
143
+ example: 'account_01j5y5ghx5fg68d663j1fvy2x7',
144
+ }),
145
+ portalType: z.nativeEnum(PortalType).optional().openapi({
146
+ example: PortalType.ISSUER,
147
+ }),
148
+ });
149
+
150
+ export type PostInviteZod = z.infer<typeof PostInviteZod>;
151
+
152
+ export const CompliancePostInviteZod = z.object({
153
+ email: EmailSchema,
154
+ role: z.nativeEnum(UserRole).openapi({
155
+ example: UserRole.ADMIN,
156
+ }),
157
+ });
158
+
159
+ export type CompliancePostInviteZod = z.infer<typeof CompliancePostInviteZod>;
@@ -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';
@@ -193,38 +194,39 @@ export const PatchIssuerOffering = z.object({
193
194
  .max(100)
194
195
  .optional()
195
196
  .openapi({ example: 'Airbnb IPO' }),
197
+ type: z
198
+ .nativeEnum(OfferingType)
199
+ .optional()
200
+ .openapi({ example: OfferingType.REG_D }),
196
201
  targetAmount: z
197
202
  .number()
198
203
  .min(0)
199
204
  .max(10000000000)
200
205
  .optional()
201
206
  .openapi({ example: 120000 }),
202
- raiseAmount: z
203
- .number()
204
- .min(0)
205
- .max(10000000000)
206
- .optional()
207
- .openapi({ example: 200000 }),
208
207
  minInvestment: z
209
208
  .number()
210
209
  .min(0)
211
210
  .max(10000000000)
211
+ .nullable()
212
212
  .optional()
213
213
  .openapi({ example: 1000 }),
214
214
  maxInvestment: z
215
215
  .number()
216
216
  .min(0)
217
217
  .max(10000000000)
218
+ .nullable()
218
219
  .optional()
219
220
  .openapi({ example: 20000 }),
220
221
  contingencyAmount: z
221
222
  .number()
222
223
  .min(0)
223
224
  .max(10000000000)
225
+ .nullable()
224
226
  .optional()
225
227
  .openapi({ example: 5000 }),
226
- startAt: dateSchema.optional().openapi({ example: '10/20/2024' }),
227
- endAt: dateSchema.optional().openapi({ example: '10/27/2024' }),
228
+ startAt: dateSchema.nullable().optional().openapi({ example: '10/20/2024' }),
229
+ endAt: dateSchema.nullable().optional().openapi({ example: '10/27/2024' }),
228
230
  cancellationPeriod: z
229
231
  .number()
230
232
  .min(1)
@@ -370,15 +372,7 @@ export const IssuerOfferingsFilterZod = z.object({
370
372
  issuerId: z.lazy(() => issuerIdSchema).optional(),
371
373
  type: z.nativeEnum(OfferingType).optional(),
372
374
  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
- ),
375
+ enabled: StringToBooleanSchema.optional(),
382
376
  managedBy: z.nativeEnum(ManagedByType).optional(),
383
377
  versioningType: z.nativeEnum(OfferingVersioningType).optional(),
384
378
  combinedStatus: z.nativeEnum(OfferingStatus).optional(),
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { IBaseEntity } from './entity.types';
3
3
  import {
4
4
  dateSchema,
5
+ EmailSchema,
5
6
  IPaginationMeta,
6
7
  KYBStatus,
7
8
  SanctionsStatus,
@@ -138,7 +139,7 @@ export const PostLegalEntitySchema = z
138
139
  investorAccountId: investorAccountIdSchema,
139
140
  name: CompanyNameSchema,
140
141
  ein: EINSchema,
141
- email: z.string().email().optional(),
142
+ email: EmailSchema.optional(),
142
143
  companyType: CompanyTypeSchema.optional(),
143
144
  phone: PhoneZodSchema.openapi({ example: '+12124567890' }).optional(),
144
145
  dateOfIncorporation: z.lazy(() => dateSchema).optional(),
@@ -153,7 +154,7 @@ export const UpdateLegalEntitySchema = z
153
154
  id: legalEntityIdSchema.optional(),
154
155
  name: CompanyNameSchema.optional(),
155
156
  ein: EINSchema,
156
- email: z.string().email().optional(),
157
+ email: EmailSchema.optional(),
157
158
  companyType: CompanyTypeSchema.optional(),
158
159
  phone: PhoneZodSchema.openapi({ example: '+12124567890' }).optional(),
159
160
  dateOfIncorporation: z.lazy(() => dateSchema).optional(),