Skip to content

Add visit archiving to the manage History tab - #31

Merged
gbyo merged 1 commit into
mainfrom
gibby/history-archive-records
Aug 11, 2026
Merged

gbyo merged 1 commit into
mainfrom
gibby/history-archive-records

Conversation

@gbyo

@gbyo gbyo commented Aug 11, 2026

Copy link
Copy Markdown
Member

Librarians can archive a visit record from the History tab and restore it later.

Archiving is for records that should not have existed — test scans, duplicates, a check-in a student abandoned — so an archived visit is hidden everywhere, not just in the history list: overview counts, the students list visit counts, stats, kiosk fun facts, the live occupancy count and CSV export all skip it. Nothing is deleted; the row stays in library_visits with archived_at and archived_by, and Restore puts it back.

What's in the UI

The History tab gets an Active records / Archived records switch next to the date filter, and a per-row Archive / Restore action with a confirmation step. Archived rows show who archived them and when, under the student name.

Two decisions worth reviewing

Archiving a visit that has no checkout also closes it (as librarian). Without that it would sit archived and open forever, and restoring it months later would silently drop that student back into the live occupancy count without anyone scanning them in. The confirm dialog says so when it applies.

The columns are added by a lazy once-per-isolate migration. CREATE TABLE IF NOT EXISTS cannot add columns to a table that already exists, so ensureVisitArchiveColumns runs the ALTER TABLEs once per isolate before anything touches archived_at. Existing databases self-heal on the first request after deploy; the manual SQL is documented for anyone who would rather run it themselves.

API

POST /api/library/admin-archive-visit   {"visitId": 123, "archived": true}
GET  /api/library/admin-history?archived=1

Also fixed

A pre-existing bug found while building this: .empty{display:grid} overrode the hidden attribute, so every table on the manage page rendered its "No records found" empty state underneath its rows at all times. One-line CSS fix, but it mattered here because the archived view needs a correct empty state.

Verification

npm run build, then a real local D1 seeded with the pre-change schema so the migration path itself was exercised:

  • the two columns were added automatically on first request
  • archiving a completed visit removed it from history and from the CSV export
  • archiving an open visit closed it and dropped the live count 1 → 0
  • the kiosk then treated that student's next scan as a fresh check-in rather than a checkout
  • restore put the record back into history, stats and the student's visit count
  • unknown visit id, missing visit id and GET all return sensible errors

Then drove the actual UI through archive → archived view → restore.

🤖 Generated with Claude Code

Librarians can archive a visit record from the History tab and restore it
later. Archiving is for records that should not have existed — test scans,
duplicates, a check-in a student abandoned — so an archived visit is hidden
everywhere, not just in the history list: overview counts, the students list
visit counts, stats, kiosk fun facts, the live occupancy count and CSV export
all skip it. The row stays in library_visits with archived_at and archived_by.

- new archived_at / archived_by columns, applied to existing databases by a
  lazy once-per-isolate migration since CREATE TABLE IF NOT EXISTS cannot add
  columns to a table that already exists
- POST /api/library/admin-archive-visit archives or restores a single visit
- GET /api/library/admin-history?archived=1 lists archived visits
- History tab gets an Active/Archived switch and a per-row Archive or Restore
  action with a confirmation step

Archiving a visit that never got a checkout closes it on the way out. Without
that it would sit archived and open forever, and restoring it later would drop
the student back into the live occupancy count without anyone scanning them in.

Also fixes a pre-existing bug found while building this: .empty{display:grid}
overrode the hidden attribute, so every table on the manage page rendered its
"No records found" empty state underneath its rows at all times.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
flow f12353a Aug 11 2026, 11:55 AM

@github-actions github-actions Bot added area:docs Documentation changes area:source Changes to application source code labels Aug 11, 2026
@gbyo
gbyo merged commit 180054f into main Aug 11, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:docs Documentation changes area:source Changes to application source code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant