From 817556b8293ccfb4cf661b12b239c4243e74a04d Mon Sep 17 00:00:00 2001 From: cameron testerman <11036339+voidspooks@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:36:11 -0500 Subject: [PATCH] feat(10-0998): 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/10-0998/schema.js --- src/schemas/10-0998/schema.js | 598 ++++++++++++++++++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 src/schemas/10-0998/schema.js diff --git a/src/schemas/10-0998/schema.js b/src/schemas/10-0998/schema.js new file mode 100644 index 00000000..a1045368 --- /dev/null +++ b/src/schemas/10-0998/schema.js @@ -0,0 +1,598 @@ +const buildDefinitionReference = referenceId => ({ $ref: `#/definitions/${referenceId}` }); + +const schema = { + $schema: 'http://json-schema.org/draft-04/schema#', + type: 'object', + additionalProperties: false, + + definitions: { + // ISO 8601 date string (YYYY-MM-DD) + date: { + type: 'string', + format: 'date', + example: '2025-04-01', + }, + + // Nullable ISO 8601 date string + nullableDate: { + type: ['string', 'null'], + format: 'date', + example: '2025-04-01', + }, + + // Claimant type — drives all conditional routing in the experience + claimantType: { + type: 'string', + enum: [ + 'veteran-beneficiary-payer', + 'provider-not-under-contract', + 'provider-under-contract', + ], + description: 'Identifies the role of the person who received the VHA healthcare benefits decision notice. Drives screen routing: contracted providers are directed to Screen 3A; all others proceed through Screens 3B–8.', + }, + + // AMA review lane selection + reviewLane: { + type: 'string', + enum: [ + 'supplemental-claim', + 'higher-level-review', + 'board-appeal', + ], + description: 'The AMA review lane selected by the user on Screen 4. Only available to veteran-beneficiary-payer and provider-not-under-contract claimant types. Drives lane-specific content on Screens 5A/5B/5C and Next Steps summary on Screen 8.', + }, + + // Personalization status for Phase 2 API integration + personalizationStatus: { + type: 'string', + enum: [ + 'idle', + 'loading', + 'success', + 'error', + ], + description: 'Phase 2: tracks the status of the GET /v0/healthcare_benefits_decision_notice API call for decision date personalization.', + }, + + // VA facility name — Phase 2 personalization data + facilityName: { + type: ['string', 'null'], + maxLength: 200, + description: 'Phase 2: name of the VHA facility that issued the healthcare benefits decision. Sourced from VHA case management system. Null if unavailable.', + example: 'VA Boston Healthcare System', + }, + }, + + properties: { + + // ───────────────────────────────────────────────────────────────────────── + // Section 1 — Flow State + // Captures the user's navigation selections throughout the multi-screen + // informational experience. These are not submission fields; they drive + // conditional content display and downstream CTA routing. + // Corresponds to: Redux state shape (reducers/index.js) and sessionStorage + // key 'va-10-0998-flow-state'. + // ───────────────────────────────────────────────────────────────────────── + flowState: { + type: 'object', + additionalProperties: false, + description: 'Transient session state representing the user\'s selections as they navigate the VA Form 10-0998 informational content experience. Persisted to sessionStorage under key va-10-0998-flow-state. Contains no PII in Phase 1.', + properties: { + + // Screen 2 — Claimant-type radio selection + claimantType: { + ...buildDefinitionReference('claimantType'), + description: 'Screen 2 selection: which best describes your role in this claim. Drives routing to Screen 3A (contracted provider) or Screen 3B (all others). Required before navigation from Screen 2.', + }, + + // Screen 4 — Review lane radio selection + reviewLane: { + ...buildDefinitionReference('reviewLane'), + description: 'Screen 4 selection: which AMA review lane the user wants to pursue. Drives routing to Screens 5A (supplemental-claim), 5B (higher-level-review), or 5C (board-appeal). Required before navigation from Screen 4. Only meaningful when claimantType is veteran-beneficiary-payer or provider-not-under-contract.', + }, + + // Screen 5A — Records assistance checkbox (optional) + needsRecordsAssistance: { + type: 'boolean', + default: false, + description: 'Screen 5A optional checkbox: user indicates they need VA help gathering records. When true, surfaces VA Form 21-4142 and VA Form 21-4142a information in a VaSummaryBox. Per authoritative PDF: "If you want VA to help you gather records, complete and return the appropriate Release of Information Form: 21-4142 or 21-4142a."', + }, + }, + required: [], + }, + + // ───────────────────────────────────────────────────────────────────────── + // Section 2 — Personalization Data (Phase 2) + // Data returned by GET /v0/healthcare_benefits_decision_notice for + // authenticated LOA2 users. Stored in Redux state (in-memory only — + // NOT written to sessionStorage). All fields may be null if the VHA + // case management system is unavailable or the user is not authenticated. + // Contains PII: decisionDate and deadlineDate are Privacy Sensitive data. + // ───────────────────────────────────────────────────────────────────────── + personalization: { + type: 'object', + additionalProperties: false, + description: 'Phase 2 personalization data returned from GET /v0/healthcare_benefits_decision_notice for authenticated LOA2 users. Used to display a calculated review deadline date on Screens 1, 3B, and 8. All fields null in Phase 1 or when the VHA API is unavailable. PII: decisionDate and deadlineDate are Privacy Sensitive. Stored in Redux state only — not in sessionStorage.', + properties: { + + // ISO 8601 date of the most recent VHA healthcare benefits decision + decisionDate: { + ...buildDefinitionReference('nullableDate'), + description: 'Phase 2: ISO 8601 date string of the user\'s most recent VHA healthcare benefits decision. Sourced from VHA case management system via HealthcareBenefitsDecisionNoticeService. Null if unavailable (API error, no decision found, or user not authenticated at LOA2). Displayed as "Month DD, YYYY" in UI per accessibility requirement.', + }, + + // Server-calculated deadline date: decisionDate + 365 days + deadlineDate: { + ...buildDefinitionReference('nullableDate'), + description: 'Phase 2: server-calculated deadline date — decisionDate + 365 days. Calculated server-side in vets-api to ensure consistency and prevent client clock manipulation. Null when decisionDate is null. Displayed as "Month DD, YYYY" in VaAlert on Screens 1, 3B, and 8.', + }, + + // VHA facility that issued the decision + facilityName: { + ...buildDefinitionReference('facilityName'), + description: 'Phase 2: name of the VHA facility that issued the healthcare benefits decision. May be null initially even when decisionDate is available, depending on VHA case management system data completeness.', + }, + + // Phase 3: provider contract status auto-detected from VHA contract management system + claimantCategory: { + type: ['string', 'null'], + enum: [ + 'veteran-beneficiary-payer', + 'provider-not-under-contract', + 'provider-under-contract', + null, + ], + description: 'Phase 3: provider contract status returned from the VHA contract management system. When non-null, used to pre-select the claimant-type radio on Screen 2. Null in Phase 1 and Phase 2. Values mirror the claimantType enum for direct mapping.', + }, + + // API call status for frontend loading/error state handling + personalizationStatus: { + ...buildDefinitionReference('personalizationStatus'), + description: 'Phase 2: tracks the lifecycle of the GET /v0/healthcare_benefits_decision_notice API call. idle = not yet called; loading = in flight; success = response received; error = non-200 response or network failure. On error, the frontend falls back to static deadline text with no user-facing error message.', + }, + }, + required: [], + }, + + // ───────────────────────────────────────────────────────────────────────── + // Section 3 — Analytics Event Schema + // Documents the GA4 event payload shape for all tracked interactions. + // Not submitted to vets-api; used here to formalize the event contract + // between analytics.js and the GA4 platform. Stored transiently in + // platform/monitoring/record-event call payloads only. + // ───────────────────────────────────────────────────────────────────────── + analyticsEvents: { + type: 'object', + additionalProperties: false, + description: 'Formal schema for GA4 analytics event payloads emitted by the 10-0998 application via platform/monitoring/record-event. Not transmitted to vets-api. Documents the event contract for analytics.js. All event properties contain no PII.', + properties: { + + // Screen view events — one per screen, fired on route mount + screenView: { + type: 'object', + additionalProperties: false, + description: 'Fired on componentDidMount / useEffect on each screen route change.', + properties: { + event: { + type: 'string', + enum: ['nav-10-0998-screen-view'], + }, + screenName: { + type: 'string', + enum: [ + 'introduction', + 'claimant-type-selector', + 'contracted-provider-guidance', + 'review-options', + 'lane-selector', + 'supplemental-claim', + 'higher-level-review', + 'board-appeal', + 'representative-help', + 'missed-deadline', + 'next-steps', + ], + }, + }, + required: ['event', 'screenName'], + }, + + // Claimant type selection event + claimantTypeSelected: { + type: 'object', + additionalProperties: false, + description: 'Fired when user makes a claimant-type selection on Screen 2.', + properties: { + event: { + type: 'string', + enum: ['10-0998-claimant-type-selected'], + }, + claimantType: buildDefinitionReference('claimantType'), + }, + required: ['event', 'claimantType'], + }, + + // Review lane selection event + laneSelected: { + type: 'object', + additionalProperties: false, + description: 'Fired when user makes a review lane selection on Screen 4.', + properties: { + event: { + type: 'string', + enum: ['10-0998-lane-selected'], + }, + lane: buildDefinitionReference('reviewLane'), + }, + required: ['event', 'lane'], + }, + + // CTA click event — downstream form link activation + ctaClick: { + type: 'object', + additionalProperties: false, + description: 'Fired when user clicks a VaLinkAction CTA to a downstream form on Screen 8.', + properties: { + event: { + type: 'string', + enum: ['10-0998-cta-click'], + }, + destination: { + type: 'string', + enum: [ + 'higher-level-review', + 'board-appeal', + 'supplemental-claim', + ], + }, + screen: { + type: 'string', + enum: ['next-steps', 'supplemental-claim', 'higher-level-review', 'board-appeal'], + }, + }, + required: ['event', 'destination', 'screen'], + }, + + // Records assistance selection event + recordsAssistanceSelected: { + type: 'object', + additionalProperties: false, + description: 'Fired when user checks or unchecks the records assistance checkbox on Screen 5A.', + properties: { + event: { + type: 'string', + enum: ['10-0998-records-assistance-selected'], + }, + value: { + type: 'boolean', + }, + }, + required: ['event', 'value'], + }, + + // Missed deadline page view event + missedDeadlinePageViewed: { + type: 'object', + additionalProperties: false, + description: 'Fired when user views Screen 7 (Missed Deadline).', + properties: { + event: { + type: 'string', + enum: ['10-0998-missed-deadline-page-viewed'], + }, + }, + required: ['event'], + }, + + // Validation error event + validationError: { + type: 'object', + additionalProperties: false, + description: 'Fired when a required radio selection is missing and user attempts to navigate forward.', + properties: { + event: { + type: 'string', + enum: ['10-0998-validation-error'], + }, + field: { + type: 'string', + enum: ['claimant-type', 'review-lane'], + }, + screen: { + type: 'string', + enum: ['claimant-type-selector', 'lane-selector'], + }, + }, + required: ['event', 'field', 'screen'], + }, + + // Print event + printPage: { + type: 'object', + additionalProperties: false, + description: 'Fired when user activates the Print this page button on Screen 8.', + properties: { + event: { + type: 'string', + enum: ['10-0998-print-page'], + }, + screen: { + type: 'string', + enum: ['next-steps'], + }, + }, + required: ['event', 'screen'], + }, + + // Phase 2 — personalization load event + personalizationLoaded: { + type: 'object', + additionalProperties: false, + description: 'Phase 2: fired after GET /v0/healthcare_benefits_decision_notice resolves, indicating whether personalization data was successfully loaded.', + properties: { + event: { + type: 'string', + enum: ['10-0998-personalization-loaded'], + }, + status: { + type: 'string', + enum: ['success', 'error'], + }, + }, + required: ['event', 'status'], + }, + }, + required: [], + }, + + // ───────────────────────────────────────────────────────────────────────── + // Section 4 — API Response Schema (Phase 2) + // Documents the shape of the GET /v0/healthcare_benefits_decision_notice + // JSON:API response as consumed by the vets-website frontend. + // This section is informational for vets-api model validation alignment. + // ───────────────────────────────────────────────────────────────────────── + decisionNoticeApiResponse: { + type: 'object', + additionalProperties: false, + description: 'Phase 2: documents the JSON:API response envelope for GET /v0/healthcare_benefits_decision_notice. Used for vets-api serializer contract alignment and frontend action creator type-checking. Not submitted — this is an inbound API response schema.', + properties: { + + data: { + type: 'object', + additionalProperties: false, + description: 'JSON:API data envelope for the healthcare benefits decision notice personalization response.', + properties: { + + id: { + type: ['string', 'null'], + description: 'JSON:API resource id. Null for this singleton resource (no persisted record id).', + }, + + type: { + type: 'string', + enum: ['healthcare_benefits_decision_notice'], + description: 'JSON:API resource type identifier.', + }, + + attributes: { + type: 'object', + additionalProperties: false, + description: 'Personalization attributes returned from the VHA case management system via vets-api HealthcareBenefitsDecisionNoticeService.', + properties: { + + decisionDate: { + ...buildDefinitionReference('nullableDate'), + description: 'ISO 8601 date of the user\'s most recent VHA healthcare benefits decision. Null if no decision is found or VHA system is unavailable.', + }, + + deadlineDate: { + ...buildDefinitionReference('nullableDate'), + description: 'Server-calculated review deadline: decisionDate + 365 days. Calculated in vets-api, not client-side. Null when decisionDate is null.', + }, + + facilityName: { + ...buildDefinitionReference('facilityName'), + description: 'Name of the VHA facility that issued the decision. Phase 2 — may be null initially.', + }, + + claimantCategory: { + type: ['string', 'null'], + enum: [ + 'veteran-beneficiary-payer', + 'provider-not-under-contract', + 'provider-under-contract', + null, + ], + description: 'Phase 3 addition: provider contract status from VHA contract management system. Null in Phase 1 and Phase 2.', + }, + }, + required: ['decisionDate', 'deadlineDate', 'facilityName', 'claimantCategory'], + }, + }, + required: ['id', 'type', 'attributes'], + }, + }, + required: ['data'], + }, + + // ───────────────────────────────────────────────────────────────────────── + // Section 5 — Feature Flag Configuration + // Documents the Flipper feature flag names and their expected boolean + // values as consumed by vets-website App.jsx and vets-api controllers. + // Included here to provide a single source of truth for flag naming + // across the vets-json-schema contract. + // ───────────────────────────────────────────────────────────────────────── + featureFlags: { + type: 'object', + additionalProperties: false, + description: 'Flipper feature flag values as returned by GET /v0/feature_toggles and consumed by App.jsx. Both flags default to false (disabled). Flag 1 gates the entire application. Flag 2 gates Phase 2 personalization independently.', + properties: { + + // Primary application gate — Phase 1 + healthcareBenefitsDecisionRightsEnabled: { + type: 'boolean', + default: false, + description: 'Primary Flipper gate for the entire VA Form 10-0998 digital notice application. Corresponds to Flipper flag: healthcare_benefits_decision_rights_enabled. When false, App.jsx renders the fallback VaAlert with links to the PDF and /decision-reviews/. When true, the full multi-screen experience renders.', + }, + + // Personalization gate — Phase 2 + healthcareBenefitsDecisionRightsPersonalizationEnabled: { + type: 'boolean', + default: false, + description: 'Phase 2 Flipper gate for the personalization feature (authenticated GET /v0/healthcare_benefits_decision_notice call). Corresponds to Flipper flag: healthcare_benefits_decision_rights_personalization_enabled. When false, all users see static deadline text regardless of authentication status. Phase 1 flag must be true before this flag is meaningful.', + }, + }, + required: [], + }, + + // ───────────────────────────────────────────────────────────────────────── + // Section 6 — Downstream Form References + // Documents the downstream VA.gov form applications that the 10-0998 + // experience links to from Screens 5A/5B/5C and Screen 8. + // These are external links — not submission targets owned by this team. + // Included for contract documentation purposes. + // ───────────────────────────────────────────────────────────────────────── + downstreamFormLinks: { + type: 'object', + additionalProperties: false, + description: 'Documents the downstream VA.gov form application URLs linked from the 10-0998 informational experience. These applications are owned by separate teams and are not modified by this project. URLs are stable VA.gov routes; this team must be notified of any URL changes by the owning teams.', + properties: { + + higherLevelReview: { + type: 'object', + additionalProperties: false, + description: 'VA Form 20-0996 — Decision Review Request: Higher-Level Review. Linked from Screen 5B and Screen 8 (next-steps when lane = higher-level-review).', + properties: { + formNumber: { + type: 'string', + enum: ['20-0996'], + }, + vaGovUrl: { + type: 'string', + enum: ['/decision-reviews/higher-level-review/'], + description: 'VA.gov application URL for VA Form 20-0996. Owned by the Decision Reviews team.', + }, + }, + required: ['formNumber', 'vaGovUrl'], + }, + + boardAppeal: { + type: 'object', + additionalProperties: false, + description: 'VA Form 10182 — Decision Review Request: Board Appeal (Notice of Disagreement). Linked from Screen 5C and Screen 8 (next-steps when lane = board-appeal). Also includes BVA mailing address and fax from authoritative PDF.', + properties: { + formNumber: { + type: 'string', + enum: ['10182'], + }, + vaGovUrl: { + type: 'string', + enum: ['/decision-reviews/board-appeal/'], + description: 'VA.gov application URL for VA Form 10182. Owned by the Decision Reviews team.', + }, + bvaMailingAddress: { + type: 'object', + additionalProperties: false, + description: 'BVA mailing address verbatim from VA Form 10-0998 APR 2025 authoritative PDF.', + properties: { + line1: { + type: 'string', + enum: ['Board of Veterans\' Appeals'], + }, + poBox: { + type: 'string', + enum: ['P.O. Box 27063'], + }, + city: { + type: 'string', + enum: ['Washington'], + }, + state: { + type: 'string', + enum: ['DC'], + }, + zip: { + type: 'string', + enum: ['20038'], + }, + }, + required: ['line1', 'poBox', 'city', 'state', 'zip'], + }, + bvaFaxNumber: { + type: 'string', + enum: ['844-678-8979'], + description: 'BVA fax number verbatim from VA Form 10-0998 APR 2025 authoritative PDF.', + }, + bvaWebsite: { + type: 'string', + enum: ['https://www.bva.va.gov/'], + description: 'BVA public website URL verbatim from VA Form 10-0998 APR 2025 authoritative PDF.', + }, + }, + required: ['formNumber', 'vaGovUrl', 'bvaMailingAddress', 'bvaFaxNumber', 'bvaWebsite'], + }, + + supplementalClaim: { + type: 'object', + additionalProperties: false, + description: 'Supplemental Claim lane. Currently no single VA.gov URL for the supplemental claim — user is directed to review their decision notice letter for submission instructions. VA Forms 21-4142 and 21-4142a are referenced for records authorization.', + properties: { + vaGovUrl: { + type: ['string', 'null'], + description: 'VA.gov application URL for Supplemental Claim. May be null if no consolidated VA.gov application URL is available; falls back to decision notice letter instructions per authoritative PDF.', + }, + recordsReleaseForms: { + type: 'array', + description: 'VA forms for authorizing VA to gather records on behalf of the claimant. Per authoritative PDF: "If you want VA to help you gather records, complete and return the appropriate Release of Information Form."', + items: { + type: 'object', + additionalProperties: false, + properties: { + formNumber: { + type: 'string', + enum: ['21-4142', '21-4142a'], + }, + formName: { + type: 'string', + enum: [ + 'Authorization to Disclose Information to the Department of Veterans Affairs (VA)', + 'General Release for Medical Provider Information to the Department of Veterans Affairs (VA)', + ], + }, + }, + required: ['formNumber', 'formName'], + }, + minItems: 2, + maxItems: 2, + }, + }, + required: ['recordsReleaseForms'], + }, + + representativeSearch: { + type: 'object', + additionalProperties: false, + description: 'Accredited representative search — linked from Screen 6 and Screen 8. Database URL verbatim from VA Form 10-0998 APR 2025 authoritative PDF. Note: eBenefits link is subject to update per Open Question OQ-7 in Architecture Intent.', + properties: { + accreditationDatabaseUrl: { + type: 'string', + enum: ['http://www.va.gov/ogc/apps/accreditation/index.asp'], + description: 'Accredited VSO/attorney/claims agent search database. URL verbatim from authoritative PDF, Page 2.', + }, + eBenefitsUrl: { + type: 'string', + enum: ['http://www.ebenefits.va.gov'], + description: 'eBenefits URL from authoritative PDF. Subject to update to VA.gov representative appointment flow per Architecture Intent Open Question OQ-7. Flag for human review before Phase 1 content finalization.', + }, + }, + required: ['accreditationDatabaseUrl'], + }, + }, + required: [], + }, + }, + + required: ['flowState'], +}; + +export default schema; \ No newline at end of file