# Uploads list and review dialog — 2026-09-07

The `/documents` Review / Correct again / Enter manually actions now open the shared `SibForm`
Review dialog used by Argus's form system, instead of appending an editor below the list.
The existing correction service and extraction rules are unchanged. Cancel, Close and Escape
dismiss without saving; dismissal is ignored while a correction is being submitted. Keyboard
focus enters the dialog, stays inside it, and returns to the invoking control. The background
is inert while reviewing. Source JSON remains available through the Details drawer.

The list now uses the existing Argus filter-bar pattern: filename search, company/unassigned
and processing-status filters, matching-row count, semantic status chips, full dates and
separate filename/size hierarchy. Existing evidence, triage, duplicate and quarantine actions
remain available. No new translation keys were necessary.

Validation: 38 tests passed (extraction review rendering, localization, design tokens and one
opt-in Playwright journey covering PT/EN at 1440px and 390px). Playwright runs a real Kestrel host
through the existing test factory against Preview, with a synthetic document that it removes
afterward. It checks filters, review prefill, invalid-total feedback, Escape, background inertness,
focus restoration and dialog width. It does not submit a financial correction or touch Main.
An initial test-cleanup defect left one synthetic Preview row; that exact row was subsequently
removed. Screenshots are under `local/artifacts/playwright/uploads-review/` (not committed).
The Impeccable mechanical detector reported no findings for the changed UI files.

To repeat browser verification, set `SIBYLA_PLAYWRIGHT_MODULE` to the installed Playwright
`index.mjs`, optionally set `SIBYLA_PLAYWRIGHT_BROWSER` to an installed Chromium executable,
then run:

```powershell
dotnet test tests/Sibyla.Tests.Browser/Sibyla.Tests.Browser.csproj --filter FullyQualifiedName~UploadsInteractionTests
```

Without the module variable, this opt-in browser test is explicitly skipped. It installs no
packages or browsers. Production-browser acceptance and deployment remain pending. These are
web/test-only changes; the concurrent extraction-spec, schema and bench edits were not modified.

## Follow-up: pending view, filters and discard

The default status is now **Pending work**: Processed, Confirmed duplicate and Discarded are
excluded. Select an individual status or All to retrieve them. Search, company/unassigned,
status, received month and channel are applied in the database before 25-row pagination, with
a matching-row count. The legacy `ListAsync` API stays unchanged for other callers. The page's
refreshes are serialized to avoid overlapping queries in its long-lived Blazor context.

**Discard / Descartar** is available for DeadLetter, HeldForPerson, Quarantined and
PossibleDuplicate, not running/retrying or already processed documents. Confirmation requires
a 1–500-character reason. The new integer status `Discarded = 10` uses the existing integer
column; no database migration is needed. `document.discard` records the actor, time, reason and
previous status. Local/cloud files, extraction answers, hold reasons and processing evidence
remain intact. Repeating the action is idempotent. Queued/running jobs, including channel jobs
with external correlation identifiers, block discard. Row locking serializes discard with
correction, re-extraction, assignment and release decisions. Discard is not a duplicate ruling
and performs no financial-register mutation. No restore/reopen action is introduced here.

Tests cover preservation, audit idempotency, required reason, active-job refusal, cross-tenant
denial, terminal-state guards, explicit/default filters, and an old failed upload behind 205
newer completed uploads. The Playwright journey also exercises the new default and an actual
discard of a synthetic Preview-only failed document, then finds it through Discarded. The
production sample named by the owner was not changed. This follow-up includes backend changes
and must be included in the release/checkpoint scope; the concurrent bench inputs remain untouched.

## Documents tab and reusable workspace

Uploads now lives at `/argus/documents/uploads`, alongside Financial Documents and Bank
Statements. All three pages share `ArgusDocumentTabs`; the Documents sidebar entry remains
active, and the separate Uploads entry is removed. Upload and Attach missing document links
target the new tab. Authenticated requests to `/documents` redirect there, retaining query
parameters and any preview PathBase.

`UploadsWorkspace` is a shared, non-routed component with an explicit `InitialStatus` parameter.
It owns the existing workflow and has no Argus route, title, tabs or module-name dependency.
`ArgusUploads` owns authentication/module gating and passes the query status into the workspace.
Backend tenant/company controls are unchanged. Other modules can host this component later;
this change does not introduce module-specific queues or processing rules.

Verification: all 145 Browser-suite tests passed with Playwright enabled. Coverage includes
the three routes and active navigation, legacy/query/PathBase redirects, anonymous access,
standalone workspace rendering without Argus enabled, and PT/EN desktop/mobile navigation,
Back/Forward, reload, review and discard. The Impeccable detector found no issues in the new
components. Production activation is still pending; no bench files were changed by this refactor.
