This guide is for running Band Licence on your own computer while allowing students and families to scan a Licence QR code at home.
The important split is:
- Teacher app: private, full app access for setup, attendance, scheduling, cards, settings, and student management.
- Public QR profile app: student profile, practice tools, privacy-filtered leaderboards, and tightly limited student-self actions from QR cards.
Do not expose the teacher app directly to the public internet.
The current code is safe local groundwork, not approval to publish profiles. School approval, privacy and child-safety review, trusted HTTPS, host hardening, monitoring, support, incident response, retention, deletion, and recovery must be completed before public use.
What You Need
To make QR cards work away from your own Wi-Fi, you need:
- An always-on computer running the app.
- A public hostname, such as a domain name or dynamic DNS hostname.
- Trusted HTTPS for that hostname.
- A reverse proxy that forwards only to the QR profile server.
- Regular SQLite backups.
If your internet service uses CGNAT, normal router port forwarding may not work. In that case you would need a public IP from your internet provider, a different internet service, or a tunnel/VPN-style approach. Without a reachable public address, phones outside your network cannot open the QR profile pages.
Windows Server Setup
Use PowerShell on the Windows computer.
- Install Node.js
24.19.0, matching the tested CI and deployment runtime. - Install pnpm
11.21.0:
corepack enable
corepack prepare pnpm@11.21.0 --activate- Copy the Band Licence app folder to the Windows computer.
- Open PowerShell in the app folder.
- Install dependencies:
pnpm install --frozen-lockfile- Copy the current database and backups from the Mac into the same folders on the Windows computer:
data/band-licence.sqlite
backups/- Build and check the app:
pnpm build
pnpm test
pnpm release:check
pnpm db:restore:rehearse- Start the private teacher app:
pnpm start:private-network- In a second PowerShell window, start the public QR profile server:
pnpm start:public-profilesThese two commands are the complete SQLite process allowance: exactly one teacher process on port 3003 and at most one QR-only process on port 3013. They must run on the same computer and use the exact same SQLITE_PATH on that computer's local disk. Do not use a NAS, network share, cloud-synchronised folder, container replica or second host. The app enables SQLite WAL mode and a 10-second busy timeout on every application connection, and starts top-level write transactions in immediate mode, so short writes from the two processes wait and serialise safely. The busy timeout alone cannot repair a deferred read-then-write transaction after its WAL snapshot becomes stale.
Start the teacher process first and confirm it is healthy before starting the QR-only process. Never start either process during a schema migration, restore or database-file replacement. Before enabling the second process, run and retain:
pnpm db:concurrency:rehearseThat isolated rehearsal proves both process roles can wait through a deliberate write lock; it does not prove real host capacity. Account beta and public use remain blocked until production-shaped teacher-plus-QR load results and an exercised monitoring/alert record are retained.
- In Windows Firewall, allow inbound TCP only for the ports you genuinely need:
3003 for private teacher access on your trusted network
3013 only if the reverse proxy runs on another computer
80 and 443 for the public HTTPS reverse proxyIf Caddy runs on the same Windows computer, the public internet should reach Caddy on ports 80 and 443, and Caddy should talk privately to 127.0.0.1:3013.
The app start commands are written to work on Windows, macOS, and Linux.
Applying Future Updates
The Mac development copy and the Windows server do not synchronise automatically. Keep the Windows database as the live source of truth and send code in the other direction:
- On the Mac, run
pnpm update:package. - Transfer the new ZIP from the Mac
releasesfolder to the Windows server. - On Windows, double-click
deploy\windows\Install Update.cmdin the existing app folder. - Select the transferred ZIP and wait for
UPDATE COMPLETE. - Confirm the teacher app and one demonstration QR profile both open.
For the first update only, extract the ZIP and run deploy\windows\Install Update.cmd from the extracted folder. It finds the existing S:\Band Licence App and installs the updater there. For later updates, run the updater directly from the existing app folder without extracting the ZIP.
The updater creates and verifies a database backup before changing code. It does not replace the Windows database, backups, Lesson Notes engine, HTTPS files, Caddy setup, or environment settings.
Recommended Shape
Student or family phone
-> https://your-public-profile-address
-> router port 443
-> reverse proxy
-> Band Licence public QR profile server on port 3013Keep the normal teacher app on port 3003 for your own use:
pnpm start:private-networkRun the public QR profile server separately:
pnpm start:public-profilesThe public QR profile server uses BAND_LICENCE_PUBLIC_PROFILE_ONLY=true. It serves the QR exchange, the /join school-code entry page, approved /student pages, and required static assets. Teacher pages such as /students, /settings, /check-in, /attendance, and /cards return 404.
Saved timer corrections use only /student/api/practice-history: authenticated students may read their own history and reduce their own timer entry through same-origin, bounded JSON PATCH requests. They cannot increase time or edit teacher-entered or another student's records.
The approved practice pages include /student/practice/tuning-darts. Its only writes are POST /student/api/tuning-darts/challenge, which issues the current student's target set, and POST /student/api/tuning-darts, which saves that challenge-bound result.
Note Run is available at /student/practice/note-run. Personal instrument choices are available in /student/settings, saved only through the session-bound POST /student/api/practice-instruments. This changes new-session dropdown choices, not the profile's primary instrument, past records or an active timer/game. Teacher settings and /player APIs are not exposed on the QR-only host.
The exact Note Run student-session APIs are /student/api/note-run (GET/POST), /student/api/note-run/leaderboard (GET), and /student/api/note-run/preferences (GET/POST). Server replay owns the score, checkpoint and once-per-level reward; appearance purchases use the existing avatar wallet. Browser microphone audio remains local and is not recorded. Assisted/unassisted competitive groups remain separate. These routes do not grant access to teacher pages or the teacher leaderboard API.
More precisely, it serves the token exchange, the explicitly approved /student pages, Exit Student View, the rate-limited POST /api/school-access/session exchange, and required static assets only. That exchange pairs a revocable, expiring, HMAC-hashed school code with an active same-school licence card, returns no roster identity, and creates only the locked session used by the existing PIN step. Its reviewed student-self writes are security-code setup/check, friend choices, practice timer/tracking preference, locally assessed mission results, locally assessed sight-reading totals, fixed-catalogue avatar changes, and server-scored theory challenges and bonus rounds, plus challenge-bound Tuning Darts results. It also permits a bounded student-authored contact subject and message, which is stored as a school-scoped support/correction request. Each write is bound on the server to the unlocked session's student and school and is rate-limited where applicable. Avatar choices accept no photos, uploads or free text. Theory, bonus round and Tuning Darts targets come from short-lived, single-use server challenges; the server recomputes their scores, and Tuning Darts retries reuse one per-student submission ID instead of creating duplicate games. The Contact feature is not private messaging and is not automatically approved for production: its free text, moderation, staff access, support response, retention and deletion process require explicit school/privacy approval. Unknown future student pages, nested practice tools, APIs and generic server-action POSTs are blocked until explicitly approved. Teacher pages, teacher APIs, exports, reports, server-action mutations, source maps, database files, backups, logs, and environment files are not part of the public allow-list.
How a Card Opens a Profile
New cards use a link shaped like:
https://profiles.example.com/profile/qr#RANDOM_SECRETThe random secret is not a student ID, name, school, instrument, or check-in barcode. A browser does not send the fragment after # to the web server. The landing page removes it from the visible URL, exchanges it for a separate random session, and then opens the clean /student address.
The temporary session:
- lasts 30 minutes and is not extended by refresh;
- uses an HttpOnly, Secure, SameSite cookie restricted to
/student; - is bound to one active student and one school;
- becomes invalid if the profile QR is reissued or the student is discontinued;
- is revoked and cleared by Exit Student View.
Copying the clean /student address to another browser does not grant access. On a shared device, always select Exit Student View when finished.
Caddy Example
Caddy is a good reverse proxy option because it can request and renew HTTPS certificates automatically when the public hostname points to your server.
Example Caddyfile:
profiles.example.com {
encode gzip zstd
reverse_proxy 127.0.0.1:3013
}Router setup:
- Forward public TCP port
80to the server computer. - Forward public TCP port
443to the server computer. - Do not forward
3003. - Do not forward
3013directly unless it is only reachable from the reverse proxy host.
Card Setup
After the public HTTPS address is working:
- Open Band Licence.
- Go to Settings -> Global Settings.
- Set Public QR Profile Access to your public HTTPS address, for example
https://profiles.example.com. - Save settings.
- Save updated or regenerated student Licence card PDFs.
Existing QR cards that still point at localhost will not work from home. Older path-based QR cards should also be reissued. Temporary compatibility exists, but those old links can place the secret in network or browser path history. New fragment-based cards avoid that.
Test Before Sending Cards Home
Test from mobile data, not your home Wi-Fi:
- Scan a card QR code.
- Confirm the student profile opens.
- Open the Practice menu and confirm the timer survives navigation to another student page.
- Open the school, global, and Friends leaderboards from that profile.
- Confirm other-school students remain anonymous and display school initials only.
- Scan another demonstration student's QR code from Friends and confirm the friend appears.
- Try changing the URL to
/students. - Try changing the URL to
/settings. - Try changing the URL to
/check-in,/attendance, and/api/health. - Copy the clean
/studentaddress into a different private browser and confirm it does not open. - Select Exit Student View, then confirm
/studentno longer opens on that device. - Open Tuning Darts, complete a demonstration game, and confirm only the current student's name is visible when peer anonymity is required. Stop or leave a live dart and confirm the browser's microphone indicator turns off; repeat once by switching the tab or app to the background.
- With fictional demonstration content only, submit one Contact request and confirm it appears in the intended school's support/correction queue, is not visible to another school, and follows the proposed staff-access, response, retention and deletion process. Do not enable this for real student text until that process is approved.
- Test the separate Code 128 check-in barcode with the normal USB scanner.
The QR profile and QR student leaderboard should work. Teacher pages should show Not found.
Lost or Copied Cards
The QR is a private bearer link, not verified identity. If a card is lost, copied, photographed, or shared too widely:
- Open the student's teacher profile as an Administrator.
- Select Reissue QR Profile Access.
- Confirm that the old QR and active student-view sessions no longer work.
- Save a replacement card PDF.
Reissuing profile access does not change the Code 128 check-in value or delete student history.
Restore Rehearsal
Before sending cards home, confirm you can test a backup restore safely:
pnpm db:restore:rehearseThis creates a temporary restored copy, verifies the key tables, shows a short snapshot, and deletes the temporary copy. It does not replace data/band-licence.sqlite.
Privacy Reminder
A QR code is a private link, not a full login. Anyone with the card or QR link can start the security-code access process for that one student profile. Teacher-controlled Licence, Method Book, pass-off and attendance records remain read-only. The only approved QR-session writes are the current student's practice timer/tracking preference, locally assessed mission and sight-reading results, fixed-catalogue avatar choices, friend choices, first-use security-code setup, and server-challenge-bound theory, bonus-round and Tuning Darts results. A bounded Contact subject and message can also be stored as a school-scoped support/correction request; it is student-authored free text, not a private or emergency channel, and requires explicit privacy, support and retention approval before real-data use. Replace a student card/token if a QR code is lost or shared too widely.
The current student view is limited to first name plus surname initial, instrument and instrument year, awarded Licence and teacher-completed progress, Method Book progress, the student's own pass-off and practice summaries, attendance percentages, approved Student View leaderboards, student-selected Friends, the student's own server-measured practice timer, and that student's mission, sight-reading, theory, and Tuning Darts results. Tuning Darts peer names follow the school's anonymity policy. Teacher-controlled progress, attendance, scheduling, and teacher records remain read-only. It excludes full surnames, IDs, check-in values, accounts, audit data, teacher notes, exact scan times, reasons, future schedules, locations, exclusions, class routines, custom statistics, photos, and all editing or check-in controls.
Use real student information only after school approval and a clear privacy process.
Teacher Access Away From Home
For teacher access from another network, use a private VPN or a properly secured account-beta deployment. Do not publish the full teacher app just so you can reach it remotely.