No description
Find a file
Filip Kin 920ef5eadb
Some checks are pending
Build on NAS and deploy argotrack / build-deploy (push) Waiting to run
argotrack: expose running commit at /version
Bake the build commit into the image (Dockerfile ARG GIT_SHA, passed by CI) and
serve it at GET /version. Lets a client poll after pushing to main to see exactly
when their change is live.
2026-07-16 22:57:49 -04:00
.github/workflows argotrack: expose running commit at /version 2026-07-16 22:57:49 -04:00
public argotrack: use the real Argonauts logo on student/mentor portal login 2026-07-17 02:52:50 +00:00
src argotrack: expose running commit at /version 2026-07-16 22:57:49 -04:00
.dockerignore argotrack: build image on NAS runner, Coolify pulls (GitHub Actions) 2026-07-06 21:58:59 -04:00
.env.example argotrack: add coach dashboard, student portal, and sign-out-all 2026-07-16 19:03:06 -04:00
.gitignore Publish 2024-03-05 15:06:25 -05:00
bun.lock bug fixes 2025-12-27 17:05:40 +13:00
Dockerfile argotrack: expose running commit at /version 2026-07-16 22:57:49 -04:00
nodemon.json Publish 2024-03-05 15:06:25 -05:00
package-lock.json Publish 2024-03-05 15:06:25 -05:00
package.json Specify Node.js version in package.json 2025-12-27 16:23:13 +13:00
README.argotrack.md argotrack: document NAS CI deploy in README 2026-07-06 22:14:51 -04:00
tsconfig.json Publish 2024-03-05 15:06:25 -05:00

argotrack (beartime, Argonauts kiosk)

Attendance kiosk for FRC team 8728 Argonauts. It combines the beartime Google-Sheets backend with a PIN-keypad kiosk frontend, plus session typing (Meeting / Outreach / Competition) and a live "who's signed in" panel.

Deployed separately from the original beartime app: argotrack.filipkin.com (Coolify), off the argotrack branch. The main branch and beartime.app.filipkin.com are untouched.

Deploy (CI)

Push to argotrack → GitHub Actions runs on the self-hosted NAS runner (.github/workflows/deploy.yml): builds the Dockerfile, pushes git.filipkin.com/filip/argotrack to the Forgejo registry, and triggers the Coolify docker-image app to pull. ~30s end-to-end; the cloud box only pulls. The Dockerfile installs wget (Coolify's image health check uses it) and the app normalizes any backslash-escaping depth in API_KEY (/\\+n/g).

Endpoints

Route Purpose
GET /punch?pin=&sessionType=&eventName= Toggle a user in/out. Records a raw Sessions row; on sign-out also adds per-day hours to Log. /login is a back-compat alias.
GET /signedin { success, mentors:[], students:[] } — kiosk polls this every 30s.
GET /stats?pin= Mentor-only attendance stats (unchanged from beartime).
GET /health Pings the sheet. 200 when healthy, 503 when the connection is wedged (Coolify uses this to auto-restart).

Spreadsheet layout (3 tabs, order matters — read by index)

  1. Userspin, fname, lname, email, type, gender, login, logout, hours, total, loggedin, sessionType, sessionName. type = MENTOR or STUDENT. This is the roster you edit.
  2. Log — date-pivot: pin, fname, lname then one column per day (hours). Feeds /stats.
  3. Sessions — raw append log: timestamp, pin, name, type, event(IN/OUT), sessionType, eventName, hours.

The "stops working after ~a week" fix

The old app was restarted every 24h by a cron to work around it silently dying. Root causes were fire-and-forget sheet saves (unhandled rejections) and a connection cached once at startup with no recovery. This version:

  • awaits every save / saveUpdatedCells,
  • caches the connection but clears it on failure so the next request reconnects,
  • wraps each sheet op in withReconnect (one automatic retry),
  • exposes /health that actually probes the sheet, and
  • runs a self-watchdog that process.exit(1)s after 15 min of being unhealthy so Docker restarts a fresh process — only when actually broken, not on a timer.

No external restart cron is needed anymore.

Provisioning a new sheet

Service accounts can't create Drive files, so create a blank Google Sheet in a human Drive, share it (Editor) with the service account, then run the provisioning script (kept outside the repo) with SPREADSHEET_ID + a Coolify token to create the three tabs.