deckhearth/.convoys/scanner-correctness-polish.md

112 lines
3.6 KiB
Markdown
Raw Normal View History

---
name: scanner-correctness-polish
classification: infra-only
success_metric: |
Mark-Owned is idempotent (in-flight lock per queue row); bulk toolbar no
longer uses setTimeout(..., 100); pages/scanner.js imports lib/use-auth
not legacy auth-context; POST /api/collections/[identifier]/cards calls
logCollectionActivity('card_added', …).
skip:
- ia
- ux
- visual
- a11y
- design
status: shipped
created: 2026-05-27
---
# Convoy: scanner-correctness-polish
**As-shipped:** PR #41 (2026-05-27). Idempotent Mark-Owned, bulk toolbar race fix, `lib/use-auth` import, activity logging.
Fix scanner-page correctness bugs without changing UX or visual design.
## Why
The scanner audit surfaced non-security bugs that cause duplicate adds,
racey bulk actions, a stale auth import, and missing activity logs. These
are small fixes with high reliability impact during bulk scanning sessions.
## Scope
### In scope
- **`pages/scanner.js`**
- Line 8: change import from legacy `lib/auth-context` to `lib/use-auth`
(should have been swept by `single-auth-provider`; scanner was missed or
regressed).
- **Mark-Owned idempotency** — in-flight lock per queue row so double-tap
/ double-click cannot duplicate POSTs.
- **Bulk toolbar** — remove `setTimeout(..., 100)` race; await or use
proper batch completion signal.
- **`pages/api/collections/[identifier]/cards.js`** — POST handler calls
`logCollectionActivity(collectionId, userId, 'card_added', details)` per
AGENTS.md convention.
### Out of scope
- **Scanner UX redesign** — convoy `redesign-scanner-flow` (#4).
- **Copy / vocabulary** — convoy `rename-collections-vocabulary` (#5).
- **OCR / identify pipeline** — convoys #2#3.
- **Visual or a11y changes** — none intended; diff should be behavior-only.
## Roles invoked
1. `role-architect` — single brief (lightweight; may be parent-owned given
infra-only classification).
2. `role-implementer` — one brief.
3. `role-reviewer` — post-PR only (design + a11y skipped).
## Todos
- [ ] Architect: brief-1 with exact line targets
- [ ] Fix use-auth import on scanner page
- [ ] Add per-row in-flight lock for Mark-Owned
- [ ] Replace setTimeout bulk-toolbar pattern
- [ ] Wire logCollectionActivity on collection card POST
## Operator action required
**None.**
## Multitask dispatch
Single brief — no implementer fan-out.
**Cross-convoy parallelism:** after #1 merges, run alongside **#2 Brief 1**
and **#5 Brief 1** — disjoint files (`pages/scanner.js` vs migrations vs
copy sweep). Coordinate if both #6 and #5 touch `pages/scanner.js` (IA
should sequence copy sweep after correctness or split files in briefs).
Post-PR audit:
```
/multitask role-reviewer
```
Group id: `audit-scanner-correctness-polish-<pr>`.
## CI impact
| Workflow / job | Behavior |
| --- | --- |
| `ci.yml` | Standard lint + vitest; no new gates. |
| `preview-smoke.yml` | Fires. |
| `visual-diff.yml` | **May fire** if `pages/scanner.js` changes — behavior-only diff should not move pixels; baseline swallow if triggered. |
## Known constraints
- **`logCollectionActivity` import** — use existing helper from
permission-middleware or documented activity module; match sibling handlers.
- **No UX copy changes** — button labels stay as-is until #5 (or avoid
overlapping scanner.js edits between #5 and #6).
## Acceptance criteria
1. `pages/scanner.js` imports from `lib/use-auth` only.
2. Double-click Mark-Owned produces one POST.
3. Bulk toolbar actions complete without setTimeout race.
4. Collection card POST emits activity log row.
5. Vitest 21/21; lint baseline preserved.