Skip to content

feat(msp-withdrawal -toggle): add logic to enable and disable withdrawal toggle - #2007

Draft
jdinh8124 wants to merge 1 commit into
mainfrom
msp-withrdrawl-tog
Draft

feat(msp-withdrawal -toggle): add logic to enable and disable withdrawal toggle#2007
jdinh8124 wants to merge 1 commit into
mainfrom
msp-withrdrawl-tog

Conversation

@jdinh8124

Copy link
Copy Markdown
Collaborator

Ticket

https://jiraent.cms.gov/browse/OY2-41235

Context

OneMAC already consumes the SMART Kafka topic and dispatches valid records by operationType, but MSP_RAI_WITHDRAWAL_TOGGLED was still using the default reservation path.

This event represents a CMS action performed in SMART. It is not a general package-status synchronization event. OneMAC must use it to enable or disable the State-side Formal RAI Response withdrawal action while preserving the package’s existing lifecycle status.

Business confirmed:

  • The applicable workflow point is Pending Second Clock; earlier SMART documentation referencing Pending First Clock was incorrect.
  • For CHIP, raiId identifies the most recent applicable RAI.
  • Medicaid has one applicable RAI, making it the most recent by default.

Solution

This PR implements the MSP_RAI_WITHDRAWAL_TOGGLED SMART event handler.

Event validation

The handler validates the event-specific fields:

  • spaWaiverId
  • id
  • origin: "SMART"
  • authority
  • createdAt
  • operationType: "MSP_RAI_WITHDRAWAL_TOGGLED"
  • raiId
  • raiName
  • raiWithdrawnToggle
  • raiWithdrawnToggleDate

Both Medicaid SPA and CHIP SPA packages are supported.

raiWithdrawnToggleDate is used as the authoritative event timestamp. createdAt is retained as a fallback for early producers that omit the event-specific timestamp.

Invalid events and business-resolution failures are published to the configured BigMAC error queue.

Package resolution

The handler operates only on an existing visible package:

  1. Resolve the package using spaWaiverId.
  2. Cross-check the result against payload.id.
  3. If no external-identifier match exists, fall back to id for a legacy OneMAC package that SMART has not touched.
  4. Backfill spaWaiverId when the ID fallback resolves an otherwise valid package.

The event is rejected when:

  • Neither identifier resolves an existing package.
  • spaWaiverId is ambiguous or belongs to another package.
  • The ID already has a conflicting external identifier.
  • The package is deleted.
  • The target is a hidden SMART reservation.
  • The authority differs from the existing package.

Unlike manual-record events, an RAI toggle does not create a reservation or new package.

Toggle behavior

For a current event, the handler updates:

  • raiWithdrawEnabled
  • raiId
  • raiName
  • raiWithdrawnToggleDate
  • makoChangedDate
  • Missing SMART identity fields when appropriate

The handler intentionally does not overwrite:

  • origin
  • seatoolStatus
  • cmsStatus
  • stateStatus
  • Split SPA creation metadata

Package status remains governed by the established OneMAC lifecycle and status-update paths.

When enabled, the existing OneMAC rules display:

  • Status sub-status: Withdraw Formal RAI Response - Enabled
  • Upload Subsequent Documents
  • Withdraw Formal RAI Response
  • Withdraw Package

These actions remain subject to existing package status, RAI-response, user-role, and locking safeguards.

Administrative Package Changes

Each event writes the existing toggle-withdraw-rai changelog shape.

Enabled events display:

  • Enable Formal RAI Response Withdraw
  • The SMART user who enabled the action
  • The SMART toggle date and timestamp

Disabled events display:

  • Disable Formal RAI Response Withdraw
  • The SMART user who disabled the action
  • The SMART toggle date and timestamp

The changelog also retains raiId, raiName, spaWaiverId, correlationId, and operationType for traceability.

Replay and ordering safeguards

  • Administrative event IDs are deterministic, preventing duplicate activity on Kafka retries.
  • Replaying the same event repairs a partial write without duplicating history.
  • Events older than the latest known toggle are retained in administrative history but cannot regress the current package state.
  • Conflicting events for the same timestamp are rejected to BigMAC.
  • OpenSearch failures are rethrown so Kafka can retry.

Flow

flowchart TD
  kafka[SMART Kafka event] --> envelope[Validate base envelope]
  envelope -->|invalid| bigmac[Publish to BigMAC]
  envelope --> dispatch[Dispatch MSP_RAI_WITHDRAWAL_TOGGLED]
  dispatch --> validate[Validate RAI toggle fields]
  validate -->|invalid| bigmac
  validate --> external[Resolve package by spaWaiverId]
  external -->|not found| fallback[Fall back to package id]
  external --> verify[Verify visible package and matching authority]
  fallback --> verify
  fallback -->|not found or conflict| bigmac
  verify --> order{Compare toggle timestamps}
  order -->|current| update[Update raiWithdrawEnabled and RAI metadata]
  order -->|stale| preserve[Preserve current package state]
  update --> activity[Upsert deterministic admin event]
  preserve --> activity
