@devizovaburza/mdm-sdk 1.2.5-canary.3b970ed → 1.2.5-canary.3d05b5f
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/dist/v1/index.d.mts +20 -14
- package/dist/v1/index.d.ts +20 -14
- package/dist/v1/index.mjs +444 -336
- package/package.json +7 -6
package/dist/v1/index.d.mts
CHANGED
|
@@ -3378,22 +3378,28 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3378
3378
|
};
|
|
3379
3379
|
output: {
|
|
3380
3380
|
message: string;
|
|
3381
|
-
address
|
|
3381
|
+
address: {
|
|
3382
3382
|
id: string;
|
|
3383
3383
|
partyId: string;
|
|
3384
|
+
internalId: string | null;
|
|
3384
3385
|
addressType: "PERMANENT_ADDRESS" | "REGISTERED_OFFICE" | "CONTACT_ADDRESS";
|
|
3385
|
-
street: string;
|
|
3386
|
+
street: string | null;
|
|
3387
|
+
orientationNumber: string | null;
|
|
3388
|
+
descriptiveNumber: string | null;
|
|
3386
3389
|
municipality: string;
|
|
3390
|
+
municipalityPart: string | null;
|
|
3387
3391
|
zipCode: string;
|
|
3388
|
-
district: string;
|
|
3389
|
-
region: string;
|
|
3392
|
+
district: string | null;
|
|
3393
|
+
region: string | null;
|
|
3390
3394
|
countryCode: "IM" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EC" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "US" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW";
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3395
|
+
ruianCode: string | null;
|
|
3396
|
+
createdAt: string | null;
|
|
3397
|
+
createdBy: string | null;
|
|
3398
|
+
updatedAt: string | null;
|
|
3399
|
+
updatedBy: string | null;
|
|
3400
|
+
deletedAt: string | null;
|
|
3401
|
+
deletedBy: string | null;
|
|
3402
|
+
};
|
|
3397
3403
|
};
|
|
3398
3404
|
outputFormat: "json";
|
|
3399
3405
|
status: 200;
|
|
@@ -3914,7 +3920,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3914
3920
|
owners?: {
|
|
3915
3921
|
name: string;
|
|
3916
3922
|
surname: string;
|
|
3917
|
-
email: string;
|
|
3918
3923
|
birthDate: string;
|
|
3919
3924
|
personalId: string;
|
|
3920
3925
|
gender: "M" | "F" | "OTHER";
|
|
@@ -3941,6 +3946,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3941
3946
|
id?: string | undefined;
|
|
3942
3947
|
titleBefore?: string | undefined;
|
|
3943
3948
|
titleAfter?: string | undefined;
|
|
3949
|
+
email?: string | undefined;
|
|
3944
3950
|
birthPlace?: string | undefined;
|
|
3945
3951
|
}[] | undefined;
|
|
3946
3952
|
legalRepresentatives?: {
|
|
@@ -4253,7 +4259,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4253
4259
|
owners?: {
|
|
4254
4260
|
name: string;
|
|
4255
4261
|
surname: string;
|
|
4256
|
-
email: string;
|
|
4257
4262
|
birthDate: string;
|
|
4258
4263
|
personalId: string;
|
|
4259
4264
|
gender: "M" | "F" | "OTHER";
|
|
@@ -4280,6 +4285,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4280
4285
|
id?: string | undefined;
|
|
4281
4286
|
titleBefore?: string | undefined;
|
|
4282
4287
|
titleAfter?: string | undefined;
|
|
4288
|
+
email?: string | undefined;
|
|
4283
4289
|
birthPlace?: string | undefined;
|
|
4284
4290
|
}[] | undefined;
|
|
4285
4291
|
legalRepresentatives?: {
|
|
@@ -4592,7 +4598,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4592
4598
|
owners?: {
|
|
4593
4599
|
name: string;
|
|
4594
4600
|
surname: string;
|
|
4595
|
-
email: string;
|
|
4596
4601
|
birthDate: string;
|
|
4597
4602
|
personalId: string;
|
|
4598
4603
|
gender: "M" | "F" | "OTHER";
|
|
@@ -4619,6 +4624,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4619
4624
|
id?: string | undefined;
|
|
4620
4625
|
titleBefore?: string | undefined;
|
|
4621
4626
|
titleAfter?: string | undefined;
|
|
4627
|
+
email?: string | undefined;
|
|
4622
4628
|
birthPlace?: string | undefined;
|
|
4623
4629
|
}[] | undefined;
|
|
4624
4630
|
legalRepresentatives?: {
|
|
@@ -19310,7 +19316,7 @@ declare const partyUpdateInputSchema: z.ZodObject<{
|
|
|
19310
19316
|
name: z.ZodString;
|
|
19311
19317
|
surname: z.ZodString;
|
|
19312
19318
|
titleAfter: z.ZodOptional<z.ZodString>;
|
|
19313
|
-
email: z.ZodEmail
|
|
19319
|
+
email: z.ZodOptional<z.ZodEmail>;
|
|
19314
19320
|
birthDate: z.ZodString;
|
|
19315
19321
|
birthPlace: z.ZodOptional<z.ZodString>;
|
|
19316
19322
|
personalId: z.ZodString;
|
package/dist/v1/index.d.ts
CHANGED
|
@@ -3378,22 +3378,28 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3378
3378
|
};
|
|
3379
3379
|
output: {
|
|
3380
3380
|
message: string;
|
|
3381
|
-
address
|
|
3381
|
+
address: {
|
|
3382
3382
|
id: string;
|
|
3383
3383
|
partyId: string;
|
|
3384
|
+
internalId: string | null;
|
|
3384
3385
|
addressType: "PERMANENT_ADDRESS" | "REGISTERED_OFFICE" | "CONTACT_ADDRESS";
|
|
3385
|
-
street: string;
|
|
3386
|
+
street: string | null;
|
|
3387
|
+
orientationNumber: string | null;
|
|
3388
|
+
descriptiveNumber: string | null;
|
|
3386
3389
|
municipality: string;
|
|
3390
|
+
municipalityPart: string | null;
|
|
3387
3391
|
zipCode: string;
|
|
3388
|
-
district: string;
|
|
3389
|
-
region: string;
|
|
3392
|
+
district: string | null;
|
|
3393
|
+
region: string | null;
|
|
3390
3394
|
countryCode: "IM" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EC" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "US" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW";
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3395
|
+
ruianCode: string | null;
|
|
3396
|
+
createdAt: string | null;
|
|
3397
|
+
createdBy: string | null;
|
|
3398
|
+
updatedAt: string | null;
|
|
3399
|
+
updatedBy: string | null;
|
|
3400
|
+
deletedAt: string | null;
|
|
3401
|
+
deletedBy: string | null;
|
|
3402
|
+
};
|
|
3397
3403
|
};
|
|
3398
3404
|
outputFormat: "json";
|
|
3399
3405
|
status: 200;
|
|
@@ -3914,7 +3920,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3914
3920
|
owners?: {
|
|
3915
3921
|
name: string;
|
|
3916
3922
|
surname: string;
|
|
3917
|
-
email: string;
|
|
3918
3923
|
birthDate: string;
|
|
3919
3924
|
personalId: string;
|
|
3920
3925
|
gender: "M" | "F" | "OTHER";
|
|
@@ -3941,6 +3946,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
3941
3946
|
id?: string | undefined;
|
|
3942
3947
|
titleBefore?: string | undefined;
|
|
3943
3948
|
titleAfter?: string | undefined;
|
|
3949
|
+
email?: string | undefined;
|
|
3944
3950
|
birthPlace?: string | undefined;
|
|
3945
3951
|
}[] | undefined;
|
|
3946
3952
|
legalRepresentatives?: {
|
|
@@ -4253,7 +4259,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4253
4259
|
owners?: {
|
|
4254
4260
|
name: string;
|
|
4255
4261
|
surname: string;
|
|
4256
|
-
email: string;
|
|
4257
4262
|
birthDate: string;
|
|
4258
4263
|
personalId: string;
|
|
4259
4264
|
gender: "M" | "F" | "OTHER";
|
|
@@ -4280,6 +4285,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4280
4285
|
id?: string | undefined;
|
|
4281
4286
|
titleBefore?: string | undefined;
|
|
4282
4287
|
titleAfter?: string | undefined;
|
|
4288
|
+
email?: string | undefined;
|
|
4283
4289
|
birthPlace?: string | undefined;
|
|
4284
4290
|
}[] | undefined;
|
|
4285
4291
|
legalRepresentatives?: {
|
|
@@ -4592,7 +4598,6 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4592
4598
|
owners?: {
|
|
4593
4599
|
name: string;
|
|
4594
4600
|
surname: string;
|
|
4595
|
-
email: string;
|
|
4596
4601
|
birthDate: string;
|
|
4597
4602
|
personalId: string;
|
|
4598
4603
|
gender: "M" | "F" | "OTHER";
|
|
@@ -4619,6 +4624,7 @@ declare const partnerApi: OpenAPIHono<{
|
|
|
4619
4624
|
id?: string | undefined;
|
|
4620
4625
|
titleBefore?: string | undefined;
|
|
4621
4626
|
titleAfter?: string | undefined;
|
|
4627
|
+
email?: string | undefined;
|
|
4622
4628
|
birthPlace?: string | undefined;
|
|
4623
4629
|
}[] | undefined;
|
|
4624
4630
|
legalRepresentatives?: {
|
|
@@ -19310,7 +19316,7 @@ declare const partyUpdateInputSchema: z.ZodObject<{
|
|
|
19310
19316
|
name: z.ZodString;
|
|
19311
19317
|
surname: z.ZodString;
|
|
19312
19318
|
titleAfter: z.ZodOptional<z.ZodString>;
|
|
19313
|
-
email: z.ZodEmail
|
|
19319
|
+
email: z.ZodOptional<z.ZodEmail>;
|
|
19314
19320
|
birthDate: z.ZodString;
|
|
19315
19321
|
birthPlace: z.ZodOptional<z.ZodString>;
|
|
19316
19322
|
personalId: z.ZodString;
|
package/dist/v1/index.mjs
CHANGED
|
@@ -310,6 +310,38 @@ const RISK_BUSINESS_AREA = [
|
|
|
310
310
|
"VIRTUAL_ASSET_SERVICES"
|
|
311
311
|
];
|
|
312
312
|
|
|
313
|
+
function logAuditEvent(context, input) {
|
|
314
|
+
const identity = context.get("identity");
|
|
315
|
+
const sourceIp = context.req.header("CF-Connecting-IP");
|
|
316
|
+
const correlationId = input.correlationId ?? context.get("correlationId");
|
|
317
|
+
if (!correlationId) {
|
|
318
|
+
throw new Error(
|
|
319
|
+
"logAuditEvent: missing correlationId \u2014 auditLog() middleware must be mounted before handlers that call logAuditEvent"
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
context.executionCtx.waitUntil(
|
|
323
|
+
context.env.ACTIVITY_SERVICE.logAuditEvent({
|
|
324
|
+
logType: "event",
|
|
325
|
+
service: "gateway",
|
|
326
|
+
eventType: input.eventType,
|
|
327
|
+
correlationId,
|
|
328
|
+
actorUserId: input.actorUserId ?? identity?.user?.id,
|
|
329
|
+
actorEmail: input.actorEmail ?? identity?.user?.email ?? "not-authorized@system.internal",
|
|
330
|
+
actorOrganizationId: input.actorOrganizationId ?? identity?.user?.organizationId,
|
|
331
|
+
targetType: input.targetType,
|
|
332
|
+
targetId: input.targetId,
|
|
333
|
+
outcome: input.outcome,
|
|
334
|
+
description: input.description,
|
|
335
|
+
severity: input.severity ?? "low",
|
|
336
|
+
details: input.details,
|
|
337
|
+
userAgent: context.req.header("User-Agent"),
|
|
338
|
+
...sourceIp && { sourceIp }
|
|
339
|
+
}).catch((error) => {
|
|
340
|
+
console.error(`Failed to log audit event "${input.eventType}":`, error);
|
|
341
|
+
})
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
313
345
|
z.object({
|
|
314
346
|
message: z.string(),
|
|
315
347
|
data: z.null(),
|
|
@@ -627,101 +659,211 @@ const createPartyRoute = createRoute({
|
|
|
627
659
|
...errorResponse("Party", "Creation")
|
|
628
660
|
}
|
|
629
661
|
});
|
|
630
|
-
new OpenAPIHono().openapi(
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
)
|
|
637
|
-
|
|
638
|
-
|
|
662
|
+
new OpenAPIHono().openapi(createPartyRoute, async (context) => {
|
|
663
|
+
const { owners, legalRepresentatives, ...partyInput } = context.req.valid("json");
|
|
664
|
+
const disponentsWithDocs = (partyInput.disponents ?? []).filter(
|
|
665
|
+
(d) => d.partyType === "INDIVIDUAL" && !!d.data.identityDocuments?.length
|
|
666
|
+
);
|
|
667
|
+
const disponentsForBatch = (partyInput.disponents ?? []).filter(
|
|
668
|
+
(d) => !(d.partyType === "INDIVIDUAL" && !!d.data.identityDocuments?.length)
|
|
669
|
+
);
|
|
670
|
+
const { data: partyData, error } = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.createParty({
|
|
671
|
+
...partyInput,
|
|
672
|
+
disponents: disponentsForBatch,
|
|
673
|
+
party: { ...partyInput.party, isRoot: true }
|
|
674
|
+
});
|
|
675
|
+
if (!partyData || error) {
|
|
676
|
+
logAuditEvent(context, {
|
|
677
|
+
eventType: "party.created",
|
|
678
|
+
targetType: "party",
|
|
679
|
+
outcome: "failure",
|
|
680
|
+
severity: "medium",
|
|
681
|
+
description: "Failed to create party",
|
|
682
|
+
details: { partyType: partyInput.party.partyType }
|
|
683
|
+
});
|
|
684
|
+
return context.json(
|
|
685
|
+
{
|
|
686
|
+
message: "Could not create a party"
|
|
687
|
+
},
|
|
688
|
+
500
|
|
639
689
|
);
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
690
|
+
}
|
|
691
|
+
const mdm = context.env.MASTER_DATA_MANAGEMENT_SERVICE;
|
|
692
|
+
const docService = context.env.DOCUMENT_SERVICE;
|
|
693
|
+
if (partyInput.organizationData?.registerUri) {
|
|
694
|
+
await docService.acknowledgeDocument({
|
|
695
|
+
storageUrl: partyInput.organizationData.registerUri,
|
|
696
|
+
entityId: partyData.id
|
|
644
697
|
});
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
message: "Could not create a party"
|
|
649
|
-
},
|
|
650
|
-
500
|
|
651
|
-
);
|
|
652
|
-
}
|
|
653
|
-
const mdm = context.env.MASTER_DATA_MANAGEMENT_SERVICE;
|
|
654
|
-
const docService = context.env.DOCUMENT_SERVICE;
|
|
655
|
-
if (partyInput.organizationData?.registerUri) {
|
|
698
|
+
}
|
|
699
|
+
for (const ba of partyInput.bankAccounts ?? []) {
|
|
700
|
+
if (ba.statementUri) {
|
|
656
701
|
await docService.acknowledgeDocument({
|
|
657
|
-
storageUrl:
|
|
702
|
+
storageUrl: ba.statementUri,
|
|
658
703
|
entityId: partyData.id
|
|
659
704
|
});
|
|
660
705
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
706
|
+
}
|
|
707
|
+
for (const [i, doc] of (partyInput.personalData?.identityDocuments ?? []).entries()) {
|
|
708
|
+
const idDocId = partyData.personalIdDocIds?.[i] ?? partyData.id;
|
|
709
|
+
if (doc.frontImageUri) {
|
|
710
|
+
await docService.acknowledgeDocument({
|
|
711
|
+
storageUrl: doc.frontImageUri,
|
|
712
|
+
entityId: idDocId
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
if (doc.backImageUri) {
|
|
716
|
+
await docService.acknowledgeDocument({
|
|
717
|
+
storageUrl: doc.backImageUri,
|
|
718
|
+
entityId: idDocId
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
for (const disponent of disponentsWithDocs) {
|
|
723
|
+
const { identityDocuments, ...individualData } = disponent.data;
|
|
724
|
+
const { data: disponentParty, error: disponentError } = await mdm.createParty({
|
|
725
|
+
party: {
|
|
726
|
+
partyType: "INDIVIDUAL",
|
|
727
|
+
language: partyInput.party.language,
|
|
728
|
+
customerStatus: "NEW"
|
|
729
|
+
},
|
|
730
|
+
personalData: individualData,
|
|
731
|
+
organizationData: null,
|
|
732
|
+
bankAccounts: null,
|
|
733
|
+
recipients: null,
|
|
734
|
+
disponents: null,
|
|
735
|
+
addresses: [],
|
|
736
|
+
aml: null
|
|
737
|
+
});
|
|
738
|
+
if (!disponentParty || disponentError) {
|
|
739
|
+
return context.json({ message: "Could not create disponent party" }, 500);
|
|
740
|
+
}
|
|
741
|
+
const { error: linkDisponentError } = await mdm.linkPartyToParty({
|
|
742
|
+
fromPartyId: disponentParty.id,
|
|
743
|
+
toPartyId: partyData.id,
|
|
744
|
+
relationshipType: "AUTHORIZED_SIGNATORY"
|
|
745
|
+
});
|
|
746
|
+
if (linkDisponentError) {
|
|
747
|
+
return context.json({ message: "Could not link disponent to party" }, 500);
|
|
668
748
|
}
|
|
669
|
-
for (const
|
|
670
|
-
const
|
|
749
|
+
for (const doc of identityDocuments ?? []) {
|
|
750
|
+
const { data: createdIdDoc, error: idDocError } = await mdm.createIdDocument({
|
|
751
|
+
partyId: disponentParty.id,
|
|
752
|
+
idDocument: {
|
|
753
|
+
partyId: disponentParty.id,
|
|
754
|
+
idDocType: doc.idDocType,
|
|
755
|
+
idDocNumber: doc.idDocNumber,
|
|
756
|
+
idDocHolderName: `${individualData.name} ${individualData.surname}`,
|
|
757
|
+
issueDate: doc.issueDate,
|
|
758
|
+
expirationDate: doc.expirationDate,
|
|
759
|
+
issuer: doc.issuer,
|
|
760
|
+
frontImageUri: doc.frontImageUri,
|
|
761
|
+
backImageUri: doc.backImageUri
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
if (!createdIdDoc || idDocError) {
|
|
765
|
+
return context.json(
|
|
766
|
+
{ message: "Could not create disponent identity document" },
|
|
767
|
+
500
|
|
768
|
+
);
|
|
769
|
+
}
|
|
671
770
|
if (doc.frontImageUri) {
|
|
672
771
|
await docService.acknowledgeDocument({
|
|
673
772
|
storageUrl: doc.frontImageUri,
|
|
674
|
-
entityId:
|
|
773
|
+
entityId: createdIdDoc.id
|
|
675
774
|
});
|
|
676
775
|
}
|
|
677
776
|
if (doc.backImageUri) {
|
|
678
777
|
await docService.acknowledgeDocument({
|
|
679
778
|
storageUrl: doc.backImageUri,
|
|
680
|
-
entityId:
|
|
779
|
+
entityId: createdIdDoc.id
|
|
681
780
|
});
|
|
682
781
|
}
|
|
683
782
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
783
|
+
}
|
|
784
|
+
if (owners?.length) {
|
|
785
|
+
for (const owner of owners) {
|
|
786
|
+
const { address, sharePercentage, shareEstablishedAt, ...individual } = owner;
|
|
787
|
+
const { data: ownerParty, error: ownerError } = await mdm.createParty({
|
|
687
788
|
party: {
|
|
688
789
|
partyType: "INDIVIDUAL",
|
|
689
790
|
language: partyInput.party.language,
|
|
690
791
|
customerStatus: "NEW"
|
|
691
792
|
},
|
|
692
|
-
personalData:
|
|
793
|
+
personalData: { ...individual, email: individual.email ?? "" },
|
|
693
794
|
organizationData: null,
|
|
694
795
|
bankAccounts: null,
|
|
695
796
|
recipients: null,
|
|
696
797
|
disponents: null,
|
|
697
|
-
addresses: [
|
|
798
|
+
addresses: [
|
|
799
|
+
{
|
|
800
|
+
...address,
|
|
801
|
+
district: address.district ?? "",
|
|
802
|
+
region: address.region ?? ""
|
|
803
|
+
}
|
|
804
|
+
],
|
|
698
805
|
aml: null
|
|
699
806
|
});
|
|
700
|
-
if (
|
|
807
|
+
if (ownerParty && !ownerError) {
|
|
808
|
+
await mdm.linkPartyToParty({
|
|
809
|
+
fromPartyId: ownerParty.id,
|
|
810
|
+
toPartyId: partyData.id,
|
|
811
|
+
relationshipType: "UBO",
|
|
812
|
+
sharePercentage,
|
|
813
|
+
fromDate: new Date(shareEstablishedAt)
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
if (legalRepresentatives?.length) {
|
|
819
|
+
for (const rep of legalRepresentatives) {
|
|
820
|
+
const { address, identityDocuments, dateOfEstablishment, ...individual } = rep;
|
|
821
|
+
const { data: repParty, error: repError } = await mdm.createParty({
|
|
822
|
+
party: {
|
|
823
|
+
partyType: "INDIVIDUAL",
|
|
824
|
+
language: partyInput.party.language,
|
|
825
|
+
customerStatus: "NEW"
|
|
826
|
+
},
|
|
827
|
+
personalData: individual,
|
|
828
|
+
organizationData: null,
|
|
829
|
+
bankAccounts: null,
|
|
830
|
+
recipients: null,
|
|
831
|
+
disponents: null,
|
|
832
|
+
addresses: [
|
|
833
|
+
{
|
|
834
|
+
...address,
|
|
835
|
+
district: address.district ?? "",
|
|
836
|
+
region: address.region ?? ""
|
|
837
|
+
}
|
|
838
|
+
],
|
|
839
|
+
aml: null
|
|
840
|
+
});
|
|
841
|
+
if (!repParty || repError) {
|
|
701
842
|
return context.json(
|
|
702
|
-
{ message: "Could not create
|
|
843
|
+
{ message: "Could not create legal representative party" },
|
|
703
844
|
500
|
|
704
845
|
);
|
|
705
846
|
}
|
|
706
|
-
const { error:
|
|
707
|
-
fromPartyId:
|
|
847
|
+
const { error: linkRepError } = await mdm.linkPartyToParty({
|
|
848
|
+
fromPartyId: repParty.id,
|
|
708
849
|
toPartyId: partyData.id,
|
|
709
|
-
relationshipType: "
|
|
850
|
+
relationshipType: "BOARD_MEMBER",
|
|
851
|
+
fromDate: new Date(dateOfEstablishment)
|
|
710
852
|
});
|
|
711
|
-
if (
|
|
853
|
+
if (linkRepError) {
|
|
712
854
|
return context.json(
|
|
713
|
-
{ message: "Could not link
|
|
855
|
+
{ message: "Could not link legal representative to party" },
|
|
714
856
|
500
|
|
715
857
|
);
|
|
716
858
|
}
|
|
717
859
|
for (const doc of identityDocuments ?? []) {
|
|
718
860
|
const { data: createdIdDoc, error: idDocError } = await mdm.createIdDocument({
|
|
719
|
-
partyId:
|
|
861
|
+
partyId: repParty.id,
|
|
720
862
|
idDocument: {
|
|
721
|
-
partyId:
|
|
863
|
+
partyId: repParty.id,
|
|
722
864
|
idDocType: doc.idDocType,
|
|
723
865
|
idDocNumber: doc.idDocNumber,
|
|
724
|
-
idDocHolderName: `${
|
|
866
|
+
idDocHolderName: `${individual.name} ${individual.surname}`,
|
|
725
867
|
issueDate: doc.issueDate,
|
|
726
868
|
expirationDate: doc.expirationDate,
|
|
727
869
|
issuer: doc.issuer,
|
|
@@ -731,7 +873,9 @@ new OpenAPIHono().openapi(
|
|
|
731
873
|
});
|
|
732
874
|
if (!createdIdDoc || idDocError) {
|
|
733
875
|
return context.json(
|
|
734
|
-
{
|
|
876
|
+
{
|
|
877
|
+
message: "Could not create legal representative identity document"
|
|
878
|
+
},
|
|
735
879
|
500
|
|
736
880
|
);
|
|
737
881
|
}
|
|
@@ -749,133 +893,30 @@ new OpenAPIHono().openapi(
|
|
|
749
893
|
}
|
|
750
894
|
}
|
|
751
895
|
}
|
|
752
|
-
if (owners?.length) {
|
|
753
|
-
for (const owner of owners) {
|
|
754
|
-
const { address, sharePercentage, shareEstablishedAt, ...individual } = owner;
|
|
755
|
-
const { data: ownerParty, error: ownerError } = await mdm.createParty({
|
|
756
|
-
party: {
|
|
757
|
-
partyType: "INDIVIDUAL",
|
|
758
|
-
language: partyInput.party.language,
|
|
759
|
-
customerStatus: "NEW"
|
|
760
|
-
},
|
|
761
|
-
personalData: { ...individual, email: individual.email ?? "" },
|
|
762
|
-
organizationData: null,
|
|
763
|
-
bankAccounts: null,
|
|
764
|
-
recipients: null,
|
|
765
|
-
disponents: null,
|
|
766
|
-
addresses: [
|
|
767
|
-
{
|
|
768
|
-
...address,
|
|
769
|
-
district: address.district ?? "",
|
|
770
|
-
region: address.region ?? ""
|
|
771
|
-
}
|
|
772
|
-
],
|
|
773
|
-
aml: null
|
|
774
|
-
});
|
|
775
|
-
if (ownerParty && !ownerError) {
|
|
776
|
-
await mdm.linkPartyToParty({
|
|
777
|
-
fromPartyId: ownerParty.id,
|
|
778
|
-
toPartyId: partyData.id,
|
|
779
|
-
relationshipType: "UBO",
|
|
780
|
-
sharePercentage,
|
|
781
|
-
fromDate: new Date(shareEstablishedAt)
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
if (legalRepresentatives?.length) {
|
|
787
|
-
for (const rep of legalRepresentatives) {
|
|
788
|
-
const {
|
|
789
|
-
address,
|
|
790
|
-
identityDocuments,
|
|
791
|
-
dateOfEstablishment,
|
|
792
|
-
...individual
|
|
793
|
-
} = rep;
|
|
794
|
-
const { data: repParty, error: repError } = await mdm.createParty({
|
|
795
|
-
party: {
|
|
796
|
-
partyType: "INDIVIDUAL",
|
|
797
|
-
language: partyInput.party.language,
|
|
798
|
-
customerStatus: "NEW"
|
|
799
|
-
},
|
|
800
|
-
personalData: individual,
|
|
801
|
-
organizationData: null,
|
|
802
|
-
bankAccounts: null,
|
|
803
|
-
recipients: null,
|
|
804
|
-
disponents: null,
|
|
805
|
-
addresses: [
|
|
806
|
-
{
|
|
807
|
-
...address,
|
|
808
|
-
district: address.district ?? "",
|
|
809
|
-
region: address.region ?? ""
|
|
810
|
-
}
|
|
811
|
-
],
|
|
812
|
-
aml: null
|
|
813
|
-
});
|
|
814
|
-
if (!repParty || repError) {
|
|
815
|
-
return context.json(
|
|
816
|
-
{ message: "Could not create legal representative party" },
|
|
817
|
-
500
|
|
818
|
-
);
|
|
819
|
-
}
|
|
820
|
-
const { error: linkRepError } = await mdm.linkPartyToParty({
|
|
821
|
-
fromPartyId: repParty.id,
|
|
822
|
-
toPartyId: partyData.id,
|
|
823
|
-
relationshipType: "BOARD_MEMBER",
|
|
824
|
-
fromDate: new Date(dateOfEstablishment)
|
|
825
|
-
});
|
|
826
|
-
if (linkRepError) {
|
|
827
|
-
return context.json(
|
|
828
|
-
{ message: "Could not link legal representative to party" },
|
|
829
|
-
500
|
|
830
|
-
);
|
|
831
|
-
}
|
|
832
|
-
for (const doc of identityDocuments ?? []) {
|
|
833
|
-
const { data: createdIdDoc, error: idDocError } = await mdm.createIdDocument({
|
|
834
|
-
partyId: repParty.id,
|
|
835
|
-
idDocument: {
|
|
836
|
-
partyId: repParty.id,
|
|
837
|
-
idDocType: doc.idDocType,
|
|
838
|
-
idDocNumber: doc.idDocNumber,
|
|
839
|
-
idDocHolderName: `${individual.name} ${individual.surname}`,
|
|
840
|
-
issueDate: doc.issueDate,
|
|
841
|
-
expirationDate: doc.expirationDate,
|
|
842
|
-
issuer: doc.issuer,
|
|
843
|
-
frontImageUri: doc.frontImageUri,
|
|
844
|
-
backImageUri: doc.backImageUri
|
|
845
|
-
}
|
|
846
|
-
});
|
|
847
|
-
if (!createdIdDoc || idDocError) {
|
|
848
|
-
return context.json(
|
|
849
|
-
{
|
|
850
|
-
message: "Could not create legal representative identity document"
|
|
851
|
-
},
|
|
852
|
-
500
|
|
853
|
-
);
|
|
854
|
-
}
|
|
855
|
-
if (doc.frontImageUri) {
|
|
856
|
-
await docService.acknowledgeDocument({
|
|
857
|
-
storageUrl: doc.frontImageUri,
|
|
858
|
-
entityId: createdIdDoc.id
|
|
859
|
-
});
|
|
860
|
-
}
|
|
861
|
-
if (doc.backImageUri) {
|
|
862
|
-
await docService.acknowledgeDocument({
|
|
863
|
-
storageUrl: doc.backImageUri,
|
|
864
|
-
entityId: createdIdDoc.id
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
return context.json(
|
|
871
|
-
{
|
|
872
|
-
message: "party created",
|
|
873
|
-
party: partyData
|
|
874
|
-
},
|
|
875
|
-
200
|
|
876
|
-
);
|
|
877
896
|
}
|
|
878
|
-
|
|
897
|
+
logAuditEvent(context, {
|
|
898
|
+
eventType: "party.created",
|
|
899
|
+
targetType: "party",
|
|
900
|
+
targetId: partyData.id,
|
|
901
|
+
outcome: "success",
|
|
902
|
+
severity: "medium",
|
|
903
|
+
description: `Party ${partyData.id} created`,
|
|
904
|
+
details: {
|
|
905
|
+
partyType: partyInput.party.partyType,
|
|
906
|
+
disponentCount: partyInput.disponents?.length ?? 0,
|
|
907
|
+
bankAccountCount: partyInput.bankAccounts?.length ?? 0,
|
|
908
|
+
ownerCount: owners?.length ?? 0,
|
|
909
|
+
legalRepresentativeCount: legalRepresentatives?.length ?? 0
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
return context.json(
|
|
913
|
+
{
|
|
914
|
+
message: "party created",
|
|
915
|
+
party: partyData
|
|
916
|
+
},
|
|
917
|
+
200
|
|
918
|
+
);
|
|
919
|
+
});
|
|
879
920
|
|
|
880
921
|
const partySchema = z.object({
|
|
881
922
|
partyType: z.enum(PARTY_TYPE),
|
|
@@ -1091,7 +1132,7 @@ const ownerSyncSchema = z.object({
|
|
|
1091
1132
|
name: z.string(),
|
|
1092
1133
|
surname: z.string(),
|
|
1093
1134
|
titleAfter: z.string().optional(),
|
|
1094
|
-
email: z.email("E-mail je povinn\xFD"),
|
|
1135
|
+
email: z.email("E-mail je povinn\xFD").optional(),
|
|
1095
1136
|
birthDate: z.string(),
|
|
1096
1137
|
birthPlace: z.string().optional(),
|
|
1097
1138
|
personalId: z.string(),
|
|
@@ -1181,48 +1222,75 @@ const updatePartyRoute = createRoute({
|
|
|
1181
1222
|
...errorResponse("Party", "Update")
|
|
1182
1223
|
}
|
|
1183
1224
|
});
|
|
1184
|
-
new OpenAPIHono().openapi(
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1225
|
+
new OpenAPIHono().openapi(updatePartyRoute, async (context) => {
|
|
1226
|
+
const party = context.req.valid("json");
|
|
1227
|
+
const { partyId } = context.req.valid("param");
|
|
1228
|
+
const { data: updatedParty, error: partyError } = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.updateParty({
|
|
1229
|
+
partyId,
|
|
1230
|
+
party: party.party,
|
|
1231
|
+
personalData: party.personalData ?? void 0,
|
|
1232
|
+
organizationData: party.organizationData ?? void 0,
|
|
1233
|
+
bankAccounts: party.bankAccounts ?? void 0,
|
|
1234
|
+
disponents: party.disponents ?? void 0,
|
|
1235
|
+
addresses: party.addresses ?? void 0,
|
|
1236
|
+
recipients: party.recipients ?? void 0,
|
|
1237
|
+
aml: party.aml ?? void 0,
|
|
1238
|
+
products: party.products ?? void 0,
|
|
1239
|
+
traderIds: party.traderIds ?? void 0,
|
|
1240
|
+
legalRepresentatives: party.legalRepresentatives ?? void 0,
|
|
1241
|
+
owners: party.owners ?? void 0
|
|
1242
|
+
});
|
|
1243
|
+
if (!updatedParty || partyError) {
|
|
1244
|
+
logAuditEvent(context, {
|
|
1245
|
+
eventType: "party.updated",
|
|
1246
|
+
targetType: "party",
|
|
1247
|
+
targetId: partyId,
|
|
1248
|
+
outcome: "failure",
|
|
1249
|
+
severity: "medium",
|
|
1250
|
+
description: `Failed to update party ${partyId}`,
|
|
1251
|
+
details: { partyType: party.party.partyType }
|
|
1203
1252
|
});
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1253
|
+
return context.json({ message: "Could not update a Party" }, 404);
|
|
1254
|
+
}
|
|
1255
|
+
const docService = context.env.DOCUMENT_SERVICE;
|
|
1256
|
+
if (party.organizationData?.registerUri) {
|
|
1257
|
+
await docService.acknowledgeDocument({
|
|
1258
|
+
storageUrl: party.organizationData.registerUri,
|
|
1259
|
+
entityId: partyId
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
for (const ba of party.bankAccounts ?? []) {
|
|
1263
|
+
if (ba.statementUri) {
|
|
1209
1264
|
await docService.acknowledgeDocument({
|
|
1210
|
-
storageUrl:
|
|
1265
|
+
storageUrl: ba.statementUri,
|
|
1211
1266
|
entityId: partyId
|
|
1212
1267
|
});
|
|
1213
1268
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1269
|
+
}
|
|
1270
|
+
if (party.personalData?.identityDocuments?.length) {
|
|
1271
|
+
let newDocIdx = 0;
|
|
1272
|
+
for (const doc of party.personalData.identityDocuments) {
|
|
1273
|
+
const idDocEntityId = doc.id ? doc.id : updatedParty.newPersonalIdDocIds?.[newDocIdx++] ?? partyId;
|
|
1274
|
+
if (doc.frontImageUri) {
|
|
1216
1275
|
await docService.acknowledgeDocument({
|
|
1217
|
-
storageUrl:
|
|
1218
|
-
entityId:
|
|
1276
|
+
storageUrl: doc.frontImageUri,
|
|
1277
|
+
entityId: idDocEntityId
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
if (doc.backImageUri) {
|
|
1281
|
+
await docService.acknowledgeDocument({
|
|
1282
|
+
storageUrl: doc.backImageUri,
|
|
1283
|
+
entityId: idDocEntityId
|
|
1219
1284
|
});
|
|
1220
1285
|
}
|
|
1221
1286
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1287
|
+
}
|
|
1288
|
+
if (party.legalRepresentatives?.length) {
|
|
1289
|
+
let newBmDocIdx = 0;
|
|
1290
|
+
for (const rep of party.legalRepresentatives) {
|
|
1291
|
+
if (rep.id) continue;
|
|
1292
|
+
for (const doc of rep.identityDocuments ?? []) {
|
|
1293
|
+
const idDocEntityId = updatedParty.newBoardMemberIdDocIds?.[newBmDocIdx++] ?? partyId;
|
|
1226
1294
|
if (doc.frontImageUri) {
|
|
1227
1295
|
await docService.acknowledgeDocument({
|
|
1228
1296
|
storageUrl: doc.frontImageUri,
|
|
@@ -1237,54 +1305,45 @@ new OpenAPIHono().openapi(
|
|
|
1237
1305
|
}
|
|
1238
1306
|
}
|
|
1239
1307
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
for (const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
entityId: idDocEntityId
|
|
1250
|
-
});
|
|
1251
|
-
}
|
|
1252
|
-
if (doc.backImageUri) {
|
|
1253
|
-
await docService.acknowledgeDocument({
|
|
1254
|
-
storageUrl: doc.backImageUri,
|
|
1255
|
-
entityId: idDocEntityId
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1308
|
+
for (const rep of party.legalRepresentatives) {
|
|
1309
|
+
if (!rep.id) continue;
|
|
1310
|
+
for (const doc of rep.identityDocuments ?? []) {
|
|
1311
|
+
const idDocEntityId = doc.id ? doc.id : updatedParty.newBoardMemberIdDocIds?.[newBmDocIdx++] ?? partyId;
|
|
1312
|
+
if (doc.frontImageUri) {
|
|
1313
|
+
await docService.acknowledgeDocument({
|
|
1314
|
+
storageUrl: doc.frontImageUri,
|
|
1315
|
+
entityId: idDocEntityId
|
|
1316
|
+
});
|
|
1258
1317
|
}
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
if (doc.frontImageUri) {
|
|
1265
|
-
await docService.acknowledgeDocument({
|
|
1266
|
-
storageUrl: doc.frontImageUri,
|
|
1267
|
-
entityId: idDocEntityId
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1270
|
-
if (doc.backImageUri) {
|
|
1271
|
-
await docService.acknowledgeDocument({
|
|
1272
|
-
storageUrl: doc.backImageUri,
|
|
1273
|
-
entityId: idDocEntityId
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1318
|
+
if (doc.backImageUri) {
|
|
1319
|
+
await docService.acknowledgeDocument({
|
|
1320
|
+
storageUrl: doc.backImageUri,
|
|
1321
|
+
entityId: idDocEntityId
|
|
1322
|
+
});
|
|
1276
1323
|
}
|
|
1277
1324
|
}
|
|
1278
1325
|
}
|
|
1279
|
-
return context.json(
|
|
1280
|
-
{
|
|
1281
|
-
message: "Party updated successfully",
|
|
1282
|
-
party: updatedParty
|
|
1283
|
-
},
|
|
1284
|
-
200
|
|
1285
|
-
);
|
|
1286
1326
|
}
|
|
1287
|
-
|
|
1327
|
+
logAuditEvent(context, {
|
|
1328
|
+
eventType: "party.updated",
|
|
1329
|
+
targetType: "party",
|
|
1330
|
+
targetId: partyId,
|
|
1331
|
+
outcome: "success",
|
|
1332
|
+
severity: "medium",
|
|
1333
|
+
description: `Party ${partyId} updated`,
|
|
1334
|
+
details: {
|
|
1335
|
+
partyType: party.party.partyType,
|
|
1336
|
+
customerStatus: updatedParty.customerStatus
|
|
1337
|
+
}
|
|
1338
|
+
});
|
|
1339
|
+
return context.json(
|
|
1340
|
+
{
|
|
1341
|
+
message: "Party updated successfully",
|
|
1342
|
+
party: updatedParty
|
|
1343
|
+
},
|
|
1344
|
+
200
|
|
1345
|
+
);
|
|
1346
|
+
});
|
|
1288
1347
|
|
|
1289
1348
|
const DOCUMENT_SIDE = ["front", "back"];
|
|
1290
1349
|
const paramsSchema$2 = z.object({
|
|
@@ -1388,64 +1447,91 @@ const createDocumentRoute = createRoute({
|
|
|
1388
1447
|
}
|
|
1389
1448
|
}
|
|
1390
1449
|
});
|
|
1391
|
-
new OpenAPIHono().openapi(
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1450
|
+
new OpenAPIHono().openapi(createDocumentRoute, async (context) => {
|
|
1451
|
+
const rawBody = await context.req.parseBody();
|
|
1452
|
+
const { partyId } = context.req.valid("param");
|
|
1453
|
+
const idDocumentRaw = rawBody.idDocument;
|
|
1454
|
+
const documentSide = rawBody.documentSide;
|
|
1455
|
+
const file = rawBody.file;
|
|
1456
|
+
if (typeof idDocumentRaw !== "string" || !DOCUMENT_SIDE.includes(documentSide) || !(file instanceof File)) {
|
|
1457
|
+
return context.json({ message: "Invalid multipart payload" }, 400);
|
|
1458
|
+
}
|
|
1459
|
+
const idDocumentJson = JSON.parse(JSON.parse(idDocumentRaw));
|
|
1460
|
+
const idDocumentResult = idDocumentCreateInputSchema.safeParse(idDocumentJson);
|
|
1461
|
+
if (!idDocumentResult.success) {
|
|
1462
|
+
console.error(idDocumentResult.error);
|
|
1463
|
+
return context.json({ message: "Could not parse IdDocument" }, 400);
|
|
1464
|
+
}
|
|
1465
|
+
const {
|
|
1466
|
+
data: createdIdDocument,
|
|
1467
|
+
error: createError,
|
|
1468
|
+
message
|
|
1469
|
+
} = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.createIdDocument({
|
|
1470
|
+
idDocument: idDocumentResult.data,
|
|
1471
|
+
partyId
|
|
1472
|
+
});
|
|
1473
|
+
if (!createdIdDocument || createError) {
|
|
1474
|
+
console.error(message);
|
|
1475
|
+
logAuditEvent(context, {
|
|
1476
|
+
eventType: "id-document.created",
|
|
1477
|
+
targetType: "id-document",
|
|
1478
|
+
outcome: "failure",
|
|
1479
|
+
severity: "medium",
|
|
1480
|
+
description: `Failed to create ID document for party ${partyId}`,
|
|
1481
|
+
details: { partyId, idDocType: idDocumentResult.data.idDocType }
|
|
1415
1482
|
});
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1483
|
+
return context.json({ message: "Could not create IdDocument" }, 500);
|
|
1484
|
+
}
|
|
1485
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
1486
|
+
const { data: uploadResult, error: uploadError } = await context.env.DOCUMENT_SERVICE.uploadDocument({
|
|
1487
|
+
entityType: "client",
|
|
1488
|
+
entityId: createdIdDocument.id,
|
|
1489
|
+
type: "kyc",
|
|
1490
|
+
metadata: {},
|
|
1491
|
+
file: {
|
|
1492
|
+
bytes,
|
|
1493
|
+
type: file.type,
|
|
1494
|
+
name: file.name,
|
|
1495
|
+
size: file.size
|
|
1419
1496
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
size: file.size
|
|
1431
|
-
}
|
|
1497
|
+
});
|
|
1498
|
+
if (!uploadResult || uploadError) {
|
|
1499
|
+
logAuditEvent(context, {
|
|
1500
|
+
eventType: "id-document.created",
|
|
1501
|
+
targetType: "id-document",
|
|
1502
|
+
targetId: createdIdDocument.id,
|
|
1503
|
+
outcome: "error",
|
|
1504
|
+
severity: "medium",
|
|
1505
|
+
description: `ID document ${createdIdDocument.id} created but file upload failed`,
|
|
1506
|
+
details: { partyId, documentSide }
|
|
1432
1507
|
});
|
|
1433
|
-
|
|
1434
|
-
return context.json({ message: "File upload failed" }, 500);
|
|
1435
|
-
}
|
|
1436
|
-
return context.json(
|
|
1437
|
-
{
|
|
1438
|
-
message: "IdDocument created successfully",
|
|
1439
|
-
idDocument: {
|
|
1440
|
-
...createdIdDocument,
|
|
1441
|
-
frontImageUri: documentSide === "front" ? uploadResult.storageUrl : createdIdDocument.frontImageUri,
|
|
1442
|
-
backImageUri: documentSide === "back" ? uploadResult.storageUrl : createdIdDocument.backImageUri
|
|
1443
|
-
}
|
|
1444
|
-
},
|
|
1445
|
-
200
|
|
1446
|
-
);
|
|
1508
|
+
return context.json({ message: "File upload failed" }, 500);
|
|
1447
1509
|
}
|
|
1448
|
-
|
|
1510
|
+
logAuditEvent(context, {
|
|
1511
|
+
eventType: "id-document.created",
|
|
1512
|
+
targetType: "id-document",
|
|
1513
|
+
targetId: createdIdDocument.id,
|
|
1514
|
+
outcome: "success",
|
|
1515
|
+
severity: "medium",
|
|
1516
|
+
description: `ID document ${createdIdDocument.id} created for party ${partyId}`,
|
|
1517
|
+
details: {
|
|
1518
|
+
partyId,
|
|
1519
|
+
idDocType: createdIdDocument.idDocType,
|
|
1520
|
+
documentSide
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1523
|
+
return context.json(
|
|
1524
|
+
{
|
|
1525
|
+
message: "IdDocument created successfully",
|
|
1526
|
+
idDocument: {
|
|
1527
|
+
...createdIdDocument,
|
|
1528
|
+
frontImageUri: documentSide === "front" ? uploadResult.storageUrl : createdIdDocument.frontImageUri,
|
|
1529
|
+
backImageUri: documentSide === "back" ? uploadResult.storageUrl : createdIdDocument.backImageUri
|
|
1530
|
+
}
|
|
1531
|
+
},
|
|
1532
|
+
200
|
|
1533
|
+
);
|
|
1534
|
+
});
|
|
1449
1535
|
|
|
1450
1536
|
const partyBaseOutputSchema = z.object({
|
|
1451
1537
|
customerStatus: z.enum(CUSTOMER_STATUS),
|
|
@@ -1960,35 +2046,57 @@ const updateIdDocumentRoute = createRoute({
|
|
|
1960
2046
|
}
|
|
1961
2047
|
}
|
|
1962
2048
|
});
|
|
1963
|
-
new OpenAPIHono().openapi(
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
id
|
|
1976
|
-
};
|
|
1977
|
-
const { data: updatedIdDocument, error: updateError } = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.updateIdDocument({
|
|
1978
|
-
idDocument: fullIdDocument
|
|
2049
|
+
new OpenAPIHono().openapi(updateIdDocumentRoute, async (context) => {
|
|
2050
|
+
const { id } = context.req.valid("param");
|
|
2051
|
+
const patch = context.req.valid("json");
|
|
2052
|
+
const { data: existingDocument, error: fetchError } = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.getIdDocument({ id });
|
|
2053
|
+
if (!existingDocument || fetchError) {
|
|
2054
|
+
logAuditEvent(context, {
|
|
2055
|
+
eventType: "id-document.updated",
|
|
2056
|
+
targetType: "id-document",
|
|
2057
|
+
targetId: id,
|
|
2058
|
+
outcome: "failure",
|
|
2059
|
+
severity: "medium",
|
|
2060
|
+
description: `Failed to update ID document ${id}: not found`
|
|
1979
2061
|
});
|
|
1980
|
-
|
|
1981
|
-
return context.json({ message: "Could not update ID document" }, 500);
|
|
1982
|
-
}
|
|
1983
|
-
return context.json(
|
|
1984
|
-
{
|
|
1985
|
-
message: "ID document updated successfully",
|
|
1986
|
-
idDocument: updatedIdDocument
|
|
1987
|
-
},
|
|
1988
|
-
200
|
|
1989
|
-
);
|
|
2062
|
+
return context.json({ message: "ID document not found" }, 404);
|
|
1990
2063
|
}
|
|
1991
|
-
|
|
2064
|
+
const fullIdDocument = {
|
|
2065
|
+
...existingDocument,
|
|
2066
|
+
...patch,
|
|
2067
|
+
id
|
|
2068
|
+
};
|
|
2069
|
+
const { data: updatedIdDocument, error: updateError } = await context.env.MASTER_DATA_MANAGEMENT_SERVICE.updateIdDocument({
|
|
2070
|
+
idDocument: fullIdDocument
|
|
2071
|
+
});
|
|
2072
|
+
if (!updatedIdDocument || updateError) {
|
|
2073
|
+
logAuditEvent(context, {
|
|
2074
|
+
eventType: "id-document.updated",
|
|
2075
|
+
targetType: "id-document",
|
|
2076
|
+
targetId: id,
|
|
2077
|
+
outcome: "failure",
|
|
2078
|
+
severity: "medium",
|
|
2079
|
+
description: `Failed to update ID document ${id}`
|
|
2080
|
+
});
|
|
2081
|
+
return context.json({ message: "Could not update ID document" }, 500);
|
|
2082
|
+
}
|
|
2083
|
+
logAuditEvent(context, {
|
|
2084
|
+
eventType: "id-document.updated",
|
|
2085
|
+
targetType: "id-document",
|
|
2086
|
+
targetId: id,
|
|
2087
|
+
outcome: "success",
|
|
2088
|
+
severity: "medium",
|
|
2089
|
+
description: `ID document ${id} updated`,
|
|
2090
|
+
details: { partyId: updatedIdDocument.partyId }
|
|
2091
|
+
});
|
|
2092
|
+
return context.json(
|
|
2093
|
+
{
|
|
2094
|
+
message: "ID document updated successfully",
|
|
2095
|
+
idDocument: updatedIdDocument
|
|
2096
|
+
},
|
|
2097
|
+
200
|
|
2098
|
+
);
|
|
2099
|
+
});
|
|
1992
2100
|
|
|
1993
2101
|
const messageResponseSchema = z.object({
|
|
1994
2102
|
message: z.string()
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devizovaburza/mdm-sdk",
|
|
3
|
-
"version": "1.2.5-canary.
|
|
3
|
+
"version": "1.2.5-canary.3d05b5f",
|
|
4
4
|
"author": "Devizová burza a.s.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"prepare": "bun run build",
|
|
9
|
-
"build": "unbuild"
|
|
9
|
+
"build": "unbuild",
|
|
10
|
+
"test": "vitest --project $npm_package_name --root ../.."
|
|
10
11
|
},
|
|
11
12
|
"exports": {
|
|
12
13
|
"./v1": {
|
|
@@ -18,18 +19,18 @@
|
|
|
18
19
|
"dist"
|
|
19
20
|
],
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@develit-io/backend-sdk": "^10.0.
|
|
22
|
+
"@develit-io/backend-sdk": "^10.0.3",
|
|
22
23
|
"@develit-io/general-codes": "^1.17.0",
|
|
23
|
-
"@hono/zod-openapi": "^1.
|
|
24
|
+
"@hono/zod-openapi": "^1.3.0",
|
|
24
25
|
"drizzle-orm": "^0.45.2",
|
|
25
26
|
"drizzle-zod": "^0.8.3",
|
|
26
27
|
"zod": "^4.3.6"
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
29
|
-
"hono": "^4.12.
|
|
30
|
+
"hono": "^4.12.14"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@apps/gateway": "workspace:*",
|
|
33
|
-
"unbuild": "
|
|
34
|
+
"unbuild": "3.6.1"
|
|
34
35
|
}
|
|
35
36
|
}
|