Tracker — Manual Add Permit (2026-07-28)

Stephaney (and UP admins) can now add brand-new permits to the Overdue Task Force tracker that never appeared in a JES export.

  • POST /tracker/records (entirely-api c232bae) — gated like the uploads (_upload_allowed: up_owner/up_admin + TRACKER_UPLOAD_USERS). Zone validation via shared _normalize_zone (accepts JES labels, workbook tab spellings RICH/ROA/“VA BEACH”, tracker codes). 409 on duplicates, days_on_bw auto-computed from end date, create change logged (revert blocked — close instead).
  • Portal ”+ Add Permit” button + modal on the tracker page (entirely-portal ae1e6b9), same can-upload gate as the upload bar.
  • upload-overdue branch-tab inserts — rows existing only on a workbook branch tab are ingested as new records under the tab’s zone. Unknown-zone rows are now counted + sampled in the response instead of silently dropped.

Trigger: Stephaney’s three Mathews County (VBEACH) permits, 2026-07-28. Two were already tracked (186117, 193591); 17589 (Jay Kinney, 14 Gwynnsville Rd, permit 202500059) was added via the new endpoint.

Round 2 (same day)

  • ”+ Add Permit” also in the spreadsheet view toolbar (portal 86d3d85); same modal, gated by the can-upload probe (CAN_UPLOAD flag).
  • Skipped-row resolver: upload-overdue returns unknown-branch rows with their full field set (skipped_rows, cap 50, api bc4c827); the upload result banner renders each with a branch dropdown + Add button that resubmits via POST /records. Works for Sync Overdue and the one-click workbook upload.
  • POST /records now runs the post-ingestion cert-link sweep scoped to the new record (same enrichment as uploads).

Round 3 (same day) — manual project matching

  • GET /tracker/records/{id}/match-candidates + POST /tracker/records/{id}/match (api, pushed): PMS sqlite + Supabase projects candidates (permit/customer/ street/owner auto-search, ?q= free-text); link/unlink writes the original batch-matcher shapes, match_type=‘manual’, undoable via change history. Edit-gated — Stephaney’s triage role qualifies (same as inline edits).
  • Portal: Match modal; Find Match / Unlink buttons in the row detail; RECON’D IN PORTAL cell in sheet view opens the modal.
  • Confirmed: _EDIT_ROLES = {up_owner, up_admin, triage} — Stephaney can already inline-edit sheet cells, notes, RTS, close/reopen.
  • Mathews = county under VBEACH (Dustin confirmed), never a branch.