Skip to content

bug: lastScanAt not persisted for fully-empty scans, breaking hasCompletedScan on reopen #271

Description

@guyghost

Summary

lastScanAt is reconstructed on panel init from persisted connector statuses, but background/index.ts writes no status row when a connector returns zero missions with no error. When an entire scan returns zero missions across all connectors, no durable trace is written, so on panel reopen controller.lastScanAt reverts to null and hasCompletedScan is false. As a result the feed's scanned-empty operational story (added in PR #270) never appears for its target scenario after a reopen — the user instead sees the never-scanned-empty "Lancez un premier scan" state despite having just scanned.

Surfaced by Codex review on PR #270 (thread on apps/extension/src/ui/pages/FeedPage.svelte:447).

Steps to reproduce

  1. Ensure every configured connector is connected but returns zero missions for the current profile (or temporarily point connectors at empty result sets).
  2. Trigger a scan from the side panel and let it complete successfully.
  3. Observe the hero shows the scanned-empty / "Aucune correspondance" story (correct, in-memory lastScanAt is set).
  4. Close the side panel and reopen it.
  5. Observe the hero now shows the never-scanned-empty / "Lancez un premier scan" story.

Expected behavior

A successfully completed scan should leave a durable trace so hasCompletedScan stays true after a panel reopen, and the scanned-empty story continues to render until the next state change.

Area

Extension

Browser

Chrome (MV3)

Logs or screenshots

Design decision required (do not implement blindly): pick one approach and reconcile it with src/models/scan-lifecycle.model.md.

  • Option A — scan-level timestamp: persist a lastScanCompletedAt value in chrome.storage.local, written by the background after every successful scan regardless of mission count, and read on init. Additive and low-risk, but introduces a parallel signal next to the connector-status-derived lastScanAt; the model must define which is canonical.
  • Option B — durable zero-result connector rows: make background/index.ts write a done / missionsCount: 0 status row for connectors that were scanned successfully but returned nothing. This requires the scan result to carry the list of attempted connectors (today the status map is built only from missions + errors). Touches the scan-result persistence shape; higher risk.

Either way, update scan-lifecycle.model.md to specify whether "scan completed" is a connector-level or scan-level fact and how it coexists with the existing connector-status-derived lastScanAt.

Within-session behavior already works (handleScanFeedComplete sets lastScanAt in memory); only cross-session durability is broken.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions