@dalmore/api-contracts 0.0.0-dev.56ec35b → 0.0.0-dev.582cb9c
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/disbursements.types.ts +22 -0
- 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 +1 -0
- package/common/types/issuer-offering.types.ts +2 -0
- package/common/types/offering.types.ts +2 -0
- package/contracts/investors/individuals/index.ts +22 -0
- package/contracts/issuers/disbursements/index.ts +18 -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(),
|
|
@@ -308,3 +308,25 @@ export const DisbursementSummaryZod = z.object({
|
|
|
308
308
|
amountToBeTransferred: z.number(),
|
|
309
309
|
});
|
|
310
310
|
export type DisbursementSummaryZod = z.infer<typeof DisbursementSummaryZod>;
|
|
311
|
+
|
|
312
|
+
export const EligibleOfferingZod = z.object({
|
|
313
|
+
offeringId: offeringIdSchema,
|
|
314
|
+
offeringName: z.string(),
|
|
315
|
+
availableAmount: z.number(),
|
|
316
|
+
});
|
|
317
|
+
export type EligibleOfferingZod = z.infer<typeof EligibleOfferingZod>;
|
|
318
|
+
|
|
319
|
+
export const IPaginatedEligibleOffering = z.object({
|
|
320
|
+
items: z.array(EligibleOfferingZod),
|
|
321
|
+
meta: IPaginationMeta,
|
|
322
|
+
});
|
|
323
|
+
export type IPaginatedEligibleOffering = z.infer<
|
|
324
|
+
typeof IPaginatedEligibleOffering
|
|
325
|
+
>;
|
|
326
|
+
|
|
327
|
+
export const EligibleOfferingsFiltersZod = z.object({
|
|
328
|
+
search: z.string().optional(),
|
|
329
|
+
});
|
|
330
|
+
export type EligibleOfferingsFiltersZod = z.infer<
|
|
331
|
+
typeof EligibleOfferingsFiltersZod
|
|
332
|
+
>;
|
|
@@ -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,7 @@ 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';
|
|
45
46
|
export * from './payment-methods.types';
|
|
46
47
|
|
|
47
48
|
export enum Versions {
|
|
@@ -168,6 +168,7 @@ export const PostIssuerOffering = z
|
|
|
168
168
|
.default(AssetTemplateType.STANDARD)
|
|
169
169
|
.openapi({ example: AssetTemplateType.STANDARD }),
|
|
170
170
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
171
|
+
enableBonus: z.boolean().default(false).optional(),
|
|
171
172
|
})
|
|
172
173
|
.superRefine((data, ctx) => {
|
|
173
174
|
// Check if both values are present, and if so, ensure minInvestment is less than maxInvestment
|
|
@@ -299,6 +300,7 @@ export const PatchIssuerOffering = z.object({
|
|
|
299
300
|
.optional(),
|
|
300
301
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
301
302
|
enabled: z.boolean().optional(),
|
|
303
|
+
enableBonus: z.boolean().optional(),
|
|
302
304
|
});
|
|
303
305
|
export type PatchIssuerOffering = z.infer<typeof PatchIssuerOffering>;
|
|
304
306
|
|
|
@@ -230,6 +230,7 @@ export const PatchOffering = PatchOfferingBase.merge(
|
|
|
230
230
|
.nullable()
|
|
231
231
|
.optional(),
|
|
232
232
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
233
|
+
enableBonus: z.boolean().optional(),
|
|
233
234
|
}),
|
|
234
235
|
);
|
|
235
236
|
export type PatchOffering = z.infer<typeof PatchOffering>;
|
|
@@ -276,6 +277,7 @@ export const PostComplianceOffering = PatchOfferingBase.merge(
|
|
|
276
277
|
.default(AssetTemplateType.STANDARD)
|
|
277
278
|
.openapi({ example: AssetTemplateType.STANDARD }),
|
|
278
279
|
tiers: z.array(z.number().positive()).nullable().optional(),
|
|
280
|
+
enableBonus: z.boolean().default(false).optional(),
|
|
279
281
|
}),
|
|
280
282
|
).superRefine(postAssetRefinement);
|
|
281
283
|
export type PostComplianceOffering = z.infer<typeof PostComplianceOffering>;
|
|
@@ -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',
|
|
@@ -19,7 +19,9 @@ import {
|
|
|
19
19
|
DisbursementsMissingConfigQuery,
|
|
20
20
|
DisbursementSummaryZod,
|
|
21
21
|
DisbursementZod,
|
|
22
|
+
EligibleOfferingsFiltersZod,
|
|
22
23
|
IPaginatedDisbursement,
|
|
24
|
+
IPaginatedEligibleOffering,
|
|
23
25
|
PostDisbursementBalanceZod,
|
|
24
26
|
PostDisbursementSummaryZod,
|
|
25
27
|
PostDisbursementZod,
|
|
@@ -146,6 +148,22 @@ export const disbursementsContract = c.router(
|
|
|
146
148
|
500: InternalError,
|
|
147
149
|
},
|
|
148
150
|
},
|
|
151
|
+
getEligibleOfferings: {
|
|
152
|
+
summary: 'Get eligible offerings for disbursement',
|
|
153
|
+
method: 'GET',
|
|
154
|
+
path: '/eligible-offerings',
|
|
155
|
+
metadata: {
|
|
156
|
+
auth: true,
|
|
157
|
+
},
|
|
158
|
+
query: PaginationOptionsZod.merge(EligibleOfferingsFiltersZod),
|
|
159
|
+
responses: {
|
|
160
|
+
200: IPaginatedEligibleOffering,
|
|
161
|
+
401: UnauthorizedError,
|
|
162
|
+
403: ForbiddenError,
|
|
163
|
+
404: NotFoundError,
|
|
164
|
+
500: InternalError,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
149
167
|
},
|
|
150
168
|
{
|
|
151
169
|
pathPrefix: 'disbursements',
|
package/package.json
CHANGED