From 0c58ead31284069987b64b039412c86931d5b96a Mon Sep 17 00:00:00 2001 From: cameron testerman <11036339+voidspooks@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:20:39 -0500 Subject: [PATCH] feat(29-4125a): generate codegen_schema artifacts via Optimus Generated by Optimus (https://github.com/aquia-inc/optimus). All files require human review before merging. Files: - src/schemas/29-4125a/schema.js --- src/schemas/29-4125a/schema.js | 498 +++++++++++++++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 src/schemas/29-4125a/schema.js diff --git a/src/schemas/29-4125a/schema.js b/src/schemas/29-4125a/schema.js new file mode 100644 index 00000000..e2d61eb6 --- /dev/null +++ b/src/schemas/29-4125a/schema.js @@ -0,0 +1,498 @@ +const buildDefinitionReference = referenceId => ({ $ref: `#/definitions/${referenceId}` }); + +const schema = { + $schema: 'http://json-schema.org/draft-04/schema#', + type: 'object', + additionalProperties: false, + + definitions: { + fullName: { + type: 'object', + properties: { + first: { + type: 'string', + minLength: 1, + maxLength: 30, + example: 'John', + }, + middle: { + type: ['string', 'null'], + maxLength: 30, + example: 'Allen', + }, + last: { + type: 'string', + minLength: 1, + maxLength: 40, + example: 'Doe', + }, + }, + required: ['first', 'last'], + }, + + ssn: { + type: 'string', + pattern: '^[0-9]{9}$', + minLength: 9, + maxLength: 9, + example: '123456789', + description: 'Nine-digit Social Security Number without dashes', + }, + + date: { + type: 'string', + format: 'date', + pattern: '^\\d{4}-\\d{2}-\\d{2}$', + example: '1945-06-15', + description: 'ISO-8601 date string (YYYY-MM-DD)', + }, + + usPhone: { + type: 'string', + pattern: '^[0-9]{10}$', + minLength: 10, + maxLength: 10, + example: '8006698477', + description: '10-digit US phone number without formatting', + }, + + email: { + type: 'string', + minLength: 1, + maxLength: 100, + example: 'beneficiary@example.com', + }, + + usAddress: { + type: 'object', + properties: { + addressLine1: { + type: 'string', + minLength: 1, + maxLength: 100, + example: '123 Main St', + }, + addressLine2: { + type: ['string', 'null'], + maxLength: 50, + example: 'Apt 4', + }, + city: { + type: 'string', + minLength: 1, + maxLength: 50, + example: 'Janesville', + }, + state: { + type: 'string', + minLength: 2, + maxLength: 2, + example: 'WI', + description: 'Two-letter US state/territory abbreviation', + }, + zipCode: { + type: 'string', + pattern: '^\\d{5}(-\\d{4})?$', + minLength: 5, + maxLength: 10, + example: '53547', + }, + }, + required: ['addressLine1', 'city', 'state', 'zipCode'], + }, + + nsliPolicyNumber: { + type: 'string', + pattern: '^[A-Za-z0-9]{4,12}$', + minLength: 4, + maxLength: 12, + example: 'V1234567', + description: 'NSLI insurance policy number — format pending confirmation from VA Insurance Service (AQ-03)', + }, + + insuredSelectedOption: { + type: 'string', + enum: ['option1', 'option2', 'option3', 'option4', 'unknown'], + description: 'Payment option selected by the insured Veteran on the policy (Item 4)', + }, + + settlementOption: { + type: 'string', + enum: ['option2', 'option3', 'option4'], + description: 'Settlement option selected by the beneficiary (Item 14)', + }, + + installmentCount: { + type: 'integer', + minimum: 36, + maximum: 240, + multipleOf: 12, + description: 'Number of equal monthly installments under Option 2 (36–240 in multiples of 12)', + }, + + submitterRole: { + type: 'string', + enum: ['beneficiary', 'guardian', 'fiduciary'], + description: 'Role of the person completing and certifying the form', + }, + + relationshipToInsured: { + type: 'string', + enum: ['spouse', 'child', 'parent', 'sibling', 'other_relative', 'other'], + description: 'Beneficiary relationship to the insured Veteran (Item 9)', + }, + + paymentMethod: { + type: 'string', + enum: ['direct_deposit', 'check'], + description: 'Preferred method for receiving monthly payments', + }, + + accountType: { + type: 'string', + enum: ['checking', 'savings'], + description: 'Type of depositor account for direct deposit', + }, + + routingTransitNumber: { + type: 'string', + pattern: '^[0-9]{9}$', + minLength: 9, + maxLength: 9, + example: '021000021', + description: 'Nine-digit ABA routing transit number', + }, + + depositorAccountNumber: { + type: 'string', + pattern: '^[0-9]{4,17}$', + minLength: 4, + maxLength: 17, + example: '123456789', + description: 'Depositor bank account number (4–17 digits)', + }, + + documentUpload: { + type: 'object', + properties: { + documentGuid: { + type: 'string', + pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$', + description: 'UUID returned by the document upload endpoint', + }, + documentType: { + type: 'string', + enum: ['death_certificate', 'proof_of_age'], + description: 'Category of uploaded supporting document', + }, + filename: { + type: ['string', 'null'], + maxLength: 255, + description: 'Original filename reported by the client', + }, + }, + required: ['documentGuid', 'documentType'], + }, + }, + + properties: { + + // ─── Chapter 2: Policy Information (Screen 2, Item 1) ─────────────────── + policyInformation: { + type: 'object', + description: 'Insurance policy identification — Item 1 of VA Form 29-4125a', + additionalProperties: false, + properties: { + policyNumber: buildDefinitionReference('nsliPolicyNumber'), + }, + required: ['policyNumber'], + }, + + // ─── Chapter 3: Veteran Information (Screen 3, Items 5–7) ─────────────── + veteranInformation: { + type: 'object', + description: 'Information about the insured Veteran — Items 5, 6, 7 of VA Form 29-4125a', + additionalProperties: false, + properties: { + veteranFullName: buildDefinitionReference('fullName'), + veteranDateOfBirth: buildDefinitionReference('date'), + veteranPlaceOfDeath: { + type: 'string', + minLength: 1, + maxLength: 100, + example: 'Milwaukee, WI', + description: 'City and state or facility name and location where the Veteran died (Item 7)', + }, + }, + required: ['veteranFullName', 'veteranDateOfBirth', 'veteranPlaceOfDeath'], + }, + + // ─── Chapter 4: Beneficiary Information (Screens 4–6, Items 8–13) ─────── + beneficiaryInformation: { + type: 'object', + description: 'Personal information about the beneficiary — Items 8–13 of VA Form 29-4125a', + additionalProperties: false, + properties: { + beneficiaryFullName: buildDefinitionReference('fullName'), + relationshipToInsured: buildDefinitionReference('relationshipToInsured'), + beneficiaryDateOfBirth: buildDefinitionReference('date'), + beneficiarySsn: buildDefinitionReference('ssn'), + }, + required: [ + 'beneficiaryFullName', + 'relationshipToInsured', + 'beneficiaryDateOfBirth', + 'beneficiarySsn', + ], + }, + + // ─── Chapter 4 cont.: Beneficiary Contact (Screen 5, Items 11–12) ─────── + beneficiaryContact: { + type: 'object', + description: 'Contact information for the beneficiary or their guardian/fiduciary — Items 11, 12A, 12B', + additionalProperties: false, + properties: { + address: buildDefinitionReference('usAddress'), + addressIsGuardian: { + type: 'boolean', + description: 'True when the address provided is the guardian or fiduciary address, not the beneficiary address', + }, + daytimePhone: buildDefinitionReference('usPhone'), + emailAddress: { + type: ['string', 'null'], + minLength: 1, + maxLength: 100, + example: 'beneficiary@example.com', + description: 'Optional beneficiary email address (Item 12B)', + }, + }, + required: ['address', 'daytimePhone'], + }, + + // ─── Chapter 4 cont.: Submitter Role (Screens 5–6) ────────────────────── + submitterInformation: { + type: 'object', + description: 'Identifies whether the person submitting is the beneficiary, a guardian, or a fiduciary', + additionalProperties: false, + properties: { + submitterRole: buildDefinitionReference('submitterRole'), + guardianFiduciaryName: { + type: ['string', 'null'], + minLength: 1, + maxLength: 100, + example: 'Jane Smith', + description: 'Full name of the legal guardian or fiduciary (required when submitterRole is guardian or fiduciary)', + }, + guardianFiduciaryAddress: { + oneOf: [ + { $ref: '#/definitions/usAddress' }, + { type: 'null' }, + ], + description: 'Guardian or fiduciary mailing address (required when submitterRole is guardian or fiduciary)', + }, + guardianFiduciaryPhone: { + type: ['string', 'null'], + pattern: '^[0-9]{10}$', + minLength: 10, + maxLength: 10, + description: 'Guardian or fiduciary daytime phone number (required when submitterRole is guardian or fiduciary)', + }, + beneficiaryIsLegalEntity: { + type: ['boolean', 'null'], + description: 'True when the beneficiary is a firm, corporation, legal entity, or trustee (CL-06 trigger)', + }, + }, + required: ['submitterRole'], + }, + + // ─── Chapter 5: Settlement Options (Screens 7–9, Item 4 and Item 14) ──── + settlementOptions: { + type: 'object', + description: 'Insured Veteran payment option and beneficiary settlement option selection — Items 4 and 14', + additionalProperties: false, + properties: { + insuredSelectedOption: buildDefinitionReference('insuredSelectedOption'), + + // Single-select path: beneficiary selects exactly one option + settlementOption: { + type: ['string', 'null'], + enum: ['option2', 'option3', 'option4', null], + description: 'Settlement option selected by the beneficiary (single-select path) — Item 14', + }, + + // Split-option path: beneficiary selects two options when insured chose Option 1 + settlementOptionsSplit: { + type: ['array', 'null'], + items: { + type: 'string', + enum: ['option2', 'option3', 'option4'], + }, + minItems: 2, + maxItems: 2, + description: 'Two settlement options when beneficiary elects a split between two options (only valid when insuredSelectedOption is option1)', + }, + + installmentCount: { + type: ['integer', 'null'], + minimum: 36, + maximum: 240, + multipleOf: 12, + description: 'Number of monthly installments under Option 2 (36–240 in multiples of 12) — Item 14, Option 2 detail (Screen 8)', + }, + + noOptionSelected: { + type: 'boolean', + description: 'True when the beneficiary does not make a selection; VA defaults to insured option per form instructions', + }, + }, + required: ['insuredSelectedOption', 'noOptionSelected'], + }, + + // ─── Chapter 6: Document Uploads (Screens 10–11) ──────────────────────── + documentUploads: { + type: 'object', + description: 'Supporting documents uploaded by the beneficiary (death certificate and optional proof of age)', + additionalProperties: false, + properties: { + deathCertificate: { + $ref: '#/definitions/documentUpload', + description: 'Photocopy or scan of the Veteran death certificate or attending physician statement (always required)', + }, + proofOfAge: { + oneOf: [ + { $ref: '#/definitions/documentUpload' }, + { type: 'null' }, + ], + description: 'Driver license or birth certificate for proof of beneficiary age (required for Options 3 and 4 only)', + }, + }, + required: ['deathCertificate'], + }, + + // ─── Chapter 7: Direct Deposit (Screen 12) ─────────────────────────────── + directDeposit: { + type: 'object', + description: 'Direct deposit or check payment election and banking details', + additionalProperties: false, + properties: { + paymentMethod: buildDefinitionReference('paymentMethod'), + + financialInstitutionName: { + type: ['string', 'null'], + minLength: 1, + maxLength: 100, + example: 'First National Bank', + description: 'Name of the financial institution (required when paymentMethod is direct_deposit)', + }, + + financialInstitutionAddress: { + oneOf: [ + { $ref: '#/definitions/usAddress' }, + { type: 'null' }, + ], + description: 'Mailing address of the financial institution (required when paymentMethod is direct_deposit)', + }, + + financialInstitutionPhone: { + type: ['string', 'null'], + pattern: '^[0-9]{10}$', + minLength: 10, + maxLength: 10, + description: 'Telephone number of the financial institution (required when paymentMethod is direct_deposit)', + }, + + routingTransitNumber: { + type: ['string', 'null'], + pattern: '^[0-9]{9}$', + minLength: 9, + maxLength: 9, + description: 'Nine-digit ABA routing transit number (required when paymentMethod is direct_deposit); validated client-side with ABA mod-10 checksum', + }, + + accountType: { + type: ['string', 'null'], + enum: ['checking', 'savings', null], + description: 'Type of depositor account (required when paymentMethod is direct_deposit)', + }, + + depositorAccountNumber: { + type: ['string', 'null'], + pattern: '^[0-9]{4,17}$', + minLength: 4, + maxLength: 17, + description: 'Depositor bank account number (required when paymentMethod is direct_deposit); encrypted before persistence', + }, + }, + required: ['paymentMethod'], + }, + + // ─── Chapter 8: Signature and Certification (Screen 13, Items 15–16) ──── + signatureCertification: { + type: 'object', + description: 'Beneficiary certification and date signed — Items 15 and 16 of VA Form 29-4125a', + additionalProperties: false, + properties: { + certificationAccepted: { + type: 'boolean', + description: 'Item 15: Beneficiary, guardian, or fiduciary has read and certified the accuracy of the submitted information; must be true to submit', + }, + authenticatedVia: { + type: 'string', + enum: ['login_gov', 'id_me'], + description: 'Identity provider used to authenticate the submitter at IAL2/LOA3; recorded in lieu of wet ink signature pending Insurance Service policy confirmation (AQ-01)', + }, + dateSigned: buildDefinitionReference('date'), + }, + required: ['certificationAccepted', 'authenticatedVia', 'dateSigned'], + }, + + // ─── Metadata (system-generated at submission time) ────────────────────── + metadata: { + type: 'object', + description: 'System-generated submission metadata; not displayed to the user and not a form item', + additionalProperties: false, + properties: { + formId: { + type: 'string', + enum: ['VA_FORM_29_4125A'], + description: 'Registered form identifier', + }, + formVersion: { + type: 'string', + enum: ['DEC2024'], + description: 'Version of the PDF template this submission maps to', + }, + submissionSource: { + type: 'string', + enum: ['va_gov_digital_form'], + description: 'Source system that generated the submission', + }, + userUuid: { + type: 'string', + pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$', + description: 'Authenticated user UUID from the vets-api session', + }, + submittedAt: { + type: 'string', + format: 'date-time', + description: 'ISO-8601 timestamp at which the form was submitted', + }, + }, + required: ['formId', 'formVersion', 'submissionSource', 'userUuid', 'submittedAt'], + }, + }, + + required: [ + 'policyInformation', + 'veteranInformation', + 'beneficiaryInformation', + 'beneficiaryContact', + 'submitterInformation', + 'settlementOptions', + 'documentUploads', + 'directDeposit', + 'signatureCertification', + ], +}; + +export default schema; \ No newline at end of file