@dalmore/api-contracts 0.0.0-dev.d30d175 → 0.0.0-dev.d8ef117
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/activity.types.ts +1 -1
- package/common/types/bonus-tier.types.ts +24 -0
- package/common/types/cart.types.ts +4 -1
- package/common/types/disbursements.types.ts +119 -3
- package/common/types/file.types.ts +20 -4
- 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 +3 -7
- package/common/types/issuer-payment-method.types.ts +41 -0
- package/common/types/issuer.types.ts +9 -0
- package/common/types/offering.types.ts +3 -6
- package/common/types/transaction.types.ts +12 -1
- package/common/types/user.types.ts +6 -1
- package/contracts/clients/cart/index.ts +80 -0
- package/contracts/clients/index.ts +10 -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 +66 -0
- package/contracts/clients/transactions/index.ts +37 -0
- package/contracts/compliance/bonus-tiers/index.ts +19 -0
- 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/issuers/bonus-tiers/index.ts +18 -0
- package/contracts/issuers/disbursements/index.ts +36 -0
- package/package.json +1 -1
|
@@ -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(),
|
|
@@ -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(),
|
|
@@ -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
|
+
>;
|
|
@@ -17,7 +17,7 @@ import { KybZod } from './kyb.types';
|
|
|
17
17
|
import { IIndividualZod, individualIdSchema } from './individuals.types';
|
|
18
18
|
import { LegalEntityZod } from './legal-entity.types';
|
|
19
19
|
import { IInvestorAccount } from './investor-account.types';
|
|
20
|
-
import { TradeZod } from './trade.types';
|
|
20
|
+
import { tradeIdSchema, TradeZod } from './trade.types';
|
|
21
21
|
|
|
22
22
|
extendZodWithOpenApi(z);
|
|
23
23
|
|
|
@@ -168,13 +168,13 @@ export type PostFileQueryParams = z.infer<typeof PostFileQueryParams>;
|
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* CLIENT portal specific schema for file uploads
|
|
171
|
-
* Only allows INDIVIDUALS as target for file uploads
|
|
171
|
+
* Only allows INDIVIDUALS and TRADES as target for file uploads
|
|
172
172
|
*/
|
|
173
173
|
export const ClientPostFileQueryParams = z.object({
|
|
174
174
|
name: z.string().min(1).max(100).openapi({ example: 'file_name' }),
|
|
175
175
|
category: z.string().max(50).openapi({ example: 'application' }),
|
|
176
176
|
label: FileLabelsEnum.openapi({ example: FileLabels.OTHER }),
|
|
177
|
-
targetId: individualIdSchema.openapi({
|
|
177
|
+
targetId: z.union([individualIdSchema, tradeIdSchema]).openapi({
|
|
178
178
|
example: 'individual_01kcrsny60fb9rjc8bbqc3b80c',
|
|
179
179
|
}),
|
|
180
180
|
metadata: metadataSchema.nullable().optional(),
|
|
@@ -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
|
/**
|
|
@@ -13,12 +13,7 @@ import {
|
|
|
13
13
|
} from './common.types';
|
|
14
14
|
import { IBaseEntity } from './entity.types';
|
|
15
15
|
import { IIssuer, issuerIdSchema } from './issuer.types';
|
|
16
|
-
import {
|
|
17
|
-
IAsset,
|
|
18
|
-
postAssetRefinement,
|
|
19
|
-
AssetTemplateType,
|
|
20
|
-
assetIdSchema,
|
|
21
|
-
} from './asset.types';
|
|
16
|
+
import { IAsset, postAssetRefinement, AssetTemplateType } from './asset.types';
|
|
22
17
|
import { fileIdSchema, FileZod } from './file.types';
|
|
23
18
|
import { accountIdSchema } from './account.types';
|
|
24
19
|
|
|
@@ -173,6 +168,7 @@ export const PostIssuerOffering = z
|
|
|
173
168
|
.default(AssetTemplateType.STANDARD)
|
|
174
169
|
.openapi({ example: AssetTemplateType.STANDARD }),
|
|
175
170
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
171
|
+
enableBonus: z.boolean().default(false).optional(),
|
|
176
172
|
})
|
|
177
173
|
.superRefine((data, ctx) => {
|
|
178
174
|
// Check if both values are present, and if so, ensure minInvestment is less than maxInvestment
|
|
@@ -258,7 +254,6 @@ export const PatchIssuerOffering = z.object({
|
|
|
258
254
|
managedBy: z.nativeEnum(ManagedByType).optional(),
|
|
259
255
|
showTotalRaised: z.boolean().optional(),
|
|
260
256
|
issuerId: issuerIdSchema.optional(),
|
|
261
|
-
assetId: assetIdSchema,
|
|
262
257
|
assetName: z.string().min(2).max(50).optional().openapi({ example: 'Z' }),
|
|
263
258
|
assetType: z
|
|
264
259
|
.nativeEnum(AssetType)
|
|
@@ -305,6 +300,7 @@ export const PatchIssuerOffering = z.object({
|
|
|
305
300
|
.optional(),
|
|
306
301
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
307
302
|
enabled: z.boolean().optional(),
|
|
303
|
+
enableBonus: z.boolean().optional(),
|
|
308
304
|
});
|
|
309
305
|
export type PatchIssuerOffering = z.infer<typeof PatchIssuerOffering>;
|
|
310
306
|
|
|
@@ -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 }),
|
|
@@ -26,11 +26,7 @@ import {
|
|
|
26
26
|
InvestorsOfferingsIncludeQuery,
|
|
27
27
|
} from './investors-offering.types';
|
|
28
28
|
import { OfferingStatus } from './issuer-offering.types';
|
|
29
|
-
import {
|
|
30
|
-
assetIdSchema,
|
|
31
|
-
postAssetRefinement,
|
|
32
|
-
AssetTemplateType,
|
|
33
|
-
} from './asset.types';
|
|
29
|
+
import { postAssetRefinement, AssetTemplateType } from './asset.types';
|
|
34
30
|
|
|
35
31
|
export enum OfferingFeeType {
|
|
36
32
|
FIXED = 'FIXED',
|
|
@@ -184,7 +180,6 @@ export const PatchOfferingBase = z.object({
|
|
|
184
180
|
});
|
|
185
181
|
export const PatchOffering = PatchOfferingBase.merge(
|
|
186
182
|
z.object({
|
|
187
|
-
assetId: assetIdSchema,
|
|
188
183
|
assetName: z
|
|
189
184
|
.string()
|
|
190
185
|
.min(2)
|
|
@@ -235,6 +230,7 @@ export const PatchOffering = PatchOfferingBase.merge(
|
|
|
235
230
|
.nullable()
|
|
236
231
|
.optional(),
|
|
237
232
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
233
|
+
enableBonus: z.boolean().optional(),
|
|
238
234
|
}),
|
|
239
235
|
);
|
|
240
236
|
export type PatchOffering = z.infer<typeof PatchOffering>;
|
|
@@ -281,6 +277,7 @@ export const PostComplianceOffering = PatchOfferingBase.merge(
|
|
|
281
277
|
.default(AssetTemplateType.STANDARD)
|
|
282
278
|
.openapi({ example: AssetTemplateType.STANDARD }),
|
|
283
279
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
280
|
+
enableBonus: z.boolean().default(false).optional(),
|
|
284
281
|
}),
|
|
285
282
|
).superRefine(postAssetRefinement);
|
|
286
283
|
export type PostComplianceOffering = z.infer<typeof PostComplianceOffering>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { extendZodWithOpenApi } from '@anatine/zod-openapi';
|
|
1
3
|
import { TypeID } from 'typeid-js';
|
|
2
4
|
import {
|
|
3
5
|
dateSchema,
|
|
4
6
|
InvestorAccountType,
|
|
5
7
|
numberPrecisionSchema,
|
|
6
8
|
} from './common.types';
|
|
7
|
-
import { z } from 'zod';
|
|
8
9
|
import { IBaseEntity } from './entity.types';
|
|
9
10
|
import { accountIdSchema } from './account.types';
|
|
10
11
|
import {
|
|
@@ -18,7 +19,9 @@ import {
|
|
|
18
19
|
investorAccountIdSchema,
|
|
19
20
|
} from './investor-account.types';
|
|
20
21
|
import { TransactionStatus, TransactionType } from './common.types';
|
|
22
|
+
import { userIdSchema } from './user.types';
|
|
21
23
|
export { TransactionStatus, TransactionType };
|
|
24
|
+
extendZodWithOpenApi(z);
|
|
22
25
|
|
|
23
26
|
export enum RefundPaymentMethod {
|
|
24
27
|
CHECK = 'CHECK',
|
|
@@ -115,6 +118,14 @@ export type InvestorPostTransactionZod = z.infer<
|
|
|
115
118
|
typeof InvestorPostTransactionZod
|
|
116
119
|
>;
|
|
117
120
|
|
|
121
|
+
export const ClientPostTransactionZod = InvestorPostTransactionZod.extend({
|
|
122
|
+
userId: z
|
|
123
|
+
.lazy(() => userIdSchema)
|
|
124
|
+
.openapi({ example: 'user_01j5y5ghx5fg68d663j1fvy2x7' }),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export type ClientPostTransactionZod = z.infer<typeof ClientPostTransactionZod>;
|
|
128
|
+
|
|
118
129
|
export const refundTransactionIdSchema = z.string().refine(
|
|
119
130
|
(value) => {
|
|
120
131
|
try {
|
|
@@ -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,
|
|
@@ -12,7 +13,6 @@ import {
|
|
|
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(),
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { initContract } from '@ts-rest/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
UnauthorizedError,
|
|
5
|
+
ForbiddenError,
|
|
6
|
+
NotFoundError,
|
|
7
|
+
BadRequestError,
|
|
8
|
+
InternalError,
|
|
9
|
+
TradeZod,
|
|
10
|
+
userIdSchema,
|
|
11
|
+
tradeIdSchema,
|
|
12
|
+
} from '../../../common/types';
|
|
13
|
+
import {
|
|
14
|
+
PatchCartBody,
|
|
15
|
+
ClientPlacetradeBody,
|
|
16
|
+
PlaceTradeResponse,
|
|
17
|
+
} from '../../../common/types/cart.types';
|
|
18
|
+
|
|
19
|
+
const c = initContract();
|
|
20
|
+
|
|
21
|
+
export const cartContract = c.router(
|
|
22
|
+
{
|
|
23
|
+
getTradeCart: {
|
|
24
|
+
summary: 'Get carts (Trade.status = CART)',
|
|
25
|
+
method: 'GET',
|
|
26
|
+
path: '',
|
|
27
|
+
metadata: {
|
|
28
|
+
auth: true,
|
|
29
|
+
},
|
|
30
|
+
query: z.object({
|
|
31
|
+
userId: userIdSchema,
|
|
32
|
+
}),
|
|
33
|
+
responses: {
|
|
34
|
+
200: TradeZod,
|
|
35
|
+
401: UnauthorizedError,
|
|
36
|
+
403: ForbiddenError,
|
|
37
|
+
404: NotFoundError,
|
|
38
|
+
500: InternalError,
|
|
39
|
+
},
|
|
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
|
+
},
|
|
57
|
+
patchCart: {
|
|
58
|
+
summary: 'Patch a cart',
|
|
59
|
+
method: 'PATCH',
|
|
60
|
+
path: '/:id',
|
|
61
|
+
metadata: {
|
|
62
|
+
auth: true,
|
|
63
|
+
},
|
|
64
|
+
pathParams: z.object({
|
|
65
|
+
id: tradeIdSchema,
|
|
66
|
+
}),
|
|
67
|
+
body: PatchCartBody,
|
|
68
|
+
responses: {
|
|
69
|
+
200: TradeZod,
|
|
70
|
+
400: BadRequestError,
|
|
71
|
+
401: UnauthorizedError,
|
|
72
|
+
403: ForbiddenError,
|
|
73
|
+
500: InternalError,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
pathPrefix: 'carts',
|
|
79
|
+
},
|
|
80
|
+
);
|
|
@@ -3,6 +3,7 @@ import { accountsContract } from './accounts';
|
|
|
3
3
|
import { apiKeysContract } from './api-keys';
|
|
4
4
|
import { clientApiKeyLogsContract } from './api-key-logs';
|
|
5
5
|
import { assetsContract } from './assets';
|
|
6
|
+
import { cartContract } from './cart';
|
|
6
7
|
import { filesContract } from './files';
|
|
7
8
|
import { individualsContract } from './individuals';
|
|
8
9
|
import { investorAccountsContract } from './investor-accounts';
|
|
@@ -15,6 +16,10 @@ import { secureRequestContract } from './secure-requests';
|
|
|
15
16
|
import { aicContract } from './aic';
|
|
16
17
|
import { authContract } from './auth';
|
|
17
18
|
import { sitesContract } from './sites';
|
|
19
|
+
import { paymentMethodsContract } from './payment-methods';
|
|
20
|
+
import { issuerPaymentMethodsContract } from './issuer-payment-methods';
|
|
21
|
+
import { tradeLineItemsContract } from './trade-line-items';
|
|
22
|
+
import { clientsTransactionsContract } from './transactions';
|
|
18
23
|
|
|
19
24
|
const c = initContract();
|
|
20
25
|
|
|
@@ -27,16 +32,21 @@ export const clientsContract = c.router(
|
|
|
27
32
|
apiKeys: apiKeysContract,
|
|
28
33
|
apiKeyLogs: clientApiKeyLogsContract,
|
|
29
34
|
assets: assetsContract,
|
|
35
|
+
cart: cartContract,
|
|
30
36
|
files: filesContract,
|
|
31
37
|
filesPublic: filesPublicContract,
|
|
32
38
|
individuals: individualsContract,
|
|
33
39
|
investorAccounts: investorAccountsContract,
|
|
40
|
+
issuerPaymentMethods: issuerPaymentMethodsContract,
|
|
34
41
|
issuers: issuersContract,
|
|
35
42
|
legalEntities: legalEntityContract,
|
|
36
43
|
offerings: offeringsContract,
|
|
44
|
+
paymentMethods: paymentMethodsContract,
|
|
37
45
|
secureRequests: secureRequestContract,
|
|
38
46
|
sites: sitesContract,
|
|
47
|
+
tradeLineItems: tradeLineItemsContract,
|
|
39
48
|
trades: tradesContract,
|
|
49
|
+
transactions: clientsTransactionsContract,
|
|
40
50
|
},
|
|
41
51
|
{
|
|
42
52
|
pathPrefix: '/clients/api/v1/',
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { initContract } from '@ts-rest/core';
|
|
2
|
+
import {
|
|
3
|
+
ForbiddenError,
|
|
4
|
+
InternalError,
|
|
5
|
+
NotFoundError,
|
|
6
|
+
UnauthorizedError,
|
|
7
|
+
GetIssuerPaymentMethodZod,
|
|
8
|
+
IPaginatedIssuerPaymentMethod,
|
|
9
|
+
IssuerPaymentMethodsIncludeQuery,
|
|
10
|
+
PaginationOptionsZod,
|
|
11
|
+
} from '../../../common/types';
|
|
12
|
+
|
|
13
|
+
const c = initContract();
|
|
14
|
+
|
|
15
|
+
export const issuerPaymentMethodsContract = c.router(
|
|
16
|
+
{
|
|
17
|
+
getIssuerPaymentMethods: {
|
|
18
|
+
summary: 'Get issuer payment methods',
|
|
19
|
+
method: 'GET',
|
|
20
|
+
path: '',
|
|
21
|
+
metadata: {
|
|
22
|
+
auth: true,
|
|
23
|
+
},
|
|
24
|
+
query: PaginationOptionsZod.merge(GetIssuerPaymentMethodZod).merge(
|
|
25
|
+
IssuerPaymentMethodsIncludeQuery,
|
|
26
|
+
),
|
|
27
|
+
responses: {
|
|
28
|
+
200: IPaginatedIssuerPaymentMethod,
|
|
29
|
+
401: UnauthorizedError,
|
|
30
|
+
403: ForbiddenError,
|
|
31
|
+
404: NotFoundError,
|
|
32
|
+
500: InternalError,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pathPrefix: 'issuer-payment-methods',
|
|
38
|
+
},
|
|
39
|
+
);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { initContract } from '@ts-rest/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
UnauthorizedError,
|
|
5
|
+
ForbiddenError,
|
|
6
|
+
NotFoundError,
|
|
7
|
+
userIdSchema,
|
|
8
|
+
BadRequestError,
|
|
9
|
+
InternalError,
|
|
10
|
+
} from '../../../common/types';
|
|
11
|
+
import {
|
|
12
|
+
PaymentMethodResponseArray,
|
|
13
|
+
PaymentMethodResponse,
|
|
14
|
+
PostPaymentMethod,
|
|
15
|
+
PostSetupIntentBody,
|
|
16
|
+
SetupIntentResponse,
|
|
17
|
+
} from '../../../common/types/payment-methods.types';
|
|
18
|
+
|
|
19
|
+
const c = initContract();
|
|
20
|
+
|
|
21
|
+
export const paymentMethodsContract = c.router(
|
|
22
|
+
{
|
|
23
|
+
getPaymentMethods: {
|
|
24
|
+
summary: 'Get payment methods for a user',
|
|
25
|
+
method: 'GET',
|
|
26
|
+
path: '',
|
|
27
|
+
metadata: {
|
|
28
|
+
auth: true,
|
|
29
|
+
},
|
|
30
|
+
query: z.object({
|
|
31
|
+
userId: userIdSchema,
|
|
32
|
+
}),
|
|
33
|
+
responses: {
|
|
34
|
+
200: PaymentMethodResponseArray,
|
|
35
|
+
401: UnauthorizedError,
|
|
36
|
+
403: ForbiddenError,
|
|
37
|
+
404: NotFoundError,
|
|
38
|
+
500: InternalError,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
createPaymentMethod: {
|
|
42
|
+
summary: 'Create payment method for a user',
|
|
43
|
+
method: 'POST',
|
|
44
|
+
path: '',
|
|
45
|
+
metadata: {
|
|
46
|
+
auth: true,
|
|
47
|
+
},
|
|
48
|
+
query: z.object({
|
|
49
|
+
userId: userIdSchema,
|
|
50
|
+
}),
|
|
51
|
+
body: PostPaymentMethod,
|
|
52
|
+
responses: {
|
|
53
|
+
201: PaymentMethodResponse,
|
|
54
|
+
400: BadRequestError,
|
|
55
|
+
401: UnauthorizedError,
|
|
56
|
+
403: ForbiddenError,
|
|
57
|
+
404: NotFoundError,
|
|
58
|
+
500: InternalError,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
createSetupIntent: {
|
|
62
|
+
summary: 'Create payment method setup intent for a user',
|
|
63
|
+
method: 'POST',
|
|
64
|
+
path: '/intent',
|
|
65
|
+
metadata: {
|
|
66
|
+
auth: true,
|
|
67
|
+
},
|
|
68
|
+
query: z.object({
|
|
69
|
+
userId: userIdSchema,
|
|
70
|
+
}),
|
|
71
|
+
body: PostSetupIntentBody,
|
|
72
|
+
responses: {
|
|
73
|
+
201: SetupIntentResponse,
|
|
74
|
+
400: BadRequestError,
|
|
75
|
+
401: UnauthorizedError,
|
|
76
|
+
403: ForbiddenError,
|
|
77
|
+
404: NotFoundError,
|
|
78
|
+
500: InternalError,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
pathPrefix: 'payment-methods',
|
|
84
|
+
},
|
|
85
|
+
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { initContract } from '@ts-rest/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
BadRequestError,
|
|
5
|
+
ForbiddenError,
|
|
6
|
+
InternalError,
|
|
7
|
+
NotFoundError,
|
|
8
|
+
UnauthorizedError,
|
|
9
|
+
userIdSchema,
|
|
10
|
+
} from '../../../common/types';
|
|
11
|
+
import {
|
|
12
|
+
PostTradeLineItem,
|
|
13
|
+
TradeLineItemParams,
|
|
14
|
+
TradeLineItemQuery,
|
|
15
|
+
TradeLineItemResponse,
|
|
16
|
+
TradeLineItemUpdate,
|
|
17
|
+
} from '../../../common/types/trade-line-item.type';
|
|
18
|
+
|
|
19
|
+
const c = initContract();
|
|
20
|
+
|
|
21
|
+
export const tradeLineItemsContract = c.router(
|
|
22
|
+
{
|
|
23
|
+
postTradeLineItem: {
|
|
24
|
+
summary: 'Create Trade Line Item',
|
|
25
|
+
method: 'POST',
|
|
26
|
+
path: '/',
|
|
27
|
+
metadata: {
|
|
28
|
+
auth: true,
|
|
29
|
+
},
|
|
30
|
+
body: PostTradeLineItem,
|
|
31
|
+
query: TradeLineItemQuery.merge(
|
|
32
|
+
z.object({
|
|
33
|
+
userId: userIdSchema,
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
responses: {
|
|
37
|
+
201: TradeLineItemResponse,
|
|
38
|
+
401: UnauthorizedError,
|
|
39
|
+
403: ForbiddenError,
|
|
40
|
+
400: BadRequestError,
|
|
41
|
+
500: InternalError,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
updateTradeLineItem: {
|
|
45
|
+
summary: 'Update Trade Line Item - Can delete if you pass quantity = 0',
|
|
46
|
+
method: 'PATCH',
|
|
47
|
+
path: '/:id',
|
|
48
|
+
metadata: {
|
|
49
|
+
auth: true,
|
|
50
|
+
},
|
|
51
|
+
pathParams: TradeLineItemParams,
|
|
52
|
+
body: TradeLineItemUpdate,
|
|
53
|
+
responses: {
|
|
54
|
+
200: TradeLineItemResponse,
|
|
55
|
+
401: UnauthorizedError,
|
|
56
|
+
403: ForbiddenError,
|
|
57
|
+
404: NotFoundError,
|
|
58
|
+
500: InternalError,
|
|
59
|
+
400: BadRequestError,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
pathPrefix: 'trade-line-items',
|
|
65
|
+
},
|
|
66
|
+
);
|
|
@@ -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
|
+
);
|
|
@@ -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',
|
|
@@ -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',
|
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
IIndividualZod,
|
|
15
15
|
BadRequestError,
|
|
16
16
|
InternalError,
|
|
17
|
+
IWillDoItLaterBodySchema,
|
|
18
|
+
IWillDoItLaterResponseSchema,
|
|
17
19
|
} from '../../../common/types';
|
|
18
20
|
import { z } from 'zod';
|
|
19
21
|
|
|
@@ -92,6 +94,26 @@ export const individualsContract = c.router(
|
|
|
92
94
|
403: ForbiddenError,
|
|
93
95
|
},
|
|
94
96
|
},
|
|
97
|
+
iWillDoItLater: {
|
|
98
|
+
summary: "I'll do it later - Create a task for later completion",
|
|
99
|
+
method: 'POST',
|
|
100
|
+
path: '/:id/defer',
|
|
101
|
+
metadata: {
|
|
102
|
+
auth: true,
|
|
103
|
+
},
|
|
104
|
+
pathParams: z.object({
|
|
105
|
+
id: individualIdSchema,
|
|
106
|
+
}),
|
|
107
|
+
body: IWillDoItLaterBodySchema,
|
|
108
|
+
responses: {
|
|
109
|
+
201: IWillDoItLaterResponseSchema,
|
|
110
|
+
400: BadRequestError,
|
|
111
|
+
401: UnauthorizedError,
|
|
112
|
+
403: ForbiddenError,
|
|
113
|
+
404: NotFoundError,
|
|
114
|
+
500: InternalError,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
95
117
|
},
|
|
96
118
|
{
|
|
97
119
|
pathPrefix: 'individuals',
|
|
@@ -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',
|
|
@@ -17,9 +17,13 @@ import {
|
|
|
17
17
|
DisbursementMissingConfigZod,
|
|
18
18
|
DisbursementsIncludeQuery,
|
|
19
19
|
DisbursementsMissingConfigQuery,
|
|
20
|
+
DisbursementPreviewZod,
|
|
20
21
|
DisbursementSummaryZod,
|
|
21
22
|
DisbursementZod,
|
|
23
|
+
GetDisbursementPreviewQueryZod,
|
|
24
|
+
EligibleOfferingsFiltersZod,
|
|
22
25
|
IPaginatedDisbursement,
|
|
26
|
+
IPaginatedEligibleOffering,
|
|
23
27
|
PostDisbursementBalanceZod,
|
|
24
28
|
PostDisbursementSummaryZod,
|
|
25
29
|
PostDisbursementZod,
|
|
@@ -146,6 +150,38 @@ export const disbursementsContract = c.router(
|
|
|
146
150
|
500: InternalError,
|
|
147
151
|
},
|
|
148
152
|
},
|
|
153
|
+
getDisbursementPreview: {
|
|
154
|
+
summary: 'Get disbursement preview data for Step 2',
|
|
155
|
+
method: 'GET',
|
|
156
|
+
path: '/preview',
|
|
157
|
+
metadata: {
|
|
158
|
+
auth: true,
|
|
159
|
+
},
|
|
160
|
+
query: GetDisbursementPreviewQueryZod,
|
|
161
|
+
responses: {
|
|
162
|
+
200: DisbursementPreviewZod,
|
|
163
|
+
400: BadRequestError,
|
|
164
|
+
401: UnauthorizedError,
|
|
165
|
+
404: NotFoundError,
|
|
166
|
+
500: InternalError,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
getEligibleOfferings: {
|
|
170
|
+
summary: 'Get eligible offerings for disbursement',
|
|
171
|
+
method: 'GET',
|
|
172
|
+
path: '/eligible-offerings',
|
|
173
|
+
metadata: {
|
|
174
|
+
auth: true,
|
|
175
|
+
},
|
|
176
|
+
query: PaginationOptionsZod.merge(EligibleOfferingsFiltersZod),
|
|
177
|
+
responses: {
|
|
178
|
+
200: IPaginatedEligibleOffering,
|
|
179
|
+
401: UnauthorizedError,
|
|
180
|
+
403: ForbiddenError,
|
|
181
|
+
404: NotFoundError,
|
|
182
|
+
500: InternalError,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
149
185
|
},
|
|
150
186
|
{
|
|
151
187
|
pathPrefix: 'disbursements',
|
package/package.json
CHANGED