@opencrvs/toolkit 2.0.0-rc.fdc585a → 2.0.0-rc.fe94e41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/create-countryconfig/index.js +103 -0
  2. package/create-countryconfig/package.json +21 -0
  3. package/dist/application-config/index.js +220 -86
  4. package/dist/cli.js +392 -128
  5. package/dist/commons/api/router.d.ts +3369 -238
  6. package/dist/commons/conditionals/conditionals.d.ts +6 -0
  7. package/dist/commons/conditionals/validate.d.ts +1 -0
  8. package/dist/commons/events/ActionDocument.d.ts +6 -0
  9. package/dist/commons/events/ActionInput.d.ts +114 -0
  10. package/dist/commons/events/Draft.d.ts +4 -2
  11. package/dist/commons/events/EventDocument.d.ts +3 -0
  12. package/dist/commons/events/EventIndex.d.ts +0 -3
  13. package/dist/commons/events/EventMetadata.d.ts +0 -7
  14. package/dist/commons/events/WorkqueueConfig.d.ts +150 -150
  15. package/dist/commons/events/index.d.ts +2 -0
  16. package/dist/commons/events/locations.d.ts +21 -0
  17. package/dist/commons/events/mocks.test.utils.d.ts +19 -0
  18. package/dist/commons/events/scopes.d.ts +24 -1
  19. package/dist/commons/events/state/flags.d.ts +16 -0
  20. package/dist/commons/events/state/index.d.ts +0 -4
  21. package/dist/commons/events/state/utils.d.ts +3 -2
  22. package/dist/commons/events/utils.d.ts +12 -1
  23. package/dist/conditionals/index.js +7 -1
  24. package/dist/events/index.js +808 -174
  25. package/dist/migrations/v2.0/checkout-upstream-files.d.ts +1 -1
  26. package/dist/migrations/v2.0/checkout-upstream-files.d.ts.map +1 -1
  27. package/dist/migrations/v2.0/checkout-upstream-files.js +1 -2
  28. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts +9 -1
  29. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts.map +1 -1
  30. package/dist/migrations/v2.0/delete-infrastructure-directory.js +66 -20
  31. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts +3 -0
  32. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts.map +1 -0
  33. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.js +110 -0
  34. package/dist/migrations/v2.0/index.d.ts +5 -3
  35. package/dist/migrations/v2.0/index.d.ts.map +1 -1
  36. package/dist/migrations/v2.0/index.js +390 -126
  37. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts +11 -1
  38. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts.map +1 -1
  39. package/dist/migrations/v2.0/merge-infrastructure-directory.js +17 -16
  40. package/dist/migrations/v2.0/migrate-scopes.d.ts.map +1 -1
  41. package/dist/migrations/v2.0/migrate-scopes.js +54 -30
  42. package/dist/migrations/v2.0/migrate-workqueue-configs.d.ts.map +1 -1
  43. package/dist/migrations/v2.0/migrate-workqueue-configs.js +140 -59
  44. package/dist/notification/index.js +656 -119
  45. package/dist/scopes/index.js +3 -1
  46. package/opencrvs-toolkit-2.0.0-rc.fe94e41.tgz +0 -0
  47. package/package.json +6 -2
  48. package/tsconfig.tsbuildinfo +1 -1
  49. package/opencrvs-toolkit-2.0.0-rc.fdc585a.tgz +0 -0
