Day to day
Create a program, import a visitor roster, tick checklist items, book meetings and logistics, print an itinerary, subscribe the office calendar.
Architecture briefing · 18 August 2026
An internal ops app for IVLP-style visitor programs. One staff team tracks visitors, meetings, transport, hotels, contracts, cultural days, and dinner diplomacy, plus a 28-item readiness checklist and a calendar of every program at once. Zero npm packages, no build step, Node 18+.
Baseline
Source unzipped into git
Tests: 553 passed, 0 failed
Repo: Absterrg0/gtm-tracker
Purpose
Global Ties Miami runs international visitor programs (typically IVLP cohorts). Staff already juggle Google Sheets, inboxes, and calendar invites. This app is the single place that answers: who is coming, what is booked, what is still open, and what happens this week.
It is not a CMS, CRM, or accounting system. Version 1 deliberately stops at operational tracking. Conflict detection, budgets, document storage, visitor-facing portals, and evaluations were discussed and deferred.
Create a program, import a visitor roster, tick checklist items, book meetings and logistics, print an itinerary, subscribe the office calendar.
Create users, disable accounts, edit the 28-item checklist template, publish or rotate the secret iCal URLs.
See dashboards, programs, and directories. Cannot write, cannot see feed tokens, cannot delete.
Request path
Domain
Add a field in lib/schema.js and the form, table, CSV export, and activity log pick it up. No second list to keep in sync.
| Type | Scope | What it tracks |
|---|---|---|
program | Global | Name, agency, theme, arrival/departure, pax, languages, lead + optional secondary, status. |
visitor | Program | Roster: org, country, flights, dietary, access, emergency, room. |
meeting | Program | Host org, contact, address, slot, interpretation, status. |
transport | Program | Pickup/drop, vendor, driver, vehicle, confirmation. |
hotel | Program | Stay, rooms, rate, billing, confirmation. |
cultural | Program | Activity, venue, tickets, cost. |
dinner | Program | Dinner diplomacy host, seats, dietary notes, home address. |
contract | Program | Counterparty, value, sent/due/signed, document link. |
checkitem | Program | Generated from template; tick stamps who and when. |
org | Directory | Meeting hosts and venues. Topics, lead time, security, access. |
host | Directory | Dinner hosts. Seats, languages, pets, orientation, agreement. |
vendor | Directory | Hotels, transport, interpreters, caterers. W-9, COI, rating. |
Directories fill themselves: type a name that is not in the list and the app offers to add it. Later forms suggest it and copy address/contact. Merge folds duplicates; an entry still in use cannot be deleted — set it Dormant / Do not use instead.
Creating a program clones the current checklist template. Later template edits do not rewrite existing programs. Individual items can be added or removed on one program without touching others. Tasks are not assigned to people; the program’s lead/secondary own the whole list.
Layout
| Path | Job |
|---|---|
| server.js | HTTP, static files, CLI (--create-admin, --backup), nightly backup timer, session purge. |
| lib/schema.js | Entities, fields, statuses, country aliases, default 28-item template, sanitize. |
| lib/store.js | SQLite or JSON. Users, sessions, records, activity, settings. |
| lib/auth.js | scrypt, 12-hour server sessions, CSRF, admin/staff/viewer. |
| lib/api.js | JSON API: records, bulk import, dashboard, search, directories, template, calendar tokens. |
| lib/ical.js | RFC 5545 feeds. Miami wall-clock stored, UTC published. |
| public/app.js | Entire SPA: hash router, forms from schema, roster import, itinerary, search. |
| deploy/ | systemd unit (hardened) and nginx TLS reverse proxy. |
| build-review.js | Single-file HTML for evaluation, mock backend, five sample programs. |
node server.js --create-admin … then HOST=127.0.0.1 PORT=8080 node server.js. Data in ./data/, gitignored.
systemd as user gtm, nginx + certbot on tracker.globaltiesmiami.org. App never talks outbound and never sends email.
node build-review.js writes a self-contained HTML file. Sample data stays in the browser; it is not the live database.
Threat model
scrypt with per-user salt. First login forces a password change. Sessions expire after 12 hours idle and die immediately when an account is disabled or the password is reset.
CSRF on every mutating request except login. Schema whitelist. CSP + DENY framing. Login rate-limited in nginx. Passwords never appear in the activity log.
Anyone with the URL can read program dates (and optionally host addresses). Rotate from Administration. Google must be able to fetch /calendar/ unauthenticated.
Sessions and passwords would travel in the clear. Always terminate TLS at nginx. Leave HOST=127.0.0.1.
Scope
| In v1 | Deferred |
|---|---|
| Dashboard calendar bands, this-week feed, open checklist items | Conflict and staff-load detection |
| CSV roster import with country aliases | Budgets and invoices |
| Directories with usage history, rename, merge | Document storage |
| Itinerary print + per-program .ics download | Mail-merge letters |
| Office-wide Google Calendar subscribe | Visitor / meeting-host portals |
| Nightly backup to disk (copy off-box yourself) | Post-program evaluations |
Sources: local tree /home/abstergo/Programming/Projects/gtm-tracker — README.md, server.js, lib/schema.js, lib/api.js, lib/store.js, lib/auth.js, lib/ical.js, public/app.js, deploy/. Tests run 18 August 2026: 180 API (SQLite) + 180 API (JSON) + 91 UI + 102 review = 553 passed.