From d906255a102d64817d2b216de2026ca60ca939b2 Mon Sep 17 00:00:00 2001 From: cameron testerman <11036339+voidspooks@users.noreply.github.com> Date: Sun, 26 Apr 2026 16:20:47 -0500 Subject: [PATCH] feat(22-1990n): 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/22-1990n/schema.js --- src/schemas/22-1990n/schema.js | 611 +++++++++++++++++++++++++++++++++ 1 file changed, 611 insertions(+) create mode 100644 src/schemas/22-1990n/schema.js diff --git a/src/schemas/22-1990n/schema.js b/src/schemas/22-1990n/schema.js new file mode 100644 index 00000000..ec518fa8 --- /dev/null +++ b/src/schemas/22-1990n/schema.js @@ -0,0 +1,611 @@ +const buildDefinitionReference = referenceId => ({ $ref: `#/definitions/${referenceId}` }); + +const schema = { + $schema: 'http://json-schema.org/draft-04/schema#', + type: 'object', + additionalProperties: false, + + definitions: { + ssn: { + type: 'string', + description: 'Social Security Number — 9 digits, no hyphens', + pattern: '^\\d{9}$', + minLength: 9, + maxLength: 9, + example: '123456789', + }, + + date: { + type: 'string', + format: 'date', + description: 'ISO 8601 date string (YYYY-MM-DD)', + pattern: '^\\d{4}-\\d{2}-\\d{2}$', + example: '1990-01-15', + }, + + phone: { + type: 'string', + description: '10-digit US phone number, digits only (no hyphens or spaces)', + pattern: '^\\d{10}$', + minLength: 10, + maxLength: 10, + example: '5551234567', + }, + + postalCode: { + type: 'string', + description: 'US ZIP code — 5 or 9 digits (5 or 5+4 with hyphen)', + pattern: '^\\d{5}(-\\d{4})?$', + minLength: 5, + maxLength: 10, + example: '12345', + }, + + usState: { + type: 'string', + description: 'Two-letter US state / territory / APO-FPO code', + enum: [ + 'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', + 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', + 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', + 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', + 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', + 'WY', + // Territories + 'PR', 'GU', 'VI', 'AS', 'MP', + // APO / FPO + 'AA', 'AE', 'AP', + ], + }, + + mailingAddress: { + type: 'object', + description: 'US mailing address', + additionalProperties: false, + required: ['street', 'city', 'state', 'postalCode'], + properties: { + street: { + type: 'string', + description: 'Street address (number and street)', + maxLength: 50, + minLength: 1, + example: '123 Main St', + }, + street2: { + type: ['string', 'null'], + description: 'Apartment or unit number (optional)', + maxLength: 20, + example: 'Apt 4B', + }, + city: { + type: 'string', + description: 'City', + maxLength: 30, + minLength: 1, + example: 'Springfield', + }, + state: buildDefinitionReference('usState'), + postalCode: buildDefinitionReference('postalCode'), + }, + }, + + schoolAddress: { + type: 'object', + description: 'School or training establishment address (all fields optional)', + additionalProperties: false, + properties: { + street: { + type: ['string', 'null'], + description: 'Street address of school', + maxLength: 50, + example: '500 University Ave', + }, + city: { + type: ['string', 'null'], + description: 'City of school', + maxLength: 30, + example: 'College Town', + }, + state: { + oneOf: [ + buildDefinitionReference('usState'), + { type: 'null' }, + ], + }, + postalCode: { + type: ['string', 'null'], + description: 'ZIP code of school', + pattern: '^\\d{5}(-\\d{4})?$', + maxLength: 10, + example: '12345', + }, + }, + }, + + directDeposit: { + type: 'object', + description: 'Direct deposit banking information (Part I, Item 7)', + additionalProperties: false, + properties: { + enrolling: { + type: 'boolean', + description: 'True if applicant is enrolling in direct deposit', + }, + accountType: { + type: 'string', + description: 'Bank account type', + enum: ['CHECKING', 'SAVINGS'], + }, + routingNumber: { + type: 'string', + description: 'ABA routing/transit number — exactly 9 digits', + pattern: '^\\d{9}$', + minLength: 9, + maxLength: 9, + example: '021000021', + }, + accountNumber: { + type: 'string', + description: 'Bank account number — up to 17 digits', + pattern: '^\\d{1,17}$', + minLength: 1, + maxLength: 17, + example: '1234567890', + }, + }, + }, + + trainingType: { + type: 'object', + description: 'Type of education or training elected (Part II, Item 8A) — at least one must be true', + additionalProperties: false, + properties: { + collegeOrSchool: { + type: 'boolean', + description: 'College or other school (including online courses)', + }, + apprenticeshipOJT: { + type: 'boolean', + description: 'Apprenticeship or on-the-job training', + }, + vocationalFlightTraining: { + type: 'boolean', + description: 'Vocational flight training', + }, + correspondence: { + type: 'boolean', + description: 'Correspondence', + }, + nationalTestReimbursement: { + type: 'boolean', + description: 'National test reimbursement (SAT, CLEP, etc.)', + }, + licensingCertificationTest: { + type: 'boolean', + description: 'Licensing or certification test reimbursement (MCSE, CCNA, EMT, NCLEX, etc.)', + }, + }, + }, + + flightTraining: { + type: 'object', + description: 'Flight training eligibility details (Part II, Item 8A conditional)', + additionalProperties: false, + properties: { + hasPrivatePilotLicense: { + type: 'boolean', + description: 'Applicant currently holds a private pilot\'s license', + }, + isATPCourse: { + type: 'boolean', + description: 'True if pursuing an Airline Transport Pilot (ATP) course; false if other flight training course', + }, + }, + }, + + servicePeriod: { + type: 'object', + description: 'One period of military service (Part III, Item 10)', + additionalProperties: false, + required: ['dateEnteredService', 'serviceComponent', 'serviceStatus'], + properties: { + dateEnteredService: { + $ref: '#/definitions/date', + description: 'Date entered service (Item 10A)', + }, + dateSeparated: { + type: ['string', 'null'], + format: 'date', + description: 'Date separated from service (Item 10B) — null if still on active duty', + pattern: '^\\d{4}-\\d{2}-\\d{2}$', + example: '2006-01-20', + }, + serviceComponent: { + type: 'string', + description: 'Service component (Item 10C)', + enum: [ + 'USA', // U.S. Army + 'USN', // U.S. Navy + 'USAF', // U.S. Air Force + 'USMC', // U.S. Marine Corps + 'USCG', // U.S. Coast Guard + 'USAR', // U.S. Army Reserve + 'ARNG', // U.S. Army National Guard + 'USNR', // U.S. Naval Reserve + 'AFRES', // U.S. Air Force Reserve + 'ANG', // U.S. Air National Guard + 'USMCR', // U.S. Marine Corps Reserve + 'CGRES', // U.S. Coast Guard Reserve + ], + }, + serviceStatus: { + type: 'string', + description: 'Service status during this period (Item 10D) — e.g., Active duty, Drilling reservist, IRR', + maxLength: 50, + minLength: 1, + example: 'Active duty', + }, + }, + }, + + documentUpload: { + type: 'object', + description: 'Reference to a document uploaded to S3 via the supporting documents endpoint', + additionalProperties: false, + required: ['name', 'confirmationCode'], + properties: { + name: { + type: 'string', + description: 'Original filename of the uploaded document', + maxLength: 255, + minLength: 1, + example: 'dd2863.pdf', + }, + confirmationCode: { + type: 'string', + description: 'UUID confirmation code returned by the document upload endpoint', + 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}$', + example: '550e8400-e29b-41d4-a716-446655440000', + }, + size: { + type: ['integer', 'null'], + description: 'File size in bytes', + minimum: 1, + example: 204800, + }, + }, + }, + }, + + // ───────────────────────────────────────────────────────────────── + // Top-level required fields + // ───────────────────────────────────────────────────────────────── + required: [ + 'personalInformation', + 'contactInformation', + 'trainingProgram', + 'serviceInformation', + 'additionalAssistance', + 'supportingDocuments', + 'certification', + ], + + properties: { + + // ─────────────────────────────────────────────────────────────── + // ELIGIBILITY SCREENER + // Not a form section stored to BIP, but captured for analytics + // and to guard against inadvertent submissions by ineligible + // applicants. + // ─────────────────────────────────────────────────────────────── + eligibilityScreener: { + type: 'object', + description: 'Eligibility screener answers — Screen 2', + additionalProperties: false, + required: ['enteredServiceOnOrAfterOct2003', 'signedNCSContract', 'electedEducationIncentive'], + properties: { + enteredServiceOnOrAfterOct2003: { + type: 'boolean', + description: 'Applicant first entered military service on or after October 1, 2003 (NCS eligibility criterion 1)', + }, + signedNCSContract: { + type: 'boolean', + description: 'Applicant signed an enlistment contract with DoD under the National Call to Service program (NCS eligibility criterion 2)', + }, + electedEducationIncentive: { + type: 'string', + description: 'Applicant elected an education incentive on DD Form 2863 (NCS eligibility criterion 3) — "YES", "NO", or "NOT_SURE"', + enum: ['YES', 'NO', 'NOT_SURE'], + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART I — PERSONAL INFORMATION + // PDF Items 1–4 (Screen 3) + // ─────────────────────────────────────────────────────────────── + personalInformation: { + type: 'object', + description: 'Part I — Personal identification information (PDF Items 1–4)', + additionalProperties: false, + required: [ + 'applicantSSN', + 'applicantSex', + 'applicantDOB', + 'applicantFirstName', + 'applicantLastName', + ], + properties: { + applicantSSN: { + $ref: '#/definitions/ssn', + description: 'Applicant Social Security Number (PDF Item 1)', + }, + applicantSex: { + type: 'string', + description: 'Sex of applicant (PDF Item 2) — verbatim PDF options', + enum: ['F', 'M'], + }, + applicantDOB: { + $ref: '#/definitions/date', + description: 'Applicant date of birth in YYYY-MM-DD format (PDF Item 3)', + }, + applicantFirstName: { + type: 'string', + description: 'Applicant first name (PDF Item 4)', + maxLength: 30, + minLength: 1, + pattern: "^[A-Za-z\\s'\\-]+$", + example: 'Jane', + }, + applicantMiddleInitial: { + type: ['string', 'null'], + description: 'Applicant middle initial — single letter (PDF Item 4)', + maxLength: 1, + pattern: '^[A-Za-z]$', + example: 'A', + }, + applicantLastName: { + type: 'string', + description: 'Applicant last name (PDF Item 4)', + maxLength: 35, + minLength: 1, + pattern: "^[A-Za-z\\s'\\-]+$", + example: 'Smith', + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART I — CONTACT INFORMATION + // PDF Items 5–7 (Screens 4–5) + // ─────────────────────────────────────────────────────────────── + contactInformation: { + type: 'object', + description: 'Part I — Contact information and direct deposit (PDF Items 5–7)', + additionalProperties: false, + required: ['mailingAddress'], + properties: { + mailingAddress: { + $ref: '#/definitions/mailingAddress', + description: 'Applicant mailing address (PDF Item 5)', + }, + homePhone: { + $ref: '#/definitions/phone', + description: 'Home phone number — 10 digits (PDF Item 6A)', + }, + mobilePhone: { + type: ['string', 'null'], + description: 'Mobile phone number — 10 digits, optional (PDF Item 6A)', + pattern: '^\\d{10}$', + minLength: 10, + maxLength: 10, + example: '5559876543', + }, + email: { + type: ['string', 'null'], + description: 'Email address — optional per PDF Item 6B', + format: 'email', + maxLength: 256, + example: 'jane.smith@example.com', + }, + directDeposit: { + $ref: '#/definitions/directDeposit', + description: 'Direct deposit banking information (PDF Item 7)', + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART II — TRAINING PROGRAM + // PDF Items 8A–8C (Screens 6–9) + // ─────────────────────────────────────────────────────────────── + trainingProgram: { + type: 'object', + description: 'Part II — Training program information (PDF Items 8A–8C)', + additionalProperties: false, + required: ['trainingType'], + properties: { + trainingType: { + $ref: '#/definitions/trainingType', + description: 'Type(s) of education or training selected (PDF Item 8A)', + }, + flightTraining: { + $ref: '#/definitions/flightTraining', + description: 'Flight training eligibility details — required when trainingType.vocationalFlightTraining is true (PDF Item 8A conditional)', + }, + schoolName: { + type: ['string', 'null'], + description: 'Name of school or training establishment — optional per PDF Item 8B "if known"', + maxLength: 100, + example: 'State University', + }, + schoolAddress: { + $ref: '#/definitions/schoolAddress', + description: 'School or training establishment address — optional, used for RPO routing (PDF Item 8B)', + }, + educationObjective: { + type: ['string', 'null'], + description: 'Educational or career objective — optional per PDF Item 8C "if known"', + maxLength: 500, + example: 'Bachelor of Arts in Accounting', + }, + highestRateAuthorization: { + type: 'boolean', + description: 'Authorization for VA to pay the highest monthly rate if eligible for more than one benefit (PDF Part II checkbox)', + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART III — SERVICE INFORMATION + // PDF Items 9A–10 (Screens 10–11) + // ─────────────────────────────────────────────────────────────── + serviceInformation: { + type: 'object', + description: 'Part III — Military service information (PDF Items 9A, 9B, 10)', + additionalProperties: false, + required: ['isActiveDuty', 'isOnTerminalLeave', 'servicePeriods'], + properties: { + isActiveDuty: { + type: 'boolean', + description: 'Applicant is currently on active duty (PDF Item 9A)', + }, + isOnTerminalLeave: { + type: 'boolean', + description: 'Applicant is currently on terminal leave just before discharge (PDF Item 9B)', + }, + servicePeriods: { + type: 'array', + description: 'One or more periods of military service (PDF Item 10)', + minItems: 1, + maxItems: 10, + items: { + $ref: '#/definitions/servicePeriod', + }, + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART IV — ADDITIONAL ASSISTANCE + // PDF Items 11A–11C (Screen 12) + // ─────────────────────────────────────────────────────────────── + additionalAssistance: { + type: 'object', + description: 'Part IV — Entitlement to additional types of assistance (PDF Items 11A–11C)', + additionalProperties: false, + required: ['isSeniorROTCScholar'], + properties: { + isSeniorROTCScholar: { + type: 'boolean', + description: 'Applicant is currently participating in a Senior ROTC scholarship program under 10 U.S.C. § 2107 (PDF Item 11A)', + }, + receivingFederalTuitionAssist: { + type: ['boolean', 'null'], + description: 'Applicant is receiving or anticipates receiving Federal Tuition Assistance from the Armed Forces or Public Health Service — shown for active duty claimants only (PDF Item 11B)', + }, + isCivilianGovEmployee: { + type: ['boolean', 'null'], + description: 'Screening question: applicant is a civilian employee of the U.S. Government — drives visibility of Item 11C', + }, + receivingAgencyFunds: { + type: ['boolean', 'null'], + description: 'Civilian government employee expects to receive agency/department funds for the same courses — shown for civilian government employees only (PDF Item 11C)', + }, + agencyFundsSource: { + type: ['string', 'null'], + description: 'Source of agency funds — required when receivingAgencyFunds is true (PDF Item 11C)', + maxLength: 100, + example: 'Department of Defense Tuition Assistance Program', + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // SUPPORTING DOCUMENTS + // PDF Part III Note — DD 2863, DD 214, voided check + // (Screens 13–15) + // ─────────────────────────────────────────────────────────────── + supportingDocuments: { + type: 'object', + description: 'Supporting document upload references (DD Form 2863, DD Form 214, voided check/deposit slip)', + additionalProperties: false, + required: ['dd2863Upload'], + properties: { + dd2863Upload: { + $ref: '#/definitions/documentUpload', + description: 'DD Form 2863 (National Call to Service Election of Options) — required for NCS eligibility verification', + }, + dd214Upload: { + type: 'array', + description: 'DD Form 214 Member 4 copies for all periods of active duty service — required unless applicant is on terminal leave pending issuance', + minItems: 0, + maxItems: 10, + items: { + $ref: '#/definitions/documentUpload', + }, + }, + voidedCheckUpload: { + type: ['object', 'null'], + description: 'Voided personal check or deposit slip to verify direct deposit banking information — required when directDeposit.enrolling is true', + additionalProperties: false, + properties: { + name: { + type: 'string', + description: 'Original filename of the uploaded document', + maxLength: 255, + minLength: 1, + example: 'voided-check.jpg', + }, + confirmationCode: { + type: 'string', + description: 'UUID confirmation code returned by the document upload endpoint', + 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}$', + example: '550e8400-e29b-41d4-a716-446655440001', + }, + size: { + type: ['integer', 'null'], + description: 'File size in bytes', + minimum: 1, + example: 102400, + }, + }, + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // PART V — CERTIFICATION + // PDF Items 12A–12B (Screen 16) + // ─────────────────────────────────────────────────────────────── + certification: { + type: 'object', + description: 'Part V — Applicant certification and signature (PDF Items 12A–12B)', + additionalProperties: false, + required: ['certificationChecked'], + properties: { + certificationChecked: { + type: 'boolean', + description: 'Applicant certified all statements are true and correct to the best of their knowledge and belief (PDF Part V — digital attestation replacing wet ink signature Item 12A)', + }, + esoConsultationChecked: { + type: ['boolean', 'null'], + description: 'Active duty applicant certified consultation with an Education Service Officer (ESO) regarding the education program (PDF Part V active duty addition — required when isActiveDuty is true)', + }, + }, + }, + + // ─────────────────────────────────────────────────────────────── + // METADATA + // Non-PDF fields used by vets-api / BIP pipeline + // ─────────────────────────────────────────────────────────────── + submissionTimestamp: { + type: ['string', 'null'], + format: 'date-time', + description: 'ISO 8601 timestamp set by vets-api at time of submission — maps to PDF Item 12B applicant signature date', + example: '2024-01-15T14:32:00Z', + }, + }, +}; + +export default schema; \ No newline at end of file