@@ -213,6 +213,10 @@ __export(events_exports, {
213
213
  UUID: () => UUID,
214
214
  UnassignActionInput: () => UnassignActionInput,
215
215
  UserAuditRecordInput: () => UserAuditRecordInput,
216
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS: () => V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS,
217
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP: () => V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP,
218
+ V2_DEFAULT_MOCK_LOCATIONS: () => V2_DEFAULT_MOCK_LOCATIONS,
219
+ V2_DEFAULT_MOCK_LOCATIONS_MAP: () => V2_DEFAULT_MOCK_LOCATIONS_MAP,
216
220
  ValidationConfig: () => ValidationConfig,
217
221
  VerificationActionConfig: () => VerificationActionConfig,
218
222
  VerificationPageConfig: () => VerificationPageConfig,
@@ -234,6 +238,7 @@ __export(events_exports, {
234
238
  ageToDate: () => ageToDate,
235
239
  aggregateActionAnnotations: () => aggregateActionAnnotations,
236
240
  aggregateActionDeclarations: () => aggregateActionDeclarations,
241
+ always: () => always,
237
242
  alwaysTrue: () => alwaysTrue,
238
243
  and: () => and,
239
244
  annotationActions: () => annotationActions,
@@ -277,6 +282,7 @@ __export(events_exports, {
277
282
  findActiveDraftForEvent: () => findActiveDraftForEvent,
278
283
  findAllFields: () => findAllFields,
279
284
  findLastAssignmentAction: () => findLastAssignmentAction,
285
+ findPendingCorrectionAction: () => findPendingCorrectionAction,
280
286
  findRecordActionPages: () => findRecordActionPages,
281
287
  flag: () => flag,
282
288
  flattenFieldReference: () => flattenFieldReference,
@@ -302,13 +308,15 @@ __export(events_exports, {
302
308
  getActionConfig: () => getActionConfig,
303
309
  getActionReview: () => getActionReview,
304
310
  getActionReviewFields: () => getActionReviewFields,
311
+ getAdministrativeAreaHierarchy: () => getAdministrativeAreaHierarchy,
305
312
  getAllUniqueFields: () => getAllUniqueFields,
306
313
  getAnnotationFromDrafts: () => getAnnotationFromDrafts,
307
314
  getAssignedUserFromActions: () => getAssignedUserFromActions,
308
- getAssignedUserSignatureFromActions: () => getAssignedUserSignatureFromActions,
309
315
  getAssignmentStatus: () => getAssignmentStatus,
310
316
  getAvailableActionsForEvent: () => getAvailableActionsForEvent,
317
+ getAvailableRolesForUserUpdatePayload: () => getAvailableRolesForUserUpdatePayload,
311
318
  getCompleteActionAnnotation: () => getCompleteActionAnnotation,
319
+ getCompleteActionContent: () => getCompleteActionContent,
312
320
  getCompleteActionDeclaration: () => getCompleteActionDeclaration,
313
321
  getCurrentEventState: () => getCurrentEventState,
314
322
  getCustomActionFields: () => getCustomActionFields,
@@ -317,7 +325,9 @@ __export(events_exports, {
317
325
  getDeclarationFields: () => getDeclarationFields,
318
326
  getDeclarationPages: () => getDeclarationPages,
319
327
  getEventConfigById: () => getEventConfigById,
328
+ getEventFlags: () => getEventFlags,
320
329
  getFilePathsFromEvent: () => getFilePathsFromEvent,
330
+ getLocationHierarchy: () => getLocationHierarchy,
321
331
  getMixedPath: () => getMixedPath,
322
332
  getPendingAction: () => getPendingAction,
323
333
  getPrintCertificatePages: () => getPrintCertificatePages,
@@ -378,6 +388,7 @@ __export(events_exports, {
378
388
  isPageVisible: () => isPageVisible,
379
389
  isParagraphFieldType: () => isParagraphFieldType,
380
390
  isPhoneFieldType: () => isPhoneFieldType,
391
+ isPotentialDuplicate: () => isPotentialDuplicate,
381
392
  isPrintButtonFieldType: () => isPrintButtonFieldType,
382
393
  isQrReaderFieldType: () => isQrReaderFieldType,
383
394
  isQueryParamReaderFieldType: () => isQueryParamReaderFieldType,
@@ -411,6 +422,7 @@ __export(events_exports, {
411
422
  plainDateToLocalDate: () => plainDateToLocalDate,
412
423
  precompileActionSchemas: () => precompileActionSchemas,
413
424
  resolveDateOfEvent: () => resolveDateOfEvent,
425
+ resolveEventCustomFlags: () => resolveEventCustomFlags,
414
426
  resolvePlaceOfEvent: () => resolvePlaceOfEvent,
415
427
  runFieldValidations: () => runFieldValidations,
416
428
  runStructuralValidations: () => runStructuralValidations,
@@ -702,7 +714,9 @@ var decodeScope = (query) => {
702
714
  };
703
715
  var DEFAULT_SCOPE_OPTIONS = {
704
716
  placeOfEvent: JurisdictionFilter.enum.all,
705
- accessLevel: JurisdictionFilter.enum.all
717
+ accessLevel: JurisdictionFilter.enum.all,
718
+ registeredIn: JurisdictionFilter.enum.all,
719
+ declaredIn: JurisdictionFilter.enum.all
706
720
  };
707
721
  function getAcceptedScopesByType({
708
722
  acceptedScopes,
@@ -1075,7 +1089,10 @@ var ActionConditional = z7.discriminatedUnion("type", [
1075
1089
  ShowConditional,
1076
1090
  // Action can be shown to the user in the list but as disabled
1077
1091
  EnableConditional
1078
- ]);
1092
+ ]).meta({
1093
+ id: "ActionConditional",
1094
+ description: "Conditional gating whether an action is shown (SHOW) or enabled (ENABLE). When omitted from an action, the action is shown and enabled for everyone."
1095
+ });
1079
1096
  var DisplayOnReviewConditional = z7.object({
1080
1097
  type: z7.literal(ConditionalType.DISPLAY_ON_REVIEW),
1081
1098
  conditional: Conditional
@@ -1090,8 +1107,8 @@ var FieldConditional = z7.discriminatedUnion("type", [
1090
1107
  // Field output can be shown / hidden on the review page
1091
1108
  DisplayOnReviewConditional
1092
1109
  ]).meta({
1093
- description: "Field conditional configuration",
1094
- id: "FieldConditional"
1110
+ id: "FieldConditional",
1111
+ description: "Conditional gating whether a form field is shown (SHOW), enabled (ENABLE), or displayed on the review page (DISPLAY_ON_REVIEW). When omitted, the field is shown and enabled for everyone, and is displayed on review whenever it has a value."
1095
1112
  });
1096
1113
 
1097
1114
  // ../commons/src/events/FieldType.ts
@@ -1411,28 +1428,20 @@ function schemaPriority(schema) {
1411
1428
  return idx === -1 ? 9999 : idx;
1412
1429
  }
1413
1430
  function safeUnion(schemas) {
1431
+ const sortedSchemas = [...schemas].sort(
1432
+ (a, b) => schemaPriority(a) - schemaPriority(b)
1433
+ );
1414
1434
  return z12.any().superRefine((val, ctx) => {
1415
- const successful = schemas.filter((s) => s.safeParse(val).success);
1416
- if (successful.length === 1) {
1417
- return;
1418
- }
1419
- if (successful.length === 0) {
1420
- ctx.addIssue({
1421
- code: "invalid_type",
1422
- expected: "custom",
1423
- message: "Value does not match any schema"
1424
- });
1425
- return;
1426
- }
1427
- successful.sort((a, b) => schemaPriority(a) - schemaPriority(b));
1428
- const best = successful[0];
1429
- if (!best.safeParse(val).success) {
1430
- ctx.addIssue({
1431
- expected: "custom",
1432
- code: "invalid_type",
1433
- message: "Value did not match the best schema"
1434
- });
1435
+ for (const schema of sortedSchemas) {
1436
+ if (schema.safeParse(val).success) {
1437
+ return;
1438
+ }
1435
1439
  }
1440
+ ctx.addIssue({
1441
+ code: "invalid_type",
1442
+ expected: "custom",
1443
+ message: "Value does not match any schema"
1444
+ });
1436
1445
  }).meta({
1437
1446
  description: "Value that matches exactly one of the possible schema types (TextValue, DateValue, DateRangeFieldValue). The best matching schema is chosen by priority."
1438
1447
  });
@@ -1649,8 +1658,9 @@ var RequestedCorrectionAction = ActionBase.extend(
1649
1658
  var ApprovedCorrectionAction = ActionBase.extend(
1650
1659
  z14.object({
1651
1660
  type: z14.literal(ActionType.APPROVE_CORRECTION),
1652
- requestId: z14.string()
1661
+ requestId: z14.string(),
1653
1662
  // TODO move into 'content' property
1663
+ content: z14.object({ immediateCorrection: z14.boolean().optional() }).optional()
1654
1664
  }).shape
1655
1665
  );
1656
1666
  var RejectedCorrectionAction = ActionBase.extend(
@@ -1742,6 +1752,9 @@ var FlagConfig = z15.object({
1742
1752
  "Indicates if this flag expects an action to be performed to be cleared."
1743
1753
  ),
1744
1754
  label: TranslationConfig.describe("Human readable label of the flag.")
1755
+ }).meta({
1756
+ id: "FlagConfig",
1757
+ description: "Configuration for a custom flag that can be added to or removed from records by event actions."
1745
1758
  });
1746
1759
  var ActionFlagConfig = z15.object({
1747
1760
  id: Flag,
@@ -1749,6 +1762,9 @@ var ActionFlagConfig = z15.object({
1749
1762
  conditional: Conditional.optional().describe(
1750
1763
  "When conditional is met, the operation is performed on the flag. If not provided, the operation is performed unconditionally."
1751
1764
  )
1765
+ }).meta({
1766
+ id: "ActionFlagConfig",
1767
+ description: "Add or remove operation applied to a flag when the parent action is accepted. Optionally gated by a conditional."
1752
1768
  });
1753
1769
 
1754
1770
  // ../commons/src/events/EventMetadata.ts
@@ -1770,8 +1786,7 @@ var ActionCreationMetadata = z16.object({
1770
1786
  ),
1771
1787
  createdByUserType: z16.enum(["user", "system"]).nullish().describe("Whether the user is a normal user or a system."),
1772
1788
  acceptedAt: z16.iso.datetime().describe("Timestamp when the action request was accepted."),
1773
- createdByRole: z16.string().optional().describe("Role of the user at the time of action request creation."),
1774
- createdBySignature: z16.string().nullish().describe("Signature of the user who created the action request.")
1789
+ createdByRole: z16.string().optional().describe("Role of the user at the time of action request creation.")
1775
1790
  });
1776
1791
  var RegistrationCreationMetadata = ActionCreationMetadata.extend({
1777
1792
  registrationNumber: z16.string().describe(
@@ -1799,9 +1814,6 @@ var EventMetadata = z16.object({
1799
1814
  createdAtLocation: UUID.nullish().describe(
1800
1815
  "Location of the user who created the event."
1801
1816
  ),
1802
- createdBySignature: DocumentPath.nullish().describe(
1803
- "Signature of the user who created the event."
1804
- ),
1805
1817
  updatedAtLocation: UUID.nullish().describe(
1806
1818
  "Location of the user who last changed the status."
1807
1819
  ),
@@ -2176,14 +2188,21 @@ var FieldId = import_v43.default.string().superRefine((val, ctx) => {
2176
2188
  }
2177
2189
  }).describe("Unique identifier for the field");
2178
2190
  var FieldReference = import_v43.default.object({
2179
- $$field: FieldId,
2191
+ $$field: FieldId.describe("Id of the field to reference"),
2180
2192
  $$subfield: import_v43.default.array(import_v43.default.string()).optional().default([]).describe(
2181
2193
  'If the FieldValue is an object, subfield can be used to refer to e.g. `["foo", "bar"]` in `{ foo: { bar: 3 } }`'
2182
2194
  )
2183
2195
  }).describe("Reference to a field by its ID");
2184
2196
  var ValidationConfig = import_v43.default.object({
2185
- validator: Conditional,
2186
- message: TranslationConfig
2197
+ validator: Conditional.describe(
2198
+ "Conditional expression that must hold for the field value to be considered valid."
2199
+ ),
2200
+ message: TranslationConfig.describe(
2201
+ "Error message displayed when the validator does not hold."
2202
+ )
2203
+ }).meta({
2204
+ id: "ValidationConfig",
2205
+ description: "Validation rule applied to a form field. The validator is a conditional expression that must hold for the field value to be considered valid."
2187
2206
  });
2188
2207
  var requiredSchema = import_v43.default.union([
2189
2208
  import_v43.default.boolean(),
@@ -2222,6 +2241,9 @@ var BaseField = import_v43.default.object({
2222
2241
  }).describe("Common properties shared across all field types.");
2223
2242
  var Divider = BaseField.extend({
2224
2243
  type: import_v43.default.literal(FieldType.DIVIDER)
2244
+ }).meta({
2245
+ description: "A horizontal line divider",
2246
+ id: "Divider"
2225
2247
  });
2226
2248
  var TextField = BaseField.extend({
2227
2249
  type: import_v43.default.literal(FieldType.TEXT),
@@ -2232,7 +2254,10 @@ var TextField = BaseField.extend({
2232
2254
  prefix: TranslationConfig.optional(),
2233
2255
  postfix: TranslationConfig.optional()
2234
2256
  }).default({ type: "text" }).optional()
2235
- }).describe("Text input");
2257
+ }).meta({
2258
+ description: "A text input field",
2259
+ id: "TextField"
2260
+ });
2236
2261
  var NumberField = BaseField.extend({
2237
2262
  type: import_v43.default.literal(FieldType.NUMBER),
2238
2263
  defaultValue: NumberFieldValue.optional(),
@@ -2242,7 +2267,10 @@ var NumberField = BaseField.extend({
2242
2267
  prefix: TranslationConfig.optional(),
2243
2268
  postfix: TranslationConfig.optional()
2244
2269
  }).optional()
2245
- }).describe("Number input");
2270
+ }).meta({
2271
+ description: "A number input field",
2272
+ id: "NumberField"
2273
+ });
2246
2274
  var TextAreaField = BaseField.extend({
2247
2275
  type: import_v43.default.literal(FieldType.TEXTAREA),
2248
2276
  defaultValue: NonEmptyTextValue.optional(),
@@ -2253,7 +2281,10 @@ var TextAreaField = BaseField.extend({
2253
2281
  prefix: TranslationConfig.optional(),
2254
2282
  postfix: TranslationConfig.optional()
2255
2283
  }).default({ rows: 4 }).optional()
2256
- }).describe("Multiline text input");
2284
+ }).meta({
2285
+ description: "A multiline text input",
2286
+ id: "TextAreaField"
2287
+ });
2257
2288
  var ImageMimeType = import_v43.default.enum([
2258
2289
  "image/png",
2259
2290
  "image/jpg",
@@ -2283,13 +2314,19 @@ var SignatureField = BaseField.extend({
2283
2314
  }).default({
2284
2315
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2285
2316
  })
2286
- }).describe("Signature input field");
2317
+ }).meta({
2318
+ description: "A signature input field",
2319
+ id: "SignatureField"
2320
+ });
2287
2321
  var EmailField = BaseField.extend({
2288
2322
  type: import_v43.default.literal(FieldType.EMAIL),
2289
2323
  configuration: import_v43.default.object({
2290
2324
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text")
2291
2325
  }).default({ maxLength: 255 }).optional(),
2292
2326
  defaultValue: NonEmptyTextValue.optional()
2327
+ }).meta({
2328
+ description: "An email input field",
2329
+ id: "EmailField"
2293
2330
  });
2294
2331
  var DateField = BaseField.extend({
2295
2332
  type: import_v43.default.literal(FieldType.DATE),
@@ -2299,7 +2336,10 @@ var DateField = BaseField.extend({
2299
2336
  "Text to display above the date input"
2300
2337
  ).optional()
2301
2338
  }).optional()
2302
- }).describe("A single date input (yyyy-MM-dd)");
2339
+ }).meta({
2340
+ description: "A date input (yyyy-MM-dd)",
2341
+ id: "DateField"
2342
+ });
2303
2343
  var AgeField = BaseField.extend({
2304
2344
  type: import_v43.default.literal(FieldType.AGE),
2305
2345
  defaultValue: NumberFieldValue.optional(),
@@ -2308,7 +2348,10 @@ var AgeField = BaseField.extend({
2308
2348
  prefix: TranslationConfig.optional(),
2309
2349
  postfix: TranslationConfig.optional()
2310
2350
  })
2311
- }).describe("An age input field which uses the current date as the asOfDate");
2351
+ }).meta({
2352
+ description: "An age input field which uses the current date as the asOfDate",
2353
+ id: "AgeField"
2354
+ });
2312
2355
  var TimeField = BaseField.extend({
2313
2356
  type: import_v43.default.literal(FieldType.TIME),
2314
2357
  defaultValue: SerializedNowDateTime.or(TimeValue).optional().describe("Default time value (HH-mm)"),
@@ -2318,7 +2361,10 @@ var TimeField = BaseField.extend({
2318
2361
  "Text to display above the time input"
2319
2362
  ).optional()
2320
2363
  }).optional()
2321
- }).describe("A single date input (HH-mm)");
2364
+ }).meta({
2365
+ description: "A single time input (HH-mm)",
2366
+ id: "TimeField"
2367
+ });
2322
2368
  var DateRangeField = BaseField.extend({
2323
2369
  type: import_v43.default.literal(FieldType.DATE_RANGE),
2324
2370
  defaultValue: DateRangeFieldValue.optional(),
@@ -2327,7 +2373,10 @@ var DateRangeField = BaseField.extend({
2327
2373
  "Text to display above the date input"
2328
2374
  ).optional()
2329
2375
  }).optional()
2330
- }).describe("A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })");
2376
+ }).meta({
2377
+ description: "A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })",
2378
+ id: "DateRangeField"
2379
+ });
2331
2380
  var HtmlFontVariant = import_v43.default.enum([
2332
2381
  "reg12",
2333
2382
  "reg14",
@@ -2371,18 +2420,30 @@ var ImageViewField = BaseField.extend({
2371
2420
  type: import_v43.default.literal(FieldType.IMAGE_VIEW),
2372
2421
  defaultValue: NonEmptyTextValue.optional(),
2373
2422
  configuration: ImageConfiguration
2374
- }).describe("A read-only image component for form pages");
2423
+ }).meta({
2424
+ description: "A read-only image component for form pages",
2425
+ id: "ImageViewField"
2426
+ });
2375
2427
  var Paragraph = BaseField.extend({
2376
2428
  type: import_v43.default.literal(FieldType.PARAGRAPH),
2377
2429
  configuration: ParagraphConfiguration
2378
- }).describe("A read-only HTML <p> paragraph");
2430
+ }).meta({
2431
+ description: "A read-only HTML <p> paragraph",
2432
+ id: "Paragraph"
2433
+ });
2379
2434
  var Heading = BaseField.extend({
2380
2435
  type: import_v43.default.literal(FieldType.HEADING),
2381
2436
  configuration: HeadingConfiguration
2382
- }).describe("A read-only heading component for form pages");
2437
+ }).meta({
2438
+ description: "A read-only heading component for form pages",
2439
+ id: "Heading"
2440
+ });
2383
2441
  var PageHeader = BaseField.extend({
2384
2442
  type: import_v43.default.literal(FieldType.PAGE_HEADER)
2385
- }).describe("A read-only header component for form pages");
2443
+ }).meta({
2444
+ description: "A read-only header component for form pages",
2445
+ id: "PageHeader"
2446
+ });
2386
2447
  var File = BaseField.extend({
2387
2448
  type: import_v43.default.literal(FieldType.FILE),
2388
2449
  defaultValue: FileFieldValue.optional(),
@@ -2401,7 +2462,10 @@ var File = BaseField.extend({
2401
2462
  }).default({
2402
2463
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2403
2464
  })
2404
- }).describe("File upload");
2465
+ }).meta({
2466
+ description: "A file upload field",
2467
+ id: "File"
2468
+ });
2405
2469
  var SelectOption = import_v43.default.object({
2406
2470
  value: import_v43.default.string().describe("The value of the option"),
2407
2471
  label: import_v43.default.union([import_v43.default.string(), TranslationConfig]).describe("The label of the option"),
@@ -2418,7 +2482,10 @@ var NumberWithUnitField = BaseField.extend({
2418
2482
  "Placeholder for the number field"
2419
2483
  )
2420
2484
  }).optional()
2421
- }).describe("Number with unit input");
2485
+ }).meta({
2486
+ description: "A number with unit input field",
2487
+ id: "NumberWithUnitField"
2488
+ });
2422
2489
  var RadioGroup = BaseField.extend({
2423
2490
  type: import_v43.default.literal(FieldType.RADIO_GROUP),
2424
2491
  defaultValue: TextValue.optional(),
@@ -2428,7 +2495,10 @@ var RadioGroup = BaseField.extend({
2428
2495
  size: import_v43.default.enum(["NORMAL", "LARGE"]).optional()
2429
2496
  }).optional()
2430
2497
  }).optional()
