|
Some checks are pending
Build on NAS and deploy argotrack / build-deploy (push) Waiting to run
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. |
||
|---|---|---|
| .github/workflows | ||
| public | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| bun.lock | ||
| Dockerfile | ||
| nodemon.json | ||
| package-lock.json | ||
| package.json | ||
| README.argotrack.md | ||
| tsconfig.json | ||
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)
- Users —
pin, fname, lname, email, type, gender, login, logout, hours, total, loggedin, sessionType, sessionName.type=MENTORorSTUDENT. This is the roster you edit. - Log — date-pivot:
pin, fname, lnamethen one column per day (hours). Feeds/stats. - 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
/healththat 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.