Filterable by template name, status (success/error/dry_run/skipped), and
date range. Sortable by all columns. Expandable rows show blockers/warnings.
Checksum displayed as first 8 chars with full hash on hover tooltip.
Client-side CSV export. 50 records per page with prev/next pagination.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend (web/routers/verify.py): POST /send (creates envelope from template),
GET /status/{id} (polls envelope state), POST /void/{id} (voids test envelope).
Registered in app.py. 7 tests passing.
Frontend (verification.js): table of migrated templates, Send Test button opens
dialog with pre-filled name/email from settings, polling every 5s, per-row
status updates (Sent → Delivered → Verified), Void button for cleanup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dedicated view surfacing all templates with blockers (migration will fail)
and warnings (migration with caveats). Each blocker item shows all error
messages; each warning item has a Migrate Anyway button and View Detail link.
Nav badge count driven by state.issueCount (updated when templates load).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend: add blockers[] and warnings[] to GET /api/templates/status. Calls
validate_template() on downloaded templates; returns empty lists if not
downloaded. 3 new tests (10 total, all passing).
Frontend (templates.js): filterable/sortable table with readiness badges
(Blocked/Caveats/Ready/Migrated/Needs Update), bulk-select toolbar,
per-row migrate/detail buttons, and template detail view with 3 tabs
(Overview, Issues, Migration History).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Projects stored in localStorage (key: migrator_projects). CRUD: create,
list, setActive, delete. Switcher modal opens automatically on first run
when no projects exist. Active project name displayed in nav footer and
project button. Deleting a project requires confirmation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>