2431
- }).describe("Grouped radio options");
2498
+ }).meta({
2499
+ description: "A grouped radio button field",
2500
+ id: "RadioGroup"
2501
+ });
2432
2502
  var BulletList = BaseField.extend({
2433
2503
  type: import_v43.default.literal(FieldType.BULLET_LIST),
2434
2504
  items: import_v43.default.array(TranslationConfig).describe("A list of items"),
@@ -2437,7 +2507,10 @@ var BulletList = BaseField.extend({
2437
2507
  fontVariant: HtmlFontVariant.optional()
2438
2508
  }).optional()
2439
2509
  }).default({})
2440
- }).describe("A list of bullet points");
2510
+ }).meta({
2511
+ description: "A list of bullet points",
2512
+ id: "BulletList"
2513
+ });
2441
2514
  var Select = BaseField.extend({
2442
2515
  type: import_v43.default.literal(FieldType.SELECT),
2443
2516
  defaultValue: TextValue.optional(),
@@ -2452,7 +2525,10 @@ var Select = BaseField.extend({
2452
2525
  { ..., defaultMessage: "'{input}' is not listed among the health facilities." }
2453
2526
  `
2454
2527
  )
2455
- }).describe("Select input");
2528
+ }).meta({
2529
+ description: "A select input field",
2530
+ id: "Select"
2531
+ });
2456
2532
  var SelectDateRangeOption = import_v43.default.object({
2457
2533
  value: SelectDateRangeValue.describe("The value of the option"),
2458
2534
  label: TranslationConfig.describe("The label of the option")
@@ -2461,7 +2537,10 @@ var SelectDateRangeField = BaseField.extend({
2461
2537
  type: import_v43.default.literal(FieldType.SELECT_DATE_RANGE),
2462
2538
  defaultValue: SelectDateRangeValue.optional(),
2463
2539
  options: import_v43.default.array(SelectDateRangeOption).describe("A list of options")
2464
- }).describe("Select input with date range options");
2540
+ }).meta({
2541
+ description: "A date range selection field",
2542
+ id: "SelectDateRangeField"
2543
+ });
2465
2544
  var NameConfig = import_v43.default.object({
2466
2545
  firstname: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
2467
2546
  middlename: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
@@ -2492,26 +2571,41 @@ var NameField = BaseField.extend({
2492
2571
  surname: { required: true }
2493
2572
  }
2494
2573
  }).optional()
2495
- }).describe("Name input field");
2574
+ }).meta({
2575
+ description: "A field for entering a persons name",
2576
+ id: "NameField"
2577
+ });
2496
2578
  var PhoneField = BaseField.extend({
2497
2579
  defaultValue: NonEmptyTextValue.optional(),
2498
2580
  type: import_v43.default.literal(FieldType.PHONE)
2499
- }).describe("Phone input field");
2581
+ }).meta({
2582
+ description: "A field for entering a phone number",
2583
+ id: "PhoneField"
2584
+ });
2500
2585
  var IdField = BaseField.extend({
2501
2586
  defaultValue: NonEmptyTextValue.optional(),
2502
2587
  type: import_v43.default.literal(FieldType.ID)
2503
- }).describe("ID input field");
2588
+ }).meta({
2589
+ description: "A field for entering an ID",
2590
+ id: "IdField"
2591
+ });
2504
2592
  var Checkbox = BaseField.extend({
2505
2593
  type: import_v43.default.literal(FieldType.CHECKBOX),
2506
2594
  defaultValue: CheckboxFieldValue.default(false)
2507
- }).describe("Boolean checkbox field");
2595
+ }).meta({
2596
+ description: "A boolean checkbox field",
2597
+ id: "Checkbox"
2598
+ });
2508
2599
  var Country = BaseField.extend({
2509
2600
  type: import_v43.default.literal(FieldType.COUNTRY),
2510
2601
  defaultValue: NonEmptyTextValue.optional(),
2511
2602
  optionOverrides: import_v43.default.array(SelectOption.omit({ label: true })).optional().describe(
2512
2603
  "Conditionals for specific countries. Countries not listed are always shown and enabled."
2513
2604
  )
2514
- }).describe("Country select field");
2605
+ }).meta({
2606
+ description: "A field for selecting a country",
2607
+ id: "Country"
2608
+ });
2515
2609
  var AllowedLocations = JurisdictionReference.optional().describe(
2516
2610
  "Limits which location options are selectable depending on user jurisdiction and location."
2517
2611
  );
@@ -2520,16 +2614,18 @@ var AdministrativeAreas = import_v43.default.enum([
2520
2614
  "HEALTH_FACILITY",
2521
2615
  "CRVS_OFFICE"
2522
2616
  ]);
2523
- var AdministrativeAreaConfiguration = import_v43.default.object({
2524
- partOf: FieldReference.optional().describe("Parent location"),
2525
- type: AdministrativeAreas,
2526
- allowedLocations: AllowedLocations
2527
- }).describe("Administrative area options");
2528
2617
  var AdministrativeAreaField = BaseField.extend({
2529
2618
  type: import_v43.default.literal(FieldType.ADMINISTRATIVE_AREA),
2530
2619
  defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2531
- configuration: AdministrativeAreaConfiguration
2532
- }).describe("Administrative area input field e.g. facility, office");
2620
+ configuration: import_v43.default.object({
2621
+ partOf: FieldReference.optional().describe("Parent location"),
2622
+ type: AdministrativeAreas,
2623
+ allowedLocations: AllowedLocations
2624
+ }).describe("Administrative area options")
2625
+ }).meta({
2626
+ description: "Administrative area input field",
2627
+ id: "AdministrativeAreaField"
2628
+ });
2533
2629
  var LocationInput = BaseField.extend({
2534
2630
  type: import_v43.default.literal(FieldType.LOCATION),
2535
2631
  defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
@@ -2537,7 +2633,10 @@ var LocationInput = BaseField.extend({
2537
2633
  locationTypes: import_v43.default.array(import_v43.default.string()).optional().describe("Types of the locations that are available for selection."),
2538
2634
  allowedLocations: AllowedLocations
2539
2635
  }).optional()
2540
- }).describe("Input field for a location");
2636
+ }).meta({
2637
+ description: "A field for selecting a location",
2638
+ id: "LocationInput"
2639
+ });
2541
2640
  var FileUploadWithOptions = BaseField.extend({
2542
2641
  type: import_v43.default.literal(FieldType.FILE_WITH_OPTIONS),
2543
2642
  options: import_v43.default.array(SelectOption).describe("A list of options"),
@@ -2551,6 +2650,9 @@ var FileUploadWithOptions = BaseField.extend({
2551
2650
  }).default({
2552
2651
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2553
2652
  })
2653
+ }).meta({
2654
+ description: "A field for uploading files with file type options",
2655
+ id: "FileUploadWithOptions"
2554
2656
  });
2555
2657
  var Facility = BaseField.extend({
2556
2658
  type: import_v43.default.literal(FieldType.FACILITY),
@@ -2596,7 +2698,10 @@ var Address = BaseField.extend({
2596
2698
  allowedLocations: AllowedLocations
2597
2699
  }).optional(),
2598
2700
  defaultValue: DefaultAddressFieldValue.optional()
2599
- }).describe("Address input field \u2013 a combination of location and text fields");
2701
+ }).meta({
2702
+ description: "Address input field \u2013 a combination of location and text fields",
2703
+ id: "Address"
2704
+ });
2600
2705
  var StaticDataEntry = import_v43.default.object({
2601
2706
  id: import_v43.default.string().describe("ID for the data entry."),
2602
2707
  label: TranslationConfig,
@@ -2611,7 +2716,10 @@ var DataField = BaseField.extend({
2611
2716
  subtitle: TranslationConfig.optional(),
2612
2717
  data: import_v43.default.array(DataEntry)
2613
2718
  })
2614
- }).describe("Data field for displaying read-only data");
2719
+ }).meta({
2720
+ description: "A field for displaying a table of read-only data",
2721
+ id: "DataField"
2722
+ });
2615
2723
  var ButtonSize = import_v43.default.enum(["small", "medium", "large"]);
2616
2724
  var ButtonType = import_v43.default.enum([
2617
2725
  "primary",
@@ -2638,11 +2746,17 @@ var ButtonField = BaseField.extend({
2638
2746
  type: import_v43.default.literal(FieldType.BUTTON),
2639
2747
  defaultValue: ButtonFieldValue.optional(),
2640
2748
  configuration: ButtonConfiguration
2641
- }).describe("Generic button without any built-in functionality");
2749
+ }).meta({
2750
+ description: "A generic button that can be used to trigger an action",
2751
+ id: "ButtonField"
2752
+ });
2642
2753
  var FieldGroup = BaseField.extend({
2643
2754
  type: import_v43.default.literal(FieldType.FIELD_GROUP),
2644
2755
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
2645
2756
  fields: import_v43.default.lazy(() => import_v43.default.array(FieldConfig))
2757
+ }).meta({
2758
+ description: "A group of fields that are displayed together",
2759
+ id: "FieldGroup"
2646
2760
  });
2647
2761
  var AlphaPrintButton = BaseField.extend({
2648
2762
  type: import_v43.default.literal(FieldType.ALPHA_PRINT_BUTTON),
@@ -2652,7 +2766,10 @@ var AlphaPrintButton = BaseField.extend({
2652
2766
  "Label for the print button"
2653
2767
  )
2654
2768
  })
2655
- }).describe("Print button field for printing certificates");
2769
+ }).meta({
2770
+ description: "An experimental print button field for printing certificates during the declaration process",
2771
+ id: "AlphaPrintButton"
2772
+ });
2656
2773
  var HttpField = BaseField.extend({
2657
2774
  type: import_v43.default.literal(FieldType.HTTP),
2658
2775
  defaultValue: HttpFieldValue.optional(),
@@ -2668,20 +2785,30 @@ var HttpField = BaseField.extend({
2668
2785
  params: import_v43.default.record(import_v43.default.string(), import_v43.default.union([import_v43.default.string(), FieldReference])).optional(),
2669
2786
  timeout: import_v43.default.number().default(15e3).describe("Request timeout in milliseconds")
2670
2787
  })
2671
- }).describe("HTTP request function triggered by a button click or other event");
2788
+ }).meta({
2789
+ description: "Makes a background HTTP request to an external service and stores the response so other fields can use it. Has no visible UI \u2014 pair with LOADER to show request status.",
2790
+ id: "HttpField"
2791
+ });
2672
2792
  var AutocompleteField = BaseField.extend({
2673
2793
  type: import_v43.default.literal(FieldType.AUTOCOMPLETE),
2674
2794
  configuration: import_v43.default.object({
2675
- url: import_v43.default.string().describe("URL to fetch autocomplete suggestions from").optional(),
2795
+ url: import_v43.default.string().describe(
2796
+ "URL to fetch autocomplete suggestions from. This should be a country config server endpoint."
2797
+ ).optional(),
2676
2798
  method: import_v43.default.enum(["GET", "POST"]).default("GET").optional(),
2677
2799
  defaultOptions: import_v43.default.array(
2678
2800
  import_v43.default.object({
2679
2801
  label: import_v43.default.string(),
2680
2802
  value: import_v43.default.string()
2681
2803
  })
2682
- ).optional()
2804
+ ).optional().describe(
2805
+ "Manual entry is supported through configuration, allowing users to provide values not currently represented in the dataset."
2806
+ )
2683
2807
  })
2684
- }).describe("Autocomplete input field");
2808
+ }).meta({
2809
+ description: "Generic autocomplete component designed for use with large dictionary-based datasets. The component supports dynamic retrieval of options from configurable data sources and is intended for datasets that may contain tens or hundreds of thousands of records.",
2810
+ id: "AutocompleteField"
2811
+ });
2685
2812
  var SearchField = HttpField.extend({
2686
2813
  type: import_v43.default.literal(FieldType.SEARCH),
2687
2814
  configuration: SearchQuery.pick({
@@ -2714,6 +2841,9 @@ var SearchField = HttpField.extend({
2714
2841
  ok: TranslationConfig.optional()
2715
2842
  }).optional()
2716
2843
  })
2844
+ }).meta({
2845
+ description: "A search input field",
2846
+ id: "SearchField"
2717
2847
  });
2718
2848
  var LinkButtonField = BaseField.extend({
2719
2849
  type: import_v43.default.literal(FieldType.LINK_BUTTON),
@@ -2722,7 +2852,10 @@ var LinkButtonField = BaseField.extend({
2722
2852
  text: TranslationConfig.describe("Text to display on the button"),
2723
2853
  icon: import_v43.default.string().optional().describe("Icon for the button. You can find icons from OpenCRVS UI-Kit.")
2724
2854
  })
2725
- }).describe("Button that opens a link");
2855
+ }).meta({
2856
+ description: "A button that opens a URL link",
2857
+ id: "LinkButtonField"
2858
+ });
2726
2859
  var VerificationStatus = BaseField.extend({
2727
2860
  type: import_v43.default.literal(FieldType.VERIFICATION_STATUS),
2728
2861
  defaultValue: VerificationStatusValue.optional(),
@@ -2732,15 +2865,19 @@ var VerificationStatus = BaseField.extend({
2732
2865
  "Explaining text on the banner in form."
2733
2866
  )
2734
2867
  })
2868
+ }).meta({
2869
+ description: "Displays a verification state (e.g. ID verified / pending). Often paired with ID_READER \u2014 it can read its value off an ID_READER rather than holding its own.",
2870
+ id: "VerificationStatus"
2735
2871
  });
2736
2872
  var QueryParamReaderField = BaseField.extend({
2737
2873
  type: import_v43.default.literal(FieldType.QUERY_PARAM_READER),
2738
2874
  configuration: import_v43.default.object({
2739
2875
  pickParams: import_v43.default.array(import_v43.default.string()).describe("List of query parameters to read from the URL")
2740
2876
  })
2741
- }).describe(
2742
- "A field that maps URL query params into form values and clears them afterward"
2743
- );
2877
+ }).meta({
2878
+ description: "A field that maps URL query params into form values and clears them afterward",
2879
+ id: "QueryParamReaderField"
2880
+ });
2744
2881
  var QrReaderField = BaseField.extend({
2745
2882
  type: import_v43.default.literal(FieldType.QR_READER),
2746
2883
  defaultValue: QrReaderFieldValue.optional(),
@@ -2751,7 +2888,7 @@ var QrReaderField = BaseField.extend({
2751
2888
  })
2752
2889
  }).optional()
2753
2890
  }).meta({
2754
- description: "Configuration for QR code reader field, including optional JSON Schema validator.",
2891
+ description: "QR code reader field, including optional JSON Schema validator.",
2755
2892
  id: "QrReaderField"
2756
2893
  });
2757
2894
  var IdReaderField = BaseField.extend({
@@ -2760,12 +2897,18 @@ var IdReaderField = BaseField.extend({
2760
2897
  methods: import_v43.default.array(
2761
2898
  import_v43.default.union([QrReaderField, LinkButtonField]).describe("Methods for reading an ID")
2762
2899
  )
2900
+ }).meta({
2901
+ description: "A wrapper around nested form fields, specifically QR_READER and LINK_BUTTON. It can hold the QR_READERs value.",
2902
+ id: "IdReaderField"
2763
2903
  });
2764
2904
  var CustomField = BaseField.extend({
2765
2905
  type: import_v43.default.literal(FieldType._EXPERIMENTAL_CUSTOM),
2766
2906
  defaultValue: CustomFieldValue.optional(),
2767
2907
  src: import_v43.default.string().describe("Module source path for the custom field component"),
2768
2908
  configuration: import_v43.default.unknown().optional()
2909
+ }).meta({
2910
+ description: "An expiremental custom field that is defined by a module source path",
2911
+ id: "CustomField"
2769
2912
  });
2770
2913
  var FieldStyleVariant = import_v43.default.enum(["default", "highlighted"]);
2771
2914
  var LoaderField = BaseField.extend({
@@ -2775,22 +2918,25 @@ var LoaderField = BaseField.extend({
2775
2918
  configuration: import_v43.default.object({
2776
2919
  text: TranslationConfig.describe("Display text above the loading spinner")
2777
2920
  })
2778
- }).describe(
2779
- "A non-interactive field that indicates an in progress operation in form"
2780
- );
2921
+ }).meta({
2922
+ description: "A non-interactive field that indicates an in progress operation in form",
2923
+ id: "LoaderField"
2924
+ });
2781
2925
  var HiddenField = BaseField.extend({
2782
2926
  type: import_v43.default.literal(FieldType.ALPHA_HIDDEN),
2783
2927
  required: import_v43.default.boolean().default(false).optional(),
2784
2928
  defaultValue: TextValue.optional()
2785
- }).describe(
2786
- "A non-interactive, hidden field that only hold a value in the form"
2787
- );
2929
+ }).meta({
2930
+ description: "A non-interactive, hidden field that only hold a value in the form",
2931
+ id: "HiddenField"
2932
+ });
2788
2933
  var UserRoleField = BaseField.extend({
2789
2934
  type: import_v43.default.literal(FieldType.USER_ROLE),
2790
2935
  defaultValue: TextValue.optional()
2791
- }).describe(
2792
- "A select dropdown that is automatically populated with available user roles"
2793
- );
2936
+ }).meta({
2937
+ description: "A select dropdown that is automatically populated with available user roles",
2938
+ id: "UserRoleField"
2939
+ });
2794
2940
  var FieldConfig = import_v43.default.discriminatedUnion("type", [
2795
2941
  FieldGroup,
2796
2942
  Address,
@@ -2889,16 +3035,19 @@ var VerificationPageConfig = FormPageConfig.extend({
2889
3035
  type: z21.literal(PageTypes.enum.VERIFICATION),
2890
3036
  actions: VerificationActionConfig
2891
3037
  });
2892
- var PageConfig = z21.discriminatedUnion("type", [
2893
- FormPageConfig,
2894
- VerificationPageConfig
2895
- ]);
3038
+ var PageConfig = z21.discriminatedUnion("type", [FormPageConfig, VerificationPageConfig]).meta({
3039
+ id: "PageConfig",
3040
+ description: "Configuration for a single page in a form. Either a form page with fields and a continue button, or a verification page with verify/cancel options."
3041
+ });
2896
3042
 
2897
3043
  // ../commons/src/events/FormConfig.ts
2898
3044
  var DeclarationFormConfig = z22.object({
2899
3045
  label: TranslationConfig.describe("Human readable description of the form"),
2900
3046
  pages: z22.array(FormPageConfig)
2901
- }).describe("Configuration of the declaration form.");
3047
+ }).meta({
3048
+ id: "DeclarationFormConfig",
3049
+ description: "Configuration of the declaration form."
3050
+ });
2902
3051
  var ActionFormConfig = z22.object({
2903
3052
  label: TranslationConfig.describe("Human readable description of the form"),
2904
3053
  pages: z22.array(PageConfig)
@@ -2998,6 +3147,9 @@ var DeduplicationConfig = z23.object({
2998
3147
  id: z23.string(),
2999
3148
  label: TranslationConfig,
3000
3149
  query: Clause
3150
+ }).meta({
3151
+ id: "DeduplicationConfig",
3152
+ description: "Configuration for duplicate detection on a declare or register action. The query is built from fuzzy / strict / date-range matchers combined with and/or/not."
3001
3153
  });
3002
3154
 
3003
3155
  // ../commons/src/events/ActionConfig.ts
@@ -3115,17 +3267,42 @@ var ActionConfig = z24.discriminatedUnion("type", [
3115
3267
  * OpenAPI references are defined here so our generated OpenAPI spec knows to reuse the models
3116
3268
  * and treat them as "models" instead of duplicating the data structure in each endpoint.
3117
3269
  */
3118
- ReadActionConfig.meta({ id: "ReadActionConfig" }),
3119
- DeclareConfig.meta({ id: "DeclareActionConfig" }),
3120
- RejectConfig.meta({ id: "RejectActionConfig" }),
3121
- RegisterConfig.meta({ id: "RegisterActionConfig" }),
3270
+ ReadActionConfig.meta({
3271
+ id: "ReadActionConfig",
3272
+ description: "Configuration for the read action \u2014 defines the record-tab content displayed on the event overview page."
3273
+ }),
3274
+ DeclareConfig.meta({
3275
+ id: "DeclareActionConfig",
3276
+ description: "Configuration for the declare action. Includes review-page fields. Shared with the notify action (ActionType.NOTIFY)."
3277
+ }),
3278
+ RejectConfig.meta({
3279
+ id: "RejectActionConfig",
3280
+ description: "Configuration for rejecting a record before registration."
3281
+ }),
3282
+ RegisterConfig.meta({
3283
+ id: "RegisterActionConfig",
3284
+ description: "Configuration for registering a record."
3285
+ }),
3122
3286
  PrintCertificateActionConfig.meta({
3123
- id: "PrintCertificateActionConfig"
3287
+ id: "PrintCertificateActionConfig",
3288
+ description: "Configuration for printing a certificate of a registered record."
3289
+ }),
3290
+ RequestCorrectionConfig.meta({
3291
+ id: "RequestCorrectionActionConfig",
3292
+ description: "Configuration for requesting a correction on a registered record."
3293
+ }),
3294
+ EditActionConfig.meta({
3295
+ id: "EditActionConfig",
3296
+ description: "Configuration for editing a record before registration."
3124
3297
  }),
3125
- RequestCorrectionConfig.meta({ id: "RequestCorrectionActionConfig" }),
3126
- EditActionConfig.meta({ id: "EditActionConfig" }),
3127
- ArchiveConfig.meta({ id: "ArchiveActionConfig" }),
3128
- CustomActionConfig.meta({ id: "CustomActionConfig" })
3298
+ ArchiveConfig.meta({
3299
+ id: "ArchiveActionConfig",
3300
+ description: "Configuration for archiving a record."
3301
+ }),
3302
+ CustomActionConfig.meta({
3303
+ id: "CustomActionConfig",
3304
+ description: "Configuration for a country-defined custom action. An event may include any number of these."
3305
+ })
3129
3306
  ]).describe(
3130
3307
  "Configuration of an action available for an event. Data collected depends on the action type and is accessible through the annotation property in ActionDocument."
3131
3308
  ).meta({ id: "ActionConfig" });
@@ -3201,7 +3378,10 @@ var Field = BaseField2.extend({
3201
3378
  }).describe("Custom field defined for the summary view.");
3202
3379
  var SummaryConfig = z27.object({
3203
3380
  fields: z27.array(z27.union([Field, ReferenceField])).describe("Fields displayed in the event summary view.")
3204
- }).describe("Configuration of the event summary section.");
3381
+ }).meta({
3382
+ id: "SummaryConfig",
3383
+ description: "Configuration of the event overview page. Defines which declaration fields appear in the record summary, optionally with custom labels, empty-value messages, and templated values."
3384
+ });
3205
3385
 
3206
3386
  // ../commons/src/events/AdvancedSearchConfig.ts
3207
3387
  var z28 = __toESM(require("zod/v4"));
@@ -3325,6 +3505,9 @@ var AdvancedSearchField = z28.discriminatedUnion("fieldType", [FieldConfigSchema
3325
3505
  var AdvancedSearchConfig = z28.object({
3326
3506
  title: TranslationConfig.describe("Advanced search tab title"),
3327
3507
  fields: z28.array(AdvancedSearchField).describe("Advanced search fields within the tab.")
3508
+ }).meta({
3509
+ id: "AdvancedSearchConfig",
3510
+ description: "Configuration of one advanced search tab. Each tab has a title and a list of searchable fields \u2014 either declaration fields (via `field()`) or event metadata (via `event()`)."
3328
3511
  });
3329
3512
 
3330
3513
  // ../commons/src/events/utils.ts
@@ -3801,6 +3984,9 @@ function precompileActionSchemas(eventConfigurations) {
3801
3984
  function isAgeValue(value) {
3802
3985
  return typeof value === "object" && value !== null && "age" in value && typeof value.age === "number";
3803
3986
  }
3987
+ function mergeWithBaseFormState(values, context) {
3988
+ return { ...context.baseFormState, ...values };
3989
+ }
3804
3990
  function validate(schema, data) {
3805
3991
  const validator = ajv.getSchema(schema.$id) || ajv.compile(schema);
3806
3992
  if ("$form" in data) {
@@ -3839,7 +4025,7 @@ function isOnline() {
3839
4025
  }
3840
4026
  function isConditionMet(conditional, values, context, eventIndex) {
3841
4027
  return validate(conditional, {
3842
- $form: values,
4028
+ $form: mergeWithBaseFormState(values, context),
3843
4029
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3844
4030
  $online: isOnline(),
3845
4031
  $user: context.user,
@@ -3868,7 +4054,7 @@ function isFieldConditionMet(field3, form, conditionalType, context) {
3868
4054
  return true;
3869
4055
  }
3870
4056
  const validConditionals = getConditionalActionsForField(field3, {
3871
- $form: form,
4057
+ $form: mergeWithBaseFormState(form, context),
3872
4058
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3873
4059
  $online: isOnline(),
3874
4060
  $user: context.user,
@@ -4060,7 +4246,7 @@ function runFieldValidations({
4060
4246
  return [];
4061
4247
  }
4062
4248
  const conditionalParameters = {
4063
- $form: form,
4249
+ $form: mergeWithBaseFormState(form, context),
4064
4250
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
4065
4251
  /**
4066
4252
  * In real use cases, there can be hundreds of thousands of locations.
@@ -4304,17 +4490,16 @@ function isPageVisible(page, formValues, context) {
4304
4490
  }
4305
4491
  return isConditionMet(page.conditional, formValues, context);
4306
4492
  }
4307
- function omitHiddenFields(fields, formValues, validatorContext, includeHiddenFieldsWithNullValues = false, declarationContext) {
4493
+ function omitHiddenFields(fields, formValues, validatorContext, includeHiddenFieldsWithNullValues = false) {
4308
4494
  const base = (0, import_lodash.cloneDeep)(formValues);
4309
4495
  function fn(prevVisibilityContext) {
4310
- const visibilityForm = declarationContext ? { ...declarationContext, ...prevVisibilityContext } : prevVisibilityContext;
4311
4496
  const cleaned = (0, import_lodash.omitBy)(base, (value, fieldId) => {
4312
4497
  const fieldConfig = fields.filter((f) => f.id === fieldId);
4313
4498
  if (!fieldConfig.length) {
4314
4499
  return false;
4315
4500
  }
4316
4501
  const isHidden = fieldConfig.every(
4317
- (f) => !isFieldVisible(f, visibilityForm, validatorContext)
4502
+ (f) => !isFieldVisible(f, prevVisibilityContext, validatorContext)
4318
4503
  );
4319
4504
  if (!isHidden) {
4320
4505
  return false;
@@ -4332,7 +4517,7 @@ function omitHiddenPaginatedFields(formConfig, values, validatorContext, include
4332
4517
  const visibleFields = formConfig.pages.filter((p) => isPageVisible(p, values, validatorContext)).flatMap((p) => p.fields);
4333
4518
  const hiddenFields = formConfig.pages.filter((p) => !isPageVisible(p, values, validatorContext)).flatMap((p) => p.fields);
4334
4519
  const valuesExceptHiddenPage = (0, import_lodash.omitBy)(values, (_2, fieldId) => {
4335
- return hiddenFields.some((f) => f.id === fieldId);
4520
+ return hiddenFields.some((f) => f.id === fieldId) && !visibleFields.some((f) => f.id === fieldId);
4336
4521
  });
4337
4522
  return omitHiddenFields(
4338
4523
  visibleFields,
@@ -4379,13 +4564,10 @@ function getVisibleVerificationPageIds(pages, annotation, context) {
4379
4564
  }
4380
4565
  function omitHiddenAnnotationFields(actionConfig, declaration, annotation, context) {
4381
4566
  const annotationFields = getActionAnnotationFields(actionConfig);
4382
- return omitHiddenFields(
4383
- annotationFields,
4384
- annotation,
4385
- context,
4386
- false,
4387
- declaration
4388
- );
4567
+ return omitHiddenFields(annotationFields, annotation, {
4568
+ ...context,
4569
+ baseFormState: declaration
4570
+ });
4389
4571
  }
4390
4572
  function deepMerge(currentDocument, actionDocument) {
4391
4573
  const currentDocumentClone = (0, import_lodash.cloneDeep)(currentDocument);
@@ -4573,6 +4755,22 @@ function getCompleteActionAnnotation(annotation, event2, action) {
4573
4755
  }
4574
4756
  return deepMerge(annotation, action.annotation ?? {});
4575
4757
  }
4758
+ function getCompleteActionContent(event2, action) {
4759
+ const currentContent = "content" in action ? action.content : void 0;
4760
+ if (!action.originalActionId) {
4761
+ return currentContent;
4762
+ }
4763
+ const originalAction = event2.actions.find(
4764
+ ({ id }) => id === action.originalActionId
4765
+ );
4766
+ if (originalAction && "content" in originalAction && originalAction.content) {
4767
+ return {
4768
+ ...originalAction.content,
4769
+ ...currentContent ?? {}
4770
+ };
4771
+ }
4772
+ return currentContent;
4773
+ }
4576
4774
  function getCompleteActionDeclaration(declaration, event2, action) {
4577
4775
  if (action.originalActionId) {
4578
4776
  const originalAction = event2.actions.find(
@@ -4679,6 +4877,9 @@ function not(condition) {
4679
4877
  function never2() {
4680
4878
  return not(alwaysTrue());
4681
4879
  }
4880
+ function always() {
4881
+ return defineConditional(alwaysTrue());
4882
+ }
4682
4883
  function jsonFieldPath(field3) {
4683
4884
  return [field3.$$field, ...field3.$$subfield].join("/");
4684
4885
  }
@@ -5374,7 +5575,7 @@ var _EventConfigBase = z33.object({
5374
5575
  ),
5375
5576
  label: TranslationConfig.describe("Human-readable label for the event type."),
5376
5577
  actions: z33.array(ActionConfig).describe(
5377
- "Configuration of system-defined actions associated with the event."
5578
+ "Configuration of core and custom actions associated with the event."
5378
5579
  ),
5379
5580
  actionOrder: z33.array(z33.string()).optional().describe(
5380
5581
  "Order of actions in the action menu. Use either the action type for core actions or the customActionType for custom actions."
@@ -5386,7 +5587,7 @@ var _EventConfigBase = z33.object({
5386
5587
  "Configuration of fields available in the advanced search feature."
5387
5588
  ),
5388
5589
  flags: z33.array(FlagConfig).optional().default([]).describe(
5389
- "Configuration of flags associated with the actions of this event type."
5590
+ "Configuration of custom flags associated with the actions of this event type."
5390
5591
  ),
5391
5592
  analytics: z33.boolean().optional().default(true).describe(
5392
5593
  "Indicates whether the records of this event type are included in analytics"
@@ -5399,8 +5600,9 @@ var EventConfig = _EventConfigBase.superRefine((event2, ctx) => {
5399
5600
  validateActionFlags(event2, ctx);
5400
5601
  validateActionOrder(event2, ctx);
5401
5602
  }).meta({
5402
- id: "EventConfig"
5403
- }).describe("Configuration defining an event type.");
5603
+ id: "EventConfig",
5604
+ description: "Configuration defining an event type registered in OpenCRVS (for example birth or death)."
5605
+ });
5404
5606
 
5405
5607
  // ../commons/src/events/EventConfigInput.ts
5406
5608
  var defineDeclarationForm = (form) => DeclarationFormConfig.parse(form);
@@ -5623,6 +5825,9 @@ var WorkqueueColumnValue = z34.object({
5623
5825
  var WorkqueueColumn = z34.object({
5624
5826
  label: TranslationConfig,
5625
5827
  value: WorkqueueColumnValue
5828
+ }).meta({
5829
+ id: "WorkqueueColumn",
5830
+ description: "Configuration for a single workqueue column. The value references an event metadata key (e.g. `dateOfEvent`, `status`, `trackingId`)."
5626
5831
  });
5627
5832
  function defineWorkqueuesColumns(workqueueColumns) {
5628
5833
  return workqueueColumns.map(
@@ -5825,18 +6030,11 @@ var WorkqueueConfigWithoutQuery = WorkqueueConfig.omit({
5825
6030
  query: true,
5826
6031
  columns: true
5827
6032
  });
5828
- var WorkqueueConfigInput = z37.object({
5829
- slug: z37.string().describe("Determines the url of the workqueue."),
5830
- name: TranslationConfig.describe(
5831
- "Title of the workflow (both in navigation and on the page)"
5832
- ),
5833
- query: CountryConfigQueryInputType,
5834
- action: z37.object({ type: WorkqueueActionType }).optional().describe(
5835
- "Workqueue call-to-action button configuration. This determines the quick action button shown on each event card and the action taken when the button is clicked."
5836
- ),
5837
- columns: z37.array(WorkqueueColumn).default(mandatoryColumns),
5838
- icon: AvailableIcons,
5839
- emptyMessage: TranslationConfig.optional()
6033
+ var WorkqueueConfigInput = WorkqueueConfig.extend({
6034
+ query: CountryConfigQueryInputType
6035
+ }).meta({
6036
+ id: "WorkqueueConfig",
6037
+ description: "Configuration for a single workqueue. Defines the filter applied to the event index, the quick-action button, the columns shown on each row, and the message rendered when the queue is empty."
5840
6038
  });
5841
6039
  function defineWorkqueue(workqueueInput) {
5842
6040
  const queryInput = workqueueInput.query;
@@ -5897,6 +6095,11 @@ var BaseActionInput = z38.object({
5897
6095
  originalActionId: UUID.optional(),
5898
6096
  // should not be part of base action.
5899
6097
  keepAssignment: z38.boolean().optional(),
6098
+ keepAssignmentIfAccepted: z38.boolean().optional(),
6099
+ keepAssignmentIfRejected: z38.boolean().optional(),
6100
+ waitFor: z38.boolean().default(true).describe(
6101
+ "Whether action waits for the indexing before returning. Defaults to true. Setting this to to false completes faster but might lead to stale data in the client if the client tries to read the event immediately after performing the action. Use with care."
6102
+ ),
5900
6103
  // For normal users, the createdAtLocation is resolved on the backend from the user's primaryOfficeId.
5901
6104
  // @TODO: createdAtLocation should be limited to actions that system users can perform. For normal users, it should not be part of the base action.
5902
6105
  createdAtLocation: UUID.nullish().describe(
@@ -6014,7 +6217,8 @@ var RejectCorrectionActionInput = BaseActionInput.extend(
6014
6217
  var ApproveCorrectionActionInput = BaseActionInput.extend(
6015
6218
  z38.object({
6016
6219
  requestId: z38.string(),
6017
- type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION)
6220
+ type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION),
6221
+ content: z38.object({ immediateCorrection: z38.boolean().optional() }).optional()
6018
6222
  }).shape
6019
6223
  );
6020
6224
  var ReadActionInput = BaseActionInput.extend(
@@ -6076,7 +6280,7 @@ var Draft = z39.object({
6076
6280
  }).describe(
6077
6281
  "A temporary storage for an action. Stored with details of the event, creator and creation time."
6078
6282
  );
6079
- var DraftInput = BaseActionInput.extend({
6283
+ var DraftInput = BaseActionInput.omit({ waitFor: true }).extend({
6080
6284
  type: ActionTypes.exclude([ActionTypes.enum.DELETE]),
6081
6285
  status: z39.enum([
6082
6286
  ActionStatus.Requested,
@@ -6150,7 +6354,6 @@ function getDeclarationActionCreationMetadata(actionType, actions) {
6150
6354
  createdAtLocation: requestAction?.createdAtLocation ?? acceptAction.createdAtLocation,
6151
6355
  acceptedAt: acceptAction.createdAt,
6152
6356
  createdByRole: requestAction?.createdByRole ?? acceptAction.createdByRole,
6153
- createdBySignature: requestAction?.createdBySignature ?? acceptAction.createdBySignature,
6154
6357
  registrationNumber
6155
6358
  };
6156
6359
  }
@@ -6208,26 +6411,43 @@ var import_date_fns3 = require("date-fns");
6208
6411
  function isEditInProgress(actions) {
6209
6412
  return actions.at(-1)?.type === ActionType.EDIT;
6210
6413
  }
6414
+ function findPendingCorrectionAction(writeActions2) {
6415
+ let correctionRequestAction;
6416
+ for (let i = writeActions2.length - 1; i >= 0; i--) {
6417
+ const action = writeActions2[i];
6418
+ if (action.type === ActionType.APPROVE_CORRECTION || action.type === ActionType.REJECT_CORRECTION) {
6419
+ break;
6420
+ }
6421
+ if (action.type === ActionType.REQUEST_CORRECTION) {
6422
+ correctionRequestAction = action;
6423
+ break;
6424
+ }
6425
+ }
6426
+ return correctionRequestAction;
6427
+ }
6211
6428
  function isCorrectionRequested(actions) {
6429
+ return findPendingCorrectionAction(actions) !== void 0;
6430
+ }
6431
+ function isDeclarationIncomplete(actions) {
6432
+ return getStatusFromActions(actions) === EventStatus.enum.NOTIFIED;
6433
+ }
6434
+ function isRejected(actions) {
6435
+ const resettingActionTypes = [
6436
+ ActionType.NOTIFY,
6437
+ ActionType.DECLARE,
6438
+ ActionType.EDIT,
6439
+ ActionType.REGISTER
6440
+ ];
6212
6441
  return actions.reduce((prev, { type }) => {
6213
- if (type === ActionType.REQUEST_CORRECTION) {
6442
+ if (type === ActionType.REJECT) {
6214
6443
  return true;
6215
6444
  }
6216
- if (type === ActionType.APPROVE_CORRECTION) {
6217
- return false;
6218
- }
6219
- if (type === ActionType.REJECT_CORRECTION) {
6445
+ if (resettingActionTypes.includes(type)) {
6220
6446
  return false;
6221
6447
  }
6222
6448
  return prev;
6223
6449
  }, false);
6224
6450
  }
6225
- function isDeclarationIncomplete(actions) {
6226
- return getStatusFromActions(actions) === EventStatus.enum.NOTIFIED;
6227
- }
6228
- function isRejected(actions) {
6229
- return actions.at(-1)?.type === ActionType.REJECT;
6230
- }
6231
6451
  function isPotentialDuplicate(actions) {
6232
6452
  return actions.reduce((prev, { type }) => {
6233
6453
  if (type === ActionType.DUPLICATE_DETECTED) {
@@ -6290,8 +6510,7 @@ function resolveEventCustomFlags(event2, eventConfiguration) {
6290
6510
  return (0, import_lodash3.uniq)(flags);
6291
6511
  }, []);
6292
6512
  }
6293
- function getEventFlags(event2, config) {
6294
- const sortedActions = event2.actions.filter(({ type }) => !isMetaAction(type)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
6513
+ function getActionStatusFlags(sortedActions) {
6295
6514
  const actionStatus = sortedActions.reduce(
6296
6515
  (actionStatuses, { type, status: status2 }) => ({
6297
6516
  ...actionStatuses,
@@ -6299,26 +6518,40 @@ function getEventFlags(event2, config) {
6299
6518
  }),
6300
6519
  {}
6301
6520
  );
6302
- const flags = Object.entries(actionStatus).filter(([, status2]) => status2 !== ActionStatus.Accepted).map(([type, status2]) => {
6521
+ return Object.entries(actionStatus).filter(([, status2]) => status2 !== ActionStatus.Accepted).map(([type, status2]) => {
6303
6522
  const flag2 = joinValues([type, status2], ":").toLowerCase();
6304
6523
  return flag2;
6305
6524
  });
6306
- if (isCorrectionRequested(sortedActions)) {
6307
- flags.push(InherentFlags.CORRECTION_REQUESTED);
6525
+ }
6526
+ function getInherentFlags(sortedActions) {
6527
+ const acceptedActions = sortedActions.filter(
6528
+ ({ status: status2 }) => status2 === ActionStatus.Accepted
6529
+ );
6530
+ const inherentFlags = [];
6531
+ if (isCorrectionRequested(acceptedActions)) {
6532
+ inherentFlags.push(InherentFlags.CORRECTION_REQUESTED);
6308
6533
  }
6309
- if (isDeclarationIncomplete(sortedActions)) {
6310
- flags.push(InherentFlags.INCOMPLETE);
6534
+ if (isDeclarationIncomplete(acceptedActions)) {
6535
+ inherentFlags.push(InherentFlags.INCOMPLETE);
6311
6536
  }
6312
- if (isRejected(sortedActions)) {
6313
- flags.push(InherentFlags.REJECTED);
6537
+ if (isRejected(acceptedActions)) {
6538
+ inherentFlags.push(InherentFlags.REJECTED);
6314
6539
  }
6315
- if (isPotentialDuplicate(sortedActions)) {
6316
- flags.push(InherentFlags.POTENTIAL_DUPLICATE);
6540
+ if (isPotentialDuplicate(acceptedActions)) {
6541
+ inherentFlags.push(InherentFlags.POTENTIAL_DUPLICATE);
6317
6542
  }
6318
- if (isEditInProgress(sortedActions)) {
6319
- flags.push(InherentFlags.EDIT_IN_PROGRESS);
6543
+ if (isEditInProgress(acceptedActions)) {
6544
+ inherentFlags.push(InherentFlags.EDIT_IN_PROGRESS);
6320
6545
  }
6321
- return [...flags, ...resolveEventCustomFlags(event2, config)];
6546
+ return inherentFlags;
6547
+ }
6548
+ function getEventFlags(event2, config) {
6549
+ const sortedActions = event2.actions.filter(({ type }) => !isMetaAction(type)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
6550
+ return [
6551
+ ...getActionStatusFlags(sortedActions),
6552
+ ...getInherentFlags(sortedActions),
6553
+ ...resolveEventCustomFlags(event2, config)
6554
+ ];
6322
6555
  }
6323
6556
 
6324
6557
  // ../commons/src/events/state/index.ts
@@ -6364,17 +6597,6 @@ function getAssignedUserFromActions(actions) {
6364
6597
  return user2;
6365
6598
  }, null);
6366
6599
  }
6367
- function getAssignedUserSignatureFromActions(actions) {
6368
- return actions.reduce((signature, action) => {
6369
- if (action.type === ActionType.ASSIGN) {
6370
- return action.createdBySignature || null;
6371
- }
6372
- if (action.type === ActionType.UNASSIGN) {
6373
- return null;
6374
- }
6375
- return signature;
6376
- }, null);
6377
- }
6378
6600
  function deepDropNulls(obj) {
6379
6601
  if (Array.isArray(obj)) {
6380
6602
  return obj.map(deepDropNulls);
@@ -6470,10 +6692,8 @@ function getCurrentEventState(event2, config) {
6470
6692
  createdBy: creationAction.createdBy,
6471
6693
  createdByUserType: creationAction.createdByUserType,
6472
6694
  createdAtLocation: creationAction.createdAtLocation,
6473
- createdBySignature: creationAction.createdBySignature,
6474
6695
  updatedAt: acceptedActionMetadata.createdAt,
6475
6696
  assignedTo: getAssignedUserFromActions(acceptedActions),
6476
- assignedToSignature: getAssignedUserSignatureFromActions(acceptedActions),
6477
6697
  updatedBy: requestActionMetadata.createdBy,
6478
6698
  updatedAtLocation: requestActionMetadata.createdAtLocation,
6479
6699
  declaration,
@@ -9732,7 +9952,6 @@ var eventQueryDataGenerator = (overrides = {}, seed = 1) => {
9732
9952
  createdBy: overrides.createdBy ?? generateUuid(rng),
9733
9953
  createdAtLocation: overrides.createdAtLocation ?? generateUuid(rng),
9734
9954
  updatedAtLocation: overrides.updatedAtLocation ?? generateUuid(rng),
9735
- createdBySignature: overrides.createdBySignature ?? generateRandomSignature(rng),
9736
9955
  updatedAt: overrides.updatedAt ?? (0, import_date_fns4.addDays)(new Date(createdAt), 1).toISOString(),
9737
9956
  assignedTo: overrides.assignedTo ?? null,
9738
9957
  updatedBy: overrides.updatedBy ?? generateUuid(rng),
@@ -10003,6 +10222,39 @@ function userCanAccessEventWithScopes(event2, scopes, user2, customActionType) {
10003
10222
  (scope) => canAccessEventWithScope(event2, scope, user2, customActionType)
10004
10223
  );
10005
10224
  }
10225
+ function getAdministrativeAreaHierarchy(administrativeAreaId, administrativeAreas) {
10226
+ const collectedLocations = [];
10227
+ const parsedAdministrativeAreaId = administrativeAreaId && UUID.safeParse(administrativeAreaId).data;
10228
+ let current = parsedAdministrativeAreaId ? administrativeAreas.get(parsedAdministrativeAreaId) : null;
10229
+ while (current) {
10230
+ collectedLocations.push(current);
10231
+ if (!current.parentId) {
10232
+ break;
10233
+ }
10234
+ const parentId = current.parentId;
10235
+ current = administrativeAreas.get(parentId);
10236
+ }
10237
+ return collectedLocations;
10238
+ }
10239
+ function getLocationHierarchy(selectedId, context) {
10240
+ const { administrativeAreas, locations } = context;
10241
+ const loc = locations.get(selectedId);
10242
+ if (loc) {
10243
+ if (loc.administrativeAreaId) {
10244
+ const hierarchy2 = getAdministrativeAreaHierarchy(
10245
+ loc.administrativeAreaId,
10246
+ administrativeAreas
10247
+ );
10248
+ return [...hierarchy2.reverse().map((area) => area.id), loc.id];
10249
+ }
10250
+ return [loc.id];
10251
+ }
10252
+ const hierarchy = getAdministrativeAreaHierarchy(
10253
+ selectedId,
10254
+ administrativeAreas
10255
+ );
10256
+ return hierarchy.reverse().map((area) => area.id);
10257
+ }
10006
10258
 
10007
10259
  // ../commons/src/events/scopes.ts
10008
10260
  var ACTION_SCOPE_MAP = {
@@ -10077,6 +10329,25 @@ function isActionInScope({
10077
10329
  );
10078
10330
  return canAccess;
10079
10331
  }
10332
+ function getAvailableRolesForUserUpdatePayload({
10333
+ allRoles,
10334
+ userLocation,
10335
+ acceptedScopes,
10336
+ userRequesting
10337
+ }) {
10338
+ const availableRoles = allRoles.filter((role) => {
10339
+ const canAccess = canAccessOtherUserWithScopes({
10340
+ userToAccess: {
10341
+ ...userLocation,
10342
+ role
10343
+ },
10344
+ user: userRequesting,
10345
+ scopes: acceptedScopes
10346
+ });
10347
+ return canAccess;
10348
+ });
10349
+ return availableRoles;
10350
+ }
10080
10351
 
10081
10352
  // ../commons/src/events/serializers/user/deserializer.ts
10082
10353
  function userDeserializer(serializedUserField, user2) {
@@ -10279,3 +10550,366 @@ function getFilePathsFromEvent(event2) {
10279
10550
  });
10280
10551
  return (0, import_lodash7.uniq)(filepaths);
10281
10552
  }
10553
+
10554
+ // ../commons/src/events/mocks.test.utils.ts
10555
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS = [
10556
+ {
10557
+ id: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10558
+ name: "Central",
10559
+ parentId: null,
10560
+ validUntil: null,
10561
+ externalId: "ydyJb1RAy4U1"
10562
+ },
10563
+ {
10564
+ id: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10565
+ name: "Sulaka",
10566
+ parentId: null,
10567
+ validUntil: null,
10568
+ externalId: "pQ8nGxWmZ2Q3"
10569
+ },
10570
+ {
10571
+ id: "7ef2b9c7-5e6d-49f6-ae05-656207d0fc64",
10572
+ name: "Pualula",
10573
+ parentId: null,
10574
+ validUntil: null,
10575
+ externalId: "Aq91DweLmT8k"
10576
+ },
10577
+ {
10578
+ id: "6d1a59df-988c-4021-a846-ccbc021931a7",
10579
+ name: "Chuminga",
10580
+ parentId: null,
10581
+ validUntil: null,
10582
+ externalId: "Rw0fYNh2Xk9a"
10583
+ },
10584
+ {
10585
+ id: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10586
+ name: "Ibombo",
10587
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10588
+ validUntil: null,
10589
+ externalId: "k7DsP4vbN1Qe"
10590
+ },
10591
+ {
10592
+ id: "27160bbd-32d1-4625-812f-860226bfb92a",
10593
+ name: "Isango",
10594
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10595
+ validUntil: null,
10596
+ externalId: "Gm3Z9eQpHw4L"
10597
+ },
10598
+ {
10599
+ id: "967032fd-3f81-478a-826c-30cb8fe121bd",
10600
+ name: "Isamba",
10601
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10602
+ validUntil: null,
10603
+ externalId: "sT0xVu1KqJ7r"
10604
+ },
10605
+ {
10606
+ id: "89a33893-b17d-481d-a26d-6461e7ac1651",
10607
+ name: "Itambo",
10608
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10609
+ validUntil: null,
10610
+ externalId: "Nq6Bv2HpL9Te"
10611
+ },
10612
+ {
10613
+ id: "d42ab2fe-e7ed-470e-8b31-4fb27f9b8250",
10614
+ name: "Ezhi",
10615
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10616
+ validUntil: null,
10617
+ externalId: "xK8cQ0ZRy5Wd"
10618
+ },
10619
+ {
10620
+ id: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
10621
+ name: "Ilanga",
10622
+ parentId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10623
+ validUntil: null,
10624
+ externalId: "Cq4Jm1XvN8Ls"
10625
+ },
10626
+ // Villages under Ibombo (62a0ccb4-880d-4f30-8882-f256007dfff9)
10627
+ {
10628
+ id: "1d4e5f6a-7b8c-4912-8efa-345678901234",
10629
+ name: "Klow",
10630
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10631
+ validUntil: null,
10632
+ externalId: "IkYcYBUcyY2"
10633
+ },
10634
+ {
10635
+ id: "2e5f6a7b-8c9d-4a23-8fab-456789012345",
10636
+ name: "Mbondo",
10637
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10638
+ validUntil: null,
10639
+ externalId: "Qhvv5hvo3mY"
10640
+ },
10641
+ {
10642
+ id: "3f6a7b8c-9d0e-4b34-8abc-567890123456",
10643
+ name: "Ndara",
10644
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10645
+ validUntil: null,
10646
+ externalId: "crXh068O9TR"
10647
+ },
10648
+ {
10649
+ id: "4a7b8c9d-0e1f-4c45-abcd-678901234567",
10650
+ name: "Olani",
10651
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10652
+ validUntil: null,
10653
+ externalId: "r00It8Tvvp7"
10654
+ },
10655
+ {
10656
+ id: "5b8c9d0e-1f2a-4d56-bcde-789012345678",
10657
+ name: "Pemba",
10658
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10659
+ validUntil: null,
10660
+ externalId: "ZnUWsbONIaH"
10661
+ },
10662
+ {
10663
+ id: "6c9d0e1f-2a3b-4e67-8def-890123456789",
10664
+ name: "Quanza",
10665
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10666
+ validUntil: null,
10667
+ externalId: "fDZycvQTa7l"
10668
+ },
10669
+ {
10670
+ id: "7d0e1f2a-3b4c-4f78-8efa-901234567890",
10671
+ name: "Rivka",
10672
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10673
+ validUntil: null,
10674
+ externalId: "KqswxCGTELa"
10675
+ },
10676
+ // Villages under Isamba (967032fd-3f81-478a-826c-30cb8fe121bd)
10677
+ {
10678
+ id: "8e1f2a3b-4c5d-4089-8fab-012345678901",
10679
+ name: "Mbula",
10680
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10681
+ validUntil: null,
10682
+ externalId: "osEbKjRc9Kg"
10683
+ },
10684
+ {
10685
+ id: "9f2a3b4c-5d6e-4190-8abf-123456789012",
10686
+ name: "Ndoki",
10687
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10688
+ validUntil: null,
10689
+ externalId: "aq4daBUAGr3"
10690
+ },
10691
+ {
10692
+ id: "0a3b4c5d-6e7f-4201-abcd-234567890123",
10693
+ name: "Tsanga",
10694
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10695
+ validUntil: null,
10696
+ externalId: "cqis6Y8trbJ"
10697
+ },
10698
+ {
10699
+ id: "1b4c5d6e-7f8a-4312-bcde-345678901234",
10700
+ name: "Waziri",
10701
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10702
+ validUntil: null,
10703
+ externalId: "LMijHPyyx6d"
10704
+ },
10705
+ {
10706
+ id: "2c5d6e7f-8a9b-4423-8def-456789012345",
10707
+ name: "Zimbi",
10708
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10709
+ validUntil: null,
10710
+ externalId: "pcQYbPuKGZ7"
10711
+ },
10712
+ // Villages under Itambo (89a33893-b17d-481d-a26d-6461e7ac1651)
10713
+ {
10714
+ id: "3d6e7f8a-9b0c-4534-8efa-567890123456",
10715
+ name: "Felani",
10716
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10717
+ validUntil: null,
10718
+ externalId: "gSqpoCGdMXp"
10719
+ },
10720
+ {
10721
+ id: "4e7f8a9b-0c1d-4645-8fab-678901234567",
10722
+ name: "Goroma",
10723
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10724
+ validUntil: null,
10725
+ externalId: "KvAAIaNqVrp"
10726
+ },
10727
+ {
10728
+ id: "5f8a9b0c-1d2e-4756-8abc-789012345678",
10729
+ name: "Halifu",
10730
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10731
+ validUntil: null,
10732
+ externalId: "qe4UnEVt1hv"
10733
+ },
10734
+ {
10735
+ id: "6a9b0c1d-2e3f-4867-abcd-890123456789",
10736
+ name: "Jabari",
10737
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10738
+ validUntil: null,
10739
+ externalId: "yHH9Nz4rLOt"
10740
+ },
10741
+ {
10742
+ id: "7b0c1d2e-3f4a-4978-bcde-901234567890",
10743
+ name: "Kifani",
10744
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10745
+ validUntil: null,
10746
+ externalId: "eSWmXIGeu1I"
10747
+ },
10748
+ {
10749
+ id: "8c1d2e3f-4a5b-4089-8def-012345678901",
10750
+ name: "Lumela",
10751
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10752
+ validUntil: null,
10753
+ externalId: "bh0b3aI1uP3"
10754
+ }
10755
+ ];
10756
+ var V2_DEFAULT_MOCK_LOCATIONS = [
10757
+ {
10758
+ id: "6f6186ce-cd5f-4a5f-810a-2d99e7c4ba12",
10759
+ name: "Central Provincial Office",
10760
+ locationType: "CRVS_OFFICE",
10761
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10762
+ validUntil: null,
10763
+ externalId: "Xr3Df8WpK6Ys"
10764
+ },
10765
+ {
10766
+ id: "b1c2d3e4-f5a6-7890-bcde-f12345678901",
10767
+ name: "Central Health Post",
10768
+ locationType: "HEALTH_FACILITY",
10769
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10770
+ validUntil: null
10771
+ },
10772
+ {
10773
+ id: "028d2c85-ca31-426d-b5d1-2cef545a4902",
10774
+ name: "Ibombo District Office",
10775
+ locationType: "CRVS_OFFICE",
10776
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10777
+ validUntil: null,
10778
+ externalId: "Sm4Nw7GrD2Vy"
10779
+ },
10780
+ {
10781
+ id: "62a0ccb4-4f30-4f30-8882-f256007dff9f",
10782
+ name: "Isamba District Office",
10783
+ locationType: "CRVS_OFFICE",
10784
+ administrativeAreaId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10785
+ validUntil: null,
10786
+ externalId: "Vg1Bq5XeH9Lt"
10787
+ },
10788
+ {
10789
+ id: "954c93e1-13f7-4435-bb82-35e0e215e07d",
10790
+ name: "Isango District Office",
10791
+ locationType: "CRVS_OFFICE",
10792
+ administrativeAreaId: "27160bbd-32d1-4625-812f-860226bfb92a",
10793
+ validUntil: null,
10794
+ externalId: "Je7Lm2XqN9Vz"
10795
+ },
10796
+ {
10797
+ id: "2884f5b9-17b4-49ce-bf4d-f538228935df",
10798
+ name: "Sulaka Provincial Office",
10799
+ locationType: "CRVS_OFFICE",
10800
+ administrativeAreaId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10801
+ validUntil: null,
10802
+ externalId: "Ht2Wp9KcX5Qv"
10803
+ },
10804
+ {
10805
+ id: "030358c6-54af-44be-821b-8e4af963a49c",
10806
+ name: "Ilanga District Office",
10807
+ locationType: "CRVS_OFFICE",
10808
+ administrativeAreaId: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
10809
+ validUntil: null,
10810
+ externalId: "Yp6Ds1WqN3Xz"
10811
+ },
10812
+ {
10813
+ id: "423d000f-101b-47c0-8b86-21a908067cee",
10814
+ name: "Chamakubi Health Post",
10815
+ locationType: "HEALTH_FACILITY",
10816
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10817
+ validUntil: null,
10818
+ externalId: "M1nFr8LbC2Qy"
10819
+ },
10820
+ {
10821
+ id: "4d3279be-d026-420c-88f7-f0a4ae986973",
10822
+ name: "Ibombo Rural Health Centre",
10823
+ locationType: "HEALTH_FACILITY",
10824
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10825
+ validUntil: null,
10826
+ externalId: "bT7pV6YrW0Xc"
10827
+ },
10828
+ {
10829
+ id: "190902f4-1d77-476a-8947-41145af1db7d",
10830
+ name: "Chikobo Rural Health Centre",
10831
+ locationType: "HEALTH_FACILITY",
10832
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10833
+ validUntil: null,
10834
+ externalId: "zE4qPn2SgJ5d"
10835
+ },
10836
+ {
10837
+ id: "f5ecbd9b-a01e-4a65-910e-70e86ab41b71",
10838
+ name: "Chilochabalenje Health Post",
10839
+ locationType: "HEALTH_FACILITY",
10840
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10841
+ validUntil: null,
10842
+ externalId: "H8vDs1MqR4Uf"
10843
+ },
10844
+ {
10845
+ id: "dbfc178f-7295-4b90-b28d-111c95b03127",
10846
+ name: "Chipeso Rural Health Centre",
10847
+ locationType: "HEALTH_FACILITY",
10848
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10849
+ validUntil: null,
10850
+ externalId: "Qw3uZ9KfX6Lm"
10851
+ },
10852
+ {
10853
+ id: "09862bfe-c7ac-46cd-987b-668681533c80",
10854
+ name: "Chisamba Rural Health Centre",
10855
+ locationType: "HEALTH_FACILITY",
10856
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10857
+ validUntil: null,
10858
+ externalId: "Yr0pCg8LdM2s"
10859
+ },
10860
+ {
10861
+ id: "834ce389-e95b-4fb0-96a0-33e9ab323059",
10862
+ name: "Chitanda Rural Health Centre",
10863
+ locationType: "HEALTH_FACILITY",
10864
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10865
+ validUntil: null,
10866
+ externalId: "tS9gJ4PwB1Qx"
10867
+ },
10868
+ {
10869
+ id: "0431c433-6062-4a4c-aee9-25271aec61ee",
10870
+ name: "Golden Valley Rural Health Centre",
10871
+ locationType: "HEALTH_FACILITY",
10872
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10873
+ validUntil: null,
10874
+ externalId: "Ld7Qm3XsA8Vr"
10875
+ },
10876
+ {
10877
+ id: "bc84d0b6-7ba7-480d-a339-5d9920d90eb2",
10878
+ name: "Ipongo Rural Health Centre",
10879
+ locationType: "HEALTH_FACILITY",
10880
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10881
+ validUntil: null,
10882
+ externalId: "kF2sW9DmH0Bt"
10883
+ },
10884
+ {
10885
+ id: "4cf1f53b-b730-41d2-8649-dff7eeed970d",
10886
+ name: "Itumbwe Health Post",
10887
+ locationType: "HEALTH_FACILITY",
10888
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10889
+ validUntil: null,
10890
+ externalId: "Ue5Xb3VaC7Pq"
10891
+ },
10892
+ {
10893
+ id: "4b3676cb-9355-4942-9eb9-2ce46acaf0e0",
10894
+ name: "Kabangalala Rural Health Centre",
10895
+ locationType: "HEALTH_FACILITY",
10896
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10897
+ validUntil: null,
10898
+ externalId: "Pz8Kc1TqH6Jn"
10899
+ },
10900
+ // Village offices
10901
+ {
10902
+ id: "1f4a5b6c-7d8e-4312-8abc-345678901234",
10903
+ name: "Klow Village Office",
10904
+ locationType: "CRVS_OFFICE",
10905
+ administrativeAreaId: "1d4e5f6a-7b8c-4912-8efa-345678901234",
10906
+ validUntil: null,
10907
+ externalId: "PmAyxAJkxiJ"
10908
+ }
10909
+ ];
10910
+ var V2_DEFAULT_MOCK_LOCATIONS_MAP = new Map(
10911
+ V2_DEFAULT_MOCK_LOCATIONS.map((l) => [l.id, l])
10912
+ );
10913
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP = new Map(
10914
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS.map((a) => [a.id, a])
10915
+ );