@dalmore/api-contracts 0.0.0-dev.d07da18 → 0.0.0-dev.d6badc9
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.
- package/common/types/account-setting.types.ts +65 -0
- package/common/types/account.types.ts +1 -0
- package/common/types/activity.types.ts +1 -1
- package/common/types/bonus-tier.types.ts +33 -0
- package/common/types/cart.types.ts +4 -1
- package/common/types/common.types.ts +16 -6
- package/common/types/dashboard.types.ts +2 -9
- package/common/types/disbursements.types.ts +119 -3
- package/common/types/file.types.ts +17 -1
- package/common/types/i-will-do-it-later.types.ts +68 -0
- package/common/types/index.ts +2 -0
- package/common/types/individuals.types.ts +2 -15
- package/common/types/issuer-offering.types.ts +13 -17
- package/common/types/issuer-payment-method.types.ts +41 -0
- package/common/types/issuer.types.ts +9 -0
- package/common/types/notification.types.ts +515 -29
- package/common/types/offering.types.ts +4 -9
- package/common/types/site.types.ts +2 -9
- package/common/types/{trade-line-item.type.ts → trade-line-item.types.ts} +2 -9
- package/common/types/trade.types.ts +1 -1
- package/common/types/transaction.types.ts +12 -1
- package/common/types/user.types.ts +15 -28
- package/contracts/clients/cart/index.ts +21 -1
- package/contracts/clients/index.ts +6 -0
- package/contracts/clients/issuer-payment-methods/index.ts +39 -0
- package/contracts/clients/payment-methods/index.ts +85 -0
- package/contracts/clients/trade-line-items/index.ts +1 -1
- package/contracts/clients/trades/index.ts +1 -1
- package/contracts/clients/transactions/index.ts +37 -0
- package/contracts/compliance/account-settings/index.ts +59 -0
- package/contracts/compliance/bonus-tiers/index.ts +21 -2
- package/contracts/compliance/index.ts +4 -0
- package/contracts/compliance/notification-channels/index.ts +251 -0
- package/contracts/compliance/trade-line-items/index.ts +1 -1
- package/contracts/compliance/users/index.ts +21 -0
- package/contracts/investors/bonus-tiers/index.ts +18 -0
- package/contracts/investors/individuals/index.ts +22 -0
- package/contracts/investors/trade-line-items/index.ts +1 -1
- package/contracts/issuers/account-settings/index.ts +36 -0
- package/contracts/issuers/bonus-tiers/index.ts +18 -0
- package/contracts/issuers/disbursements/index.ts +36 -0
- package/contracts/issuers/index.ts +4 -0
- package/contracts/issuers/notification-channels/index.ts +251 -0
- package/package.json +1 -1
|
@@ -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
|
+
>;
|
|
@@ -199,7 +199,7 @@ export const ActivityZod = IBaseEntity.extend({
|
|
|
199
199
|
userId: z.string().nullable(),
|
|
200
200
|
activityTypeId: z.string(),
|
|
201
201
|
accountId: z.string().nullable(),
|
|
202
|
-
user: UserForActivityZod,
|
|
202
|
+
user: UserForActivityZod.nullable(),
|
|
203
203
|
activityType: ActivityTypeZod,
|
|
204
204
|
targetObject: z.string().nullable().optional(),
|
|
205
205
|
__entity: z.string().optional(),
|
|
@@ -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()
|
|
@@ -145,3 +154,27 @@ export const CompliancePostBonusTierZod = PostBonusTierZod.extend({
|
|
|
145
154
|
export type CompliancePostBonusTierZod = z.infer<
|
|
146
155
|
typeof CompliancePostBonusTierZod
|
|
147
156
|
>;
|
|
157
|
+
export const PurchaseCalculationZod = z.object({
|
|
158
|
+
assetId: assetIdSchema,
|
|
159
|
+
totalAmount: z.number().positive().openapi({ example: 1000 }),
|
|
160
|
+
purchasedShares: z.number().positive().int().openapi({ example: 100 }),
|
|
161
|
+
});
|
|
162
|
+
export type PurchaseCalculationZod = z.infer<typeof PurchaseCalculationZod>;
|
|
163
|
+
|
|
164
|
+
export const PurchaseCalculationResponseZod = z.object({
|
|
165
|
+
bonusTierId: bonusTierIdSchema
|
|
166
|
+
.nullable()
|
|
167
|
+
.openapi({ example: 'bonus_tier_01j5y5ghx5fg68d663j1fvy2x7' }),
|
|
168
|
+
assetId: assetIdSchema.openapi({
|
|
169
|
+
example: 'asset_00041061050r3gg28a1c60t3gf',
|
|
170
|
+
}),
|
|
171
|
+
type: z
|
|
172
|
+
.nativeEnum(BonusType)
|
|
173
|
+
.nullable()
|
|
174
|
+
.openapi({ example: BonusType.PERCENTAGE }),
|
|
175
|
+
bonusShares: z.number().int().openapi({ example: 100 }),
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
export type PurchaseCalculationResponseZod = z.infer<
|
|
179
|
+
typeof PurchaseCalculationResponseZod
|
|
180
|
+
>;
|
|
@@ -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(),
|
|
@@ -111,6 +111,10 @@ export enum HttpMethod {
|
|
|
111
111
|
OPTIONS = 'OPTIONS',
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
export enum UserStatus {
|
|
115
|
+
ACTIVE = 'ACTIVE',
|
|
116
|
+
LOCKED = 'LOCKED',
|
|
117
|
+
}
|
|
114
118
|
export const SENSITIVE_PATTERNS = [
|
|
115
119
|
/password/i,
|
|
116
120
|
/credit.*card/i,
|
|
@@ -200,11 +204,6 @@ export enum UserType {
|
|
|
200
204
|
DEMO = 'DEMO',
|
|
201
205
|
}
|
|
202
206
|
|
|
203
|
-
export enum UserStatus {
|
|
204
|
-
ACTIVE = 'ACTIVE',
|
|
205
|
-
LOCKED = 'LOCKED',
|
|
206
|
-
}
|
|
207
|
-
|
|
208
207
|
export enum UserRole {
|
|
209
208
|
API_KEY = 'API_KEY',
|
|
210
209
|
IMPORT = 'IMPORT',
|
|
@@ -306,7 +305,7 @@ export const AuthUserReq = BaseAuthReq.extend({
|
|
|
306
305
|
lastName: z.string(),
|
|
307
306
|
email: z.string().email(),
|
|
308
307
|
provider: z.string(),
|
|
309
|
-
|
|
308
|
+
locked: z.boolean(),
|
|
310
309
|
lastLoginAt: z.date().nullable(),
|
|
311
310
|
loginCount: z.number(),
|
|
312
311
|
requiresTwoFactorSetup: z.boolean().optional(),
|
|
@@ -1518,3 +1517,14 @@ export const SUBJECT_TYPE_MAP: Record<BulkExportType, string> = {
|
|
|
1518
1517
|
[BulkExportType.SECONDARY_CUSTOMERS]: 'Secondary Customers',
|
|
1519
1518
|
[BulkExportType.SECONDARY_TRADES]: 'Secondary Trades',
|
|
1520
1519
|
};
|
|
1520
|
+
|
|
1521
|
+
export const StringToBooleanSchema = z.preprocess(
|
|
1522
|
+
(val) =>
|
|
1523
|
+
val === 'true' || val === '1'
|
|
1524
|
+
? true
|
|
1525
|
+
: val === 'false' || val === '0'
|
|
1526
|
+
? false
|
|
1527
|
+
: val,
|
|
1528
|
+
z.boolean(),
|
|
1529
|
+
);
|
|
1530
|
+
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:
|
|
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
|
|
@@ -11,14 +11,17 @@ import {
|
|
|
11
11
|
import { tradeIdSchema } from './trade.types';
|
|
12
12
|
import { accountIdSchema } from './account.types';
|
|
13
13
|
import { TypeID } from 'typeid-js';
|
|
14
|
-
import { issuerIdSchema } from './issuer.types';
|
|
15
|
-
import {
|
|
14
|
+
import { IIssuer, issuerIdSchema } from './issuer.types';
|
|
15
|
+
import {
|
|
16
|
+
IIssuerBankAccount,
|
|
17
|
+
issuerBankAccountIdSchema,
|
|
18
|
+
} from './issuer-bank-account.types';
|
|
16
19
|
import { userIdSchema, UserZod } from './user.types';
|
|
17
20
|
import {
|
|
18
21
|
PostDisbursementAdjustmentZod,
|
|
19
22
|
DisbursementAdjustmentType,
|
|
20
23
|
} from './disbursement-adjustment.types';
|
|
21
|
-
import { escrowAccountIdSchema } from './escrow-account.types';
|
|
24
|
+
import { IEscrowAccount, escrowAccountIdSchema } from './escrow-account.types';
|
|
22
25
|
|
|
23
26
|
export const disbursementIdSchema = z.string().refine(
|
|
24
27
|
(value) => {
|
|
@@ -308,3 +311,116 @@ export const DisbursementSummaryZod = z.object({
|
|
|
308
311
|
amountToBeTransferred: z.number(),
|
|
309
312
|
});
|
|
310
313
|
export type DisbursementSummaryZod = z.infer<typeof DisbursementSummaryZod>;
|
|
314
|
+
|
|
315
|
+
// GET /disbursements/preview query parameters
|
|
316
|
+
export const GetDisbursementPreviewQueryZod = z.object({
|
|
317
|
+
offeringId: offeringIdSchema,
|
|
318
|
+
selectedTrades: z
|
|
319
|
+
.string()
|
|
320
|
+
.optional()
|
|
321
|
+
.transform((str) => (str ? str.split(',') : []))
|
|
322
|
+
.refine(
|
|
323
|
+
(ids) =>
|
|
324
|
+
ids.every((id) => {
|
|
325
|
+
try {
|
|
326
|
+
const tid = TypeID.fromString(id);
|
|
327
|
+
return tid.getType() === 'trade';
|
|
328
|
+
} catch {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
}),
|
|
332
|
+
{
|
|
333
|
+
message: 'All selected trades must be valid trade IDs',
|
|
334
|
+
},
|
|
335
|
+
)
|
|
336
|
+
.openapi({
|
|
337
|
+
example: 'trade_01abc123,trade_01def456',
|
|
338
|
+
}),
|
|
339
|
+
});
|
|
340
|
+
export type GetDisbursementPreviewQueryZod = z.infer<
|
|
341
|
+
typeof GetDisbursementPreviewQueryZod
|
|
342
|
+
>;
|
|
343
|
+
|
|
344
|
+
// Context fields for disbursement preview
|
|
345
|
+
export const DisbursementPreviewContextZod = z.object({
|
|
346
|
+
issuer: z.lazy(() => IIssuer).nullable(),
|
|
347
|
+
offering: z.lazy(() => IOffering).nullable(),
|
|
348
|
+
escrowAccount: z.lazy(() => IEscrowAccount).nullable(),
|
|
349
|
+
destinationBank: z.lazy(() => IIssuerBankAccount).nullable(),
|
|
350
|
+
});
|
|
351
|
+
export type DisbursementPreviewContextZod = z.infer<
|
|
352
|
+
typeof DisbursementPreviewContextZod
|
|
353
|
+
>;
|
|
354
|
+
|
|
355
|
+
// Balance values for disbursement preview
|
|
356
|
+
export const DisbursementPreviewBalanceZod = z.object({
|
|
357
|
+
totalRaised: z.number(),
|
|
358
|
+
totalDisbursed: z.number(),
|
|
359
|
+
pending: z.number(),
|
|
360
|
+
refundPool: z.number(),
|
|
361
|
+
availableForDisbursement: z.number(),
|
|
362
|
+
});
|
|
363
|
+
export type DisbursementPreviewBalanceZod = z.infer<
|
|
364
|
+
typeof DisbursementPreviewBalanceZod
|
|
365
|
+
>;
|
|
366
|
+
|
|
367
|
+
// Trade summary for disbursement preview
|
|
368
|
+
export const DisbursementPreviewTradeSummaryZod = z.object({
|
|
369
|
+
selectedTradesCount: z.number(),
|
|
370
|
+
selectedTradesTotalAmount: z.number(),
|
|
371
|
+
});
|
|
372
|
+
export type DisbursementPreviewTradeSummaryZod = z.infer<
|
|
373
|
+
typeof DisbursementPreviewTradeSummaryZod
|
|
374
|
+
>;
|
|
375
|
+
|
|
376
|
+
// Contingency validation result
|
|
377
|
+
export const DisbursementPreviewContingencyZod = z.object({
|
|
378
|
+
contingencyPassed: z.boolean(),
|
|
379
|
+
contingencyMessage: z.string().nullable(),
|
|
380
|
+
contingencyAmount: z.number(),
|
|
381
|
+
});
|
|
382
|
+
export type DisbursementPreviewContingencyZod = z.infer<
|
|
383
|
+
typeof DisbursementPreviewContingencyZod
|
|
384
|
+
>;
|
|
385
|
+
|
|
386
|
+
// Amount defaults and constraints
|
|
387
|
+
export const DisbursementPreviewAmountZod = z.object({
|
|
388
|
+
defaultAmount: z.number(),
|
|
389
|
+
minAmount: z.number(),
|
|
390
|
+
maxAmount: z.number(),
|
|
391
|
+
});
|
|
392
|
+
export type DisbursementPreviewAmountZod = z.infer<
|
|
393
|
+
typeof DisbursementPreviewAmountZod
|
|
394
|
+
>;
|
|
395
|
+
|
|
396
|
+
// Complete response for GET /disbursements/preview
|
|
397
|
+
export const DisbursementPreviewZod = z.object({
|
|
398
|
+
context: DisbursementPreviewContextZod,
|
|
399
|
+
balance: DisbursementPreviewBalanceZod,
|
|
400
|
+
tradeSummary: DisbursementPreviewTradeSummaryZod,
|
|
401
|
+
contingency: DisbursementPreviewContingencyZod,
|
|
402
|
+
amount: DisbursementPreviewAmountZod,
|
|
403
|
+
});
|
|
404
|
+
export type DisbursementPreviewZod = z.infer<typeof DisbursementPreviewZod>;
|
|
405
|
+
|
|
406
|
+
export const EligibleOfferingZod = z.object({
|
|
407
|
+
offeringId: offeringIdSchema,
|
|
408
|
+
offeringName: z.string(),
|
|
409
|
+
availableAmount: z.number(),
|
|
410
|
+
});
|
|
411
|
+
export type EligibleOfferingZod = z.infer<typeof EligibleOfferingZod>;
|
|
412
|
+
|
|
413
|
+
export const IPaginatedEligibleOffering = z.object({
|
|
414
|
+
items: z.array(EligibleOfferingZod),
|
|
415
|
+
meta: IPaginationMeta,
|
|
416
|
+
});
|
|
417
|
+
export type IPaginatedEligibleOffering = z.infer<
|
|
418
|
+
typeof IPaginatedEligibleOffering
|
|
419
|
+
>;
|
|
420
|
+
|
|
421
|
+
export const EligibleOfferingsFiltersZod = z.object({
|
|
422
|
+
search: z.string().optional(),
|
|
423
|
+
});
|
|
424
|
+
export type EligibleOfferingsFiltersZod = z.infer<
|
|
425
|
+
typeof EligibleOfferingsFiltersZod
|
|
426
|
+
>;
|
|
@@ -314,8 +314,23 @@ export const reviewFiles = z.object({
|
|
|
314
314
|
});
|
|
315
315
|
export type reviewFiles = z.infer<typeof reviewFiles>;
|
|
316
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Zod preprocessor that trims strings and converts empty/whitespace-only strings to null
|
|
319
|
+
*/
|
|
320
|
+
const trimAndNullifyString = z.preprocess((val) => {
|
|
321
|
+
if (typeof val === 'string') {
|
|
322
|
+
const trimmed = val.trim();
|
|
323
|
+
return trimmed === '' ? null : trimmed;
|
|
324
|
+
}
|
|
325
|
+
return val;
|
|
326
|
+
}, z.unknown());
|
|
327
|
+
|
|
317
328
|
export const PatchFileMetadata = z.object({
|
|
318
|
-
corrected: z.record(z.string(),
|
|
329
|
+
corrected: z.record(z.string(), trimAndNullifyString),
|
|
330
|
+
expectedCorrected: z
|
|
331
|
+
.record(z.string(), trimAndNullifyString)
|
|
332
|
+
.nullable()
|
|
333
|
+
.optional(),
|
|
319
334
|
});
|
|
320
335
|
export type PatchFileMetadata = z.infer<typeof PatchFileMetadata>;
|
|
321
336
|
|
|
@@ -343,6 +358,7 @@ export const FileMetadataSchema = z.object({
|
|
|
343
358
|
},
|
|
344
359
|
),
|
|
345
360
|
corrected: z.record(z.any()).optional(),
|
|
361
|
+
expectedCorrected: z.record(z.any()).optional(),
|
|
346
362
|
});
|
|
347
363
|
export type FileMetadata = z.infer<typeof FileMetadataSchema>;
|
|
348
364
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { PortalType, TargetTableEnum } from './common.types';
|
|
3
|
+
import { TaskPriority, TaskType } from './task.types';
|
|
4
|
+
|
|
5
|
+
export enum IWillDoItLaterType {
|
|
6
|
+
KYC = 'KYC',
|
|
7
|
+
// Future types can be added here:
|
|
8
|
+
// AIC = 'AIC',
|
|
9
|
+
// AML = 'AML',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const IWillDoItLaterBodySchema = z.object({
|
|
13
|
+
type: z.nativeEnum(IWillDoItLaterType).default(IWillDoItLaterType.KYC),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type IWillDoItLaterBodyType = z.infer<typeof IWillDoItLaterBodySchema>;
|
|
17
|
+
|
|
18
|
+
export const IWillDoItLaterResponseSchema = z.object({
|
|
19
|
+
message: z.string(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export type IWillDoItLaterResponseType = z.infer<
|
|
23
|
+
typeof IWillDoItLaterResponseSchema
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @description Context required for processing "I'll do it later" actions.
|
|
28
|
+
*/
|
|
29
|
+
export interface IWillDoItLaterContext {
|
|
30
|
+
/** The ID of the target entity */
|
|
31
|
+
targetId: string;
|
|
32
|
+
/** The table name of the target entity */
|
|
33
|
+
targetTable: (typeof TargetTableEnum)[number];
|
|
34
|
+
/** The account ID associated with the action */
|
|
35
|
+
accountId: string;
|
|
36
|
+
/** The user ID who will be assigned the task */
|
|
37
|
+
assigneeId: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @description Configuration for each "I'll do it later" action type.
|
|
42
|
+
* Maps action types to their corresponding task configuration.
|
|
43
|
+
*/
|
|
44
|
+
export interface IWillDoItLaterTaskConfig {
|
|
45
|
+
taskType: TaskType;
|
|
46
|
+
portalType: PortalType;
|
|
47
|
+
title: string;
|
|
48
|
+
description: string;
|
|
49
|
+
priority: TaskPriority;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @description Mapping of "I'll do it later" types to their task configurations.
|
|
54
|
+
* This allows for easy extension of new action types without modifying the service logic.
|
|
55
|
+
*/
|
|
56
|
+
export const IWillDoItLaterTaskConfigMap: Record<
|
|
57
|
+
IWillDoItLaterType,
|
|
58
|
+
IWillDoItLaterTaskConfig
|
|
59
|
+
> = {
|
|
60
|
+
[IWillDoItLaterType.KYC]: {
|
|
61
|
+
taskType: TaskType.COMPLETE_KYC,
|
|
62
|
+
portalType: PortalType.INVESTOR,
|
|
63
|
+
title: 'Complete KYC',
|
|
64
|
+
description:
|
|
65
|
+
'We are unable to verify your KYC information. Please complete your KYC.',
|
|
66
|
+
priority: TaskPriority.HIGH,
|
|
67
|
+
},
|
|
68
|
+
};
|
package/common/types/index.ts
CHANGED
|
@@ -42,6 +42,8 @@ export * from './domain-filter.types';
|
|
|
42
42
|
export * from './aic.types';
|
|
43
43
|
export * from './default-theme-config.types';
|
|
44
44
|
export * from './offering-reports.types';
|
|
45
|
+
export * from './i-will-do-it-later.types';
|
|
46
|
+
export * from './payment-methods.types';
|
|
45
47
|
|
|
46
48
|
export enum Versions {
|
|
47
49
|
V1 = 'v1',
|
|
@@ -12,9 +12,7 @@ import {
|
|
|
12
12
|
InvestorAccountType,
|
|
13
13
|
SetupStatusType,
|
|
14
14
|
SetupStepType,
|
|
15
|
-
ComplianceReview,
|
|
16
15
|
RetirementAccountType,
|
|
17
|
-
TradeStatus,
|
|
18
16
|
EmploymentStatus,
|
|
19
17
|
SourceOfIncome,
|
|
20
18
|
AMLProvider,
|
|
@@ -60,8 +58,8 @@ export enum aicQuestionnaireQuestionType {
|
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
export enum FilterBy {
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
ALL = 'ALL',
|
|
62
|
+
PENDING_TRADES = 'PENDING_TRADES',
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
export const aicQuestionnaireQuestion = z.object({
|
|
@@ -243,17 +241,6 @@ export const IndividualFiltersZod = z.object({
|
|
|
243
241
|
|
|
244
242
|
export const ComplianceIndividualFiltersZod = IndividualFiltersZod.extend({
|
|
245
243
|
filterBy: z.nativeEnum(FilterBy).optional(),
|
|
246
|
-
tradeStatus: z.nativeEnum(TradeStatus).optional(),
|
|
247
|
-
complianceReview: z.nativeEnum(ComplianceReview).optional(),
|
|
248
|
-
hasPendingTrades: z.preprocess(
|
|
249
|
-
(val) =>
|
|
250
|
-
val === 'true' || val === '1'
|
|
251
|
-
? true
|
|
252
|
-
: val === 'false' || val === '0'
|
|
253
|
-
? false
|
|
254
|
-
: val,
|
|
255
|
-
z.boolean().optional(),
|
|
256
|
-
),
|
|
257
244
|
});
|
|
258
245
|
|
|
259
246
|
/**
|
|
@@ -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';
|
|
@@ -168,6 +169,7 @@ export const PostIssuerOffering = z
|
|
|
168
169
|
.default(AssetTemplateType.STANDARD)
|
|
169
170
|
.openapi({ example: AssetTemplateType.STANDARD }),
|
|
170
171
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
172
|
+
enableBonus: z.boolean().default(false).optional(),
|
|
171
173
|
})
|
|
172
174
|
.superRefine((data, ctx) => {
|
|
173
175
|
// Check if both values are present, and if so, ensure minInvestment is less than maxInvestment
|
|
@@ -192,38 +194,39 @@ export const PatchIssuerOffering = z.object({
|
|
|
192
194
|
.max(100)
|
|
193
195
|
.optional()
|
|
194
196
|
.openapi({ example: 'Airbnb IPO' }),
|
|
197
|
+
type: z
|
|
198
|
+
.nativeEnum(OfferingType)
|
|
199
|
+
.optional()
|
|
200
|
+
.openapi({ example: OfferingType.REG_D }),
|
|
195
201
|
targetAmount: z
|
|
196
202
|
.number()
|
|
197
203
|
.min(0)
|
|
198
204
|
.max(10000000000)
|
|
199
205
|
.optional()
|
|
200
206
|
.openapi({ example: 120000 }),
|
|
201
|
-
raiseAmount: z
|
|
202
|
-
.number()
|
|
203
|
-
.min(0)
|
|
204
|
-
.max(10000000000)
|
|
205
|
-
.optional()
|
|
206
|
-
.openapi({ example: 200000 }),
|
|
207
207
|
minInvestment: z
|
|
208
208
|
.number()
|
|
209
209
|
.min(0)
|
|
210
210
|
.max(10000000000)
|
|
211
|
+
.nullable()
|
|
211
212
|
.optional()
|
|
212
213
|
.openapi({ example: 1000 }),
|
|
213
214
|
maxInvestment: z
|
|
214
215
|
.number()
|
|
215
216
|
.min(0)
|
|
216
217
|
.max(10000000000)
|
|
218
|
+
.nullable()
|
|
217
219
|
.optional()
|
|
218
220
|
.openapi({ example: 20000 }),
|
|
219
221
|
contingencyAmount: z
|
|
220
222
|
.number()
|
|
221
223
|
.min(0)
|
|
222
224
|
.max(10000000000)
|
|
225
|
+
.nullable()
|
|
223
226
|
.optional()
|
|
224
227
|
.openapi({ example: 5000 }),
|
|
225
|
-
startAt: dateSchema.optional().openapi({ example: '10/20/2024' }),
|
|
226
|
-
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' }),
|
|
227
230
|
cancellationPeriod: z
|
|
228
231
|
.number()
|
|
229
232
|
.min(1)
|
|
@@ -299,6 +302,7 @@ export const PatchIssuerOffering = z.object({
|
|
|
299
302
|
.optional(),
|
|
300
303
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
301
304
|
enabled: z.boolean().optional(),
|
|
305
|
+
enableBonus: z.boolean().optional(),
|
|
302
306
|
});
|
|
303
307
|
export type PatchIssuerOffering = z.infer<typeof PatchIssuerOffering>;
|
|
304
308
|
|
|
@@ -368,15 +372,7 @@ export const IssuerOfferingsFilterZod = z.object({
|
|
|
368
372
|
issuerId: z.lazy(() => issuerIdSchema).optional(),
|
|
369
373
|
type: z.nativeEnum(OfferingType).optional(),
|
|
370
374
|
status: z.nativeEnum(ComplianceReview).optional(),
|
|
371
|
-
enabled:
|
|
372
|
-
(val) =>
|
|
373
|
-
val === 'true' || val === '1'
|
|
374
|
-
? true
|
|
375
|
-
: val === 'false' || val === '0'
|
|
376
|
-
? false
|
|
377
|
-
: val,
|
|
378
|
-
z.boolean().optional(),
|
|
379
|
-
),
|
|
375
|
+
enabled: StringToBooleanSchema.optional(),
|
|
380
376
|
managedBy: z.nativeEnum(ManagedByType).optional(),
|
|
381
377
|
versioningType: z.nativeEnum(OfferingVersioningType).optional(),
|
|
382
378
|
combinedStatus: z.nativeEnum(OfferingStatus).optional(),
|
|
@@ -222,10 +222,51 @@ export type IPaginatedIssuerPaymentMethod = z.infer<
|
|
|
222
222
|
typeof IPaginatedIssuerPaymentMethod
|
|
223
223
|
>;
|
|
224
224
|
|
|
225
|
+
const issuerPaymentMethodsInclude = z.enum(['issuer', 'integration']);
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @description Query parameters for including related entities
|
|
229
|
+
* @example in contract use as -> query: PaginationOptionsZod.merge(GetIssuerPaymentMethodZod).merge(IssuerPaymentMethodsIncludeQuery)
|
|
230
|
+
*/
|
|
231
|
+
export const IssuerPaymentMethodsIncludeQuery = z.object({
|
|
232
|
+
include: z
|
|
233
|
+
.string()
|
|
234
|
+
.optional()
|
|
235
|
+
.transform((str) => (str ? str.split(',') : []))
|
|
236
|
+
.refine(
|
|
237
|
+
(includes) =>
|
|
238
|
+
includes.every((include) =>
|
|
239
|
+
issuerPaymentMethodsInclude.options.includes(include as any),
|
|
240
|
+
),
|
|
241
|
+
{
|
|
242
|
+
message: `Invalid include option provided. Valid options are: ${issuerPaymentMethodsInclude.options.join(',')}`,
|
|
243
|
+
},
|
|
244
|
+
)
|
|
245
|
+
.openapi({
|
|
246
|
+
example: `${issuerPaymentMethodsInclude.options.join(',')}`,
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
export type IssuerPaymentMethodsIncludeQuery = z.infer<
|
|
250
|
+
typeof IssuerPaymentMethodsIncludeQuery
|
|
251
|
+
>;
|
|
252
|
+
|
|
225
253
|
export const GetIssuerPaymentMethodZod = z.object({
|
|
226
254
|
issuerId: issuerIdSchema.openapi({
|
|
227
255
|
example: 'issuer_01jdq2crwke8xskjd840cj79pw',
|
|
228
256
|
}),
|
|
257
|
+
enabled: z
|
|
258
|
+
.string()
|
|
259
|
+
.optional()
|
|
260
|
+
.refine((v) => !v || v === 'true' || v === 'false', {
|
|
261
|
+
message: 'enabled must be a boolean string',
|
|
262
|
+
})
|
|
263
|
+
.transform((v) => {
|
|
264
|
+
if (!v) return undefined;
|
|
265
|
+
return v === 'true';
|
|
266
|
+
})
|
|
267
|
+
.openapi({
|
|
268
|
+
example: 'true',
|
|
269
|
+
}),
|
|
229
270
|
});
|
|
230
271
|
export type GetIssuerPaymentMethodZod = z.infer<
|
|
231
272
|
typeof GetIssuerPaymentMethodZod
|
|
@@ -152,6 +152,10 @@ export const PutIssuerZod = z
|
|
|
152
152
|
.lazy(() => fileIdSchema)
|
|
153
153
|
.optional()
|
|
154
154
|
.nullable(),
|
|
155
|
+
formationDocumentFileId: z
|
|
156
|
+
.lazy(() => fileIdSchema)
|
|
157
|
+
.optional()
|
|
158
|
+
.nullable(),
|
|
155
159
|
coverArtId: z
|
|
156
160
|
.lazy(() => fileIdSchema)
|
|
157
161
|
.optional()
|
|
@@ -188,6 +192,11 @@ export const IIssuer = IBaseEntity.extend({
|
|
|
188
192
|
accountId: z.string(),
|
|
189
193
|
account: AccountZod.optional().nullable(),
|
|
190
194
|
ss4LetterFileId: z.string().nullable(),
|
|
195
|
+
formationDocumentFileId: z.string().nullable(),
|
|
196
|
+
formationDocument: z
|
|
197
|
+
.lazy(() => FileZod)
|
|
198
|
+
.nullable()
|
|
199
|
+
.optional(),
|
|
191
200
|
status: z
|
|
192
201
|
.nativeEnum(IssuerStatus)
|
|
193
202
|
.openapi({ example: IssuerStatus.SUBMITTED }),
|