Loading

Feature flag rollout

The existing hide-withdraw-rai-response-toggle flag remains as a rollout and rollback control.

Recommended rollout:

  1. Deploy and validate SMART events in the feature environment.
  2. Enable the flag to hide the legacy CMS enable/disable controls.
  3. Repeat in main, val, and production.
  4. Confirm SMART publishing and State-side behavior in production.
  5. After an agreed soak period, remove:
    • Legacy CMS enable/disable actions
    • Legacy toggle forms and routes
    • Legacy backend submission handling
    • Obsolete FAQ instructions
    • The feature flag and related tests

The SMART consumer is not feature-gated, allowing event processing to be tested before the legacy controls are hidden.

Testing

Completed successfully:

  • bun run lint
  • bun run build
  • bun run build:lib
  • ./run test --run lib/lambda/smart
  • SMART handler, sink integration, and OpenSearch mapping tests
  • Package action-rule tests
  • Package status tests
  • Administrative Package Changes tests
  • Package action visibility tests

Coverage includes:

  • Enable and disable events
  • Medicaid and CHIP packages
  • External-identifier resolution
  • Legacy ID fallback and external-ID backfill
  • Missing, deleted, reserved, ambiguous, and conflicting packages
  • Invalid or missing RAI fields
  • Invalid event timestamps
  • Preservation of package status and origin
  • Correct administrative attribution and timestamp
  • Idempotent Kafka replay
  • Stale and out-of-order events
  • Partial OpenSearch failure and Kafka retry behavior

Deployment and QA notes

  1. Deploy the feature stage.
  2. Confirm the SMART event source mapping is enabled.
  3. Confirm BIGMAC_ERROR_QUEUE_URL is configured before testing invalid events.
  4. Publish an enable event for a package in the applicable Pending Second Clock workflow with a received Formal RAI Response.
  5. Confirm:
    • The existing package remains visible.
    • Its lifecycle status is unchanged.
    • Withdraw Formal RAI Response - Enabled appears.
    • State users receive the expected three package actions.
    • Administrative Package Changes shows the SMART user and toggle timestamp.
  6. Publish the corresponding disable event and verify the sub-status and withdrawal action are removed.
  7. Replay an event and verify that administrative history is not duplicated.

Normal deployment starts the consumer at LATEST. Previously published events require a deliberate replay using a new consumer group or a targeted data correction.

@jdinh8124 jdinh8124 self-assigned this Sep 2, 2026
@macpro-snyk-service-account

macpro-snyk-service-account commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔴 Lines 89.6% (🎯 90%)
⬆️ +0.03%
10685 / 11925
🔴 Statements 89.2% (🎯 90%)
⬆️ +0.02%
11376 / 12753
🟢 Functions 87.47% (🎯 85%)
⬆️ +0.05%
2696 / 3082
🔴 Branches 78.47% (🎯 80%)
⬇️ -0.03%
6739 / 8587
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
lib/lambda/setupIndex.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
lib/lambda/smart/mspRaiWithdrawalToggled.ts 90.35%
⬆️ +23.69%
76%
⬆️ +26.00%
100%
🟰 ±0%
91.66%
⬆️ +25.00%
73, 139, 142, 161, 184, 186, 204, 269-270, 317-318
lib/lambda/smart/parseSmartOnemacEvent.ts 94.73%
🟰 ±0%
90.9%
🟰 ±0%
100%
🟰 ±0%
94.73%
🟰 ±0%
54
lib/packages/shared-types/opensearch/changelog/index.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
lib/packages/shared-types/opensearch/main/index.ts 100%
🟰 ±0%
100%
🟰 ±0%
66.66%
🟰 ±0%
100%
🟰 ±0%
lib/packages/shared-utils/feature-flags.ts 100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
100%
🟰 ±0%
Generated in workflow #4976 for commit 23bafdd by the Vitest Coverage Report Action

@jdinh8124
jdinh8124 deployed to msp-withrdrawl-tog September 2, 2026 22:37 — with GitHub Actions Active
@jdinh8124
jdinh8124 deployed to msp-withrdrawl-tog September 2, 2026 22:37 — with GitHub Actions Active
@jdinh8124
jdinh8124 deployed to msp-withrdrawl-tog September 2, 2026 22:37 — with GitHub Actions Active
@jdinh8124 jdinh8124 changed the title feat(msp-withdraw-toggle): feat(msp-withdrawal -toggle): add logic to enable and disable withdrawal toggle Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants