Skip to content

fix(risk_acceptance): reinstate findings when expiration date updated via API#15147

Open
Jino-T wants to merge 1 commit into
bugfixfrom
fix/risk-acceptance-reinstate-on-api-update-bugfix
Open

fix(risk_acceptance): reinstate findings when expiration date updated via API#15147
Jino-T wants to merge 1 commit into
bugfixfrom
fix/risk-acceptance-reinstate-on-api-update-bugfix

Conversation

@Jino-T

@Jino-T Jino-T commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

[sc-13436]

Summary

  • RiskAcceptanceSerializer.update() never called ra_helper.reinstate() when expiration_date changed, unlike the legacy Django view (engagement/views.py:1308-1310) which does so correctly.
  • This caused two related bugs:
    1. Findings stay Active after extending an expired RA — when a user edits the expiration date from a past date to a future date via the API (Edit Risk Acceptance form in the UI), reinstate() is never called, so findings remain active=True / risk_accepted=False instead of being set back to inactive/risk-accepted.
    2. Findings stay Inactive on subsequent expiry cycles — because reinstate() was never called, expiration_date_handled was never cleared. The Celery expiration task queries with expiration_date_handled__isnull=True, so the RA is permanently excluded from every future expiry run and findings are never reactivated when the RA expires again.

Fix

Capture old_expiration_date before super().update(), then call ra_helper.reinstate() when the date changes — matching the logic that already exists in the legacy Django view.

old_expiration_date = self.instance.expiration_date
instance = super().update(instance, validated_data)
...
if instance.expiration_date != old_expiration_date:
    ra_helper.reinstate(instance, old_expiration_date)

reinstate() handles both outcomes internally: it reinstates findings (only when expiration_date_handled is set) and unconditionally clears expiration_date_handled and expiration_date_warned, making the RA eligible for the next Celery expiry cycle.

Test plan

  • Edit a Risk Acceptance with an expired date to a future date via the API — verify findings become active=False / risk_accepted=True
  • Confirm expiration_date_handled is None after the update — verify the Celery task will pick it up on the next expiry cycle
  • Edit a fresh (never-expired) RA's date — verify findings are unchanged and expiration_date_handled stays None

🤖 Generated with Claude Code

… via API

RiskAcceptanceSerializer.update() never called ra_helper.reinstate() when
expiration_date changed, unlike the legacy Django view which does so at
engagement/views.py. This caused two bugs reported together:

1. Findings stayed Active after a user updated the expiration date from a
   past date to a future date via the Edit Risk Acceptance form (Vue UI).
   reinstate() sets them back to inactive/risk_accepted.

2. Findings stayed Inactive on subsequent expiry cycles. Because reinstate()
   was never called, expiration_date_handled was never cleared. The Celery
   expiration task filters on expiration_date_handled__isnull=True, so the
   RA was permanently excluded from every future expiry run.

Fix: capture old_expiration_date before super().update(), then call
ra_helper.reinstate() when the date changes — matching the logic that
already existed in the legacy view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Jino-T Jino-T requested review from Maffooch and mtesauro as code owners July 2, 2026 21:00
@github-actions github-actions Bot added the apiv2 label Jul 2, 2026

@mtesauro mtesauro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants