feat(sase): VIN list management view
A user-list-style table at /projects/sase/vin-decode/vins for inspecting
and managing decoded VINs. Pairs with sase.tr#34 (cache-clear + delete
endpoints).
Repo (lib/sase/vin-list.ts)
- listVinDecodes(filter, sort, page) — raw SQL with dynamic WHERE for
search (VIN/email), provider IN, success boolean, brand IDs, date
range. Joins users + brands, computes EXISTS(vehicles) per row so the
action menu knows whether DB delete is meaningful.
- KNOWN_PROVIDERS export.
Admin SDK
- clearVinCache({ vin, reason, founderId }) — POST cache-clear
- deleteVehicleByVin({ vin, reason, founderId }) — DELETE vehicle
- Result types: VinCacheClearResult, VinDeleteResult.
- SASE_ADMIN_ENDPOINTS list updated.
Panel routes
- POST /api/sase/vins/[vin]/cache-clear — auth + spoke-wired + reason
≥ 5 chars. Audit on both paths.
- DELETE /api/sase/vins/[vin] — same shape.
UI (/projects/sase/vin-decode/vins)
- URL-driven filters (VIN/email search, provider multi-select pills,
success/fail toggle) — sharable links.
- Sortable columns: Tarih (createdAt) and RT (responseTimeMs).
- Per-row cells: timestamp · VIN (mono) · brand slug+name · user email
(link to user detail) · provider badge (link to provider drill-down)
· ok/fail badge (fail title = errorMessage) · responseTimeMs ·
cacheSource from timings jsonb · action menu.
- Per-row action menu (gated on saseAdminWired):
[Cache] — opens reason modal, POSTs cache-clear
[DB] — only when vehicles row exists; opens reason modal,
destructive variant, DELETE
- Pager with prefix/postfix range + ←/→ links preserving filters.
Dashboard header gets a "VIN list →" pill next to Business/Trends.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>