Skip to content

Harden upgrade status completion lifecycle #185

Description

@badgerops-cortana-bot

Problem

The frontend now deduplicates completed upgrade reload handling, but the backend can still keep returning the last upgrade state as completed indefinitely from /api/v1/updates/status.

That makes clients responsible for remembering which completion they already handled. It also leaves stale operational state visible after the upgrade is already resolved.

Recommended backend hardening

Add a backend-side completion lifecycle so a completed upgrade does not remain an active status forever.

Reasonable implementation options:

  1. Add an acknowledgment endpoint, for example POST /api/v1/updates/status/ack.

    • Frontend calls it after observing completed and scheduling its reset.
    • Backend records that the completion was acknowledged by the client/session or clears the active status to idle.
    • Keep historical status available separately if needed.
  2. Add a status TTL.

    • Keep completed visible for a short window, such as 5-15 minutes.
    • After the TTL, /api/v1/updates/status returns idle while preserving the last upgrade details in history/logs.
  3. Prefer a stable upgrade_id.

    • Each upgrade request should produce a durable ID.
    • Status responses should include that ID so frontend and backend can reason about one specific upgrade completion instead of inferring identity from version/timestamps.

Acceptance criteria

  • /api/v1/updates/status does not return the same stale completed state forever.
  • Completed upgrade state remains observable long enough for the frontend to react.
  • The backend exposes a stable upgrade identity, preferably upgrade_id, or otherwise enough fields for clients to distinguish separate upgrade attempts.
  • Existing upgrade status tests cover completed-to-idle acknowledgment or TTL behavior.
  • Frontend reload dedupe remains a defensive fallback, not the primary lifecycle mechanism.

Context

Frontend mitigation was added in branch bugfix/upgrade-frontend-reset: it stores the handled completed-upgrade key in sessionStorage so a persisted backend completed response cannot create a reload loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions