Project Guide · for organisers & developers

Vascular Access Workshop — how it all works

Everything a newcomer needs: what this app is, the tech behind it, the roles, where the data lives, how to run a workshop, pull the results, and set up the next edition. Read top to bottom, or jump via the menu.

1. Overview

A lightweight, mobile-first web app that runs the TUH Vascular Access Workshop end to end.

Participants scan a QR code on their own phone and complete a form in the browser — no app install. The app handles:

  • Registration — name, role, email, WhatsApp, hospital + GDPR consent
  • Feedback — a one-question-at-a-time wizard, anonymous by default
  • QR codes — generated in-app for registration & feedback
  • Data dashboard — organiser loads, downloads (CSV) and deletes results

It replaces the old Google Forms + third-party QR workflow. The whole thing is essentially one HTML file plus a small Supabase database.

The workshop runs every 3–4 months. One deployment serves every future edition — you just set the date before generating QR codes.

2. Software used

PieceWhatWhy
Cloudflare PagesStatic hosting + deploys from GitHubFree, fast, auto-deploy on every push
SupabasePostgres database + auto REST APIStores registrations & feedback; no server to run
GitHubCode repo (rcheva/Vascular-WS, private)Source of truth; push = deploy
chevahub.comDomain / DNS (Cloudflare)Custom address vascular-ws.chevahub.com

In the page itself: vanilla JavaScript only — no framework, no build step. The only external bits are the QR library (qrcodejs), the icon font (Tabler), and Google Fonts, all loaded from a CDN.

Files: index.html (the whole app) · details.html (programme page) · guide.html (this page) · tuh-logo-white.png · CLAUDE.md (full technical spec).

3. Roles

Student / participant

Scans a QR code → lands on the Registration or Feedback form → submits. They only ever see those two tabs. They never need a login or a key.

Organiser (admin) — you

Sees the extra QR Codes and Data tabs by adding ?admin=1 to the URL. Sets up the workshop, prints QR codes, and pulls/deletes data using a secret key (below).

Admin tabs are hidden from students. The plain site URL always shows the student view — admin only appears with ?admin in the link.

4. How it works

Student scans QR  →  fills form in browser
        │
        ▼
   App validates  →  saves to Supabase (insert-only public key)
        │                       tagged with the workshop_id
        ▼
   Organiser (Data tab + secret key)  →  Load → Download CSV / Delete
  • Saving is automatic — the page has a baked-in public key that can only insert. Nothing to set up on the day.
  • Reading/deleting needs the secret key, which is never in the page — you paste it at runtime, on your own device.
  • Every row is stamped with a workshop_id like TUH_2026-10-12, so each edition's data stays separate.

5. The data

Lives in a Supabase project (Renal-Review), inside a dedicated vascular schema, in two tables:

TableHolds
workshop_registrationsname, role, email, whatsapp, centre, consent, timestamp, workshop_id
workshop_feedbackname (or "Anonymous"), timestamp, workshop_id, and a responses JSON holding every answer of the feedback wizard

workshop_id = TUH_<date>. It's built from the workshop date and attached to every submission. This is how the app keeps editions apart and lets you download one workshop at a time.

GDPR: registration asks for explicit consent before storing personal data. Data is used only for the workshop. The database currently sits in the sa-east-1 (Brazil) region — acceptable for low-risk contact data, but note it's not in the EU.

6. Run a workshop (day-of)

  1. Un-pause Supabase if needed (free projects sleep after ~1 week idle). Dashboard → project shows "Paused" → Restore.
  2. Open admin QR setup: vascular-ws.chevahub.com/?tab=qr&admin=1
  3. Set the workshop date + edition. The Workshop ID (e.g. TUH_2026-10-12) builds itself.
  4. Click Generate, then Download both QR PNGs.
  5. Print them: Registration QR at the entrance, Feedback QR on tables / at the exit.
  6. That's it — participants scan and submit; everything saves automatically.
Print QR codes at A5 or larger, with a text label underneath ("Scan to register"). Generate them using the final domain so the printout keeps working long-term.

7. Extract data (CSV)

  1. Open vascular-ws.chevahub.com/?tab=data&admin=1
  2. Get your service-role key from Supabase → Project Settings → API Keys → Legacy API keys → service_role (a long string starting eyJ…). Copy it.
  3. Paste it into the Service-role key field → click Load saved data.
  4. If more than one edition exists, an edition picker appears — choose the workshop.
  5. Click Download registrations and Download feedback — two separate CSV files.
Use the legacy service_role key (starts eyJ…), not the newer sb_secret_… one. The secret key bypasses all security — paste it only on your own device; it's kept in memory and cleared when you close the tab.

The feedback CSV automatically flattens every wizard answer into its own column.

8. Delete data

On the Data tab, with the service-role key loaded, the red Delete button wipes only the selected workshop's rows. Flow:

  1. Type the admin passcode (set in the code — ask the organiser / see the private repo).
  2. Confirm twice.
  3. Done — registrations + feedback for that workshop_id are removed.
Deletion is permanent. Download the CSVs first.

9. Set up a new edition

Two ways — the first needs no developer:

A. No redeploy (recommended)

In the admin QR tab, set the date + edition and Generate. The QR links embed the new workshop (?w=TUH_<date>). Anyone scanning gets that date/edition and their data is tagged correctly. One deployment serves every future workshop.

B. Redeploy (changes the default)

Edit the WORKSHOP object at the top of the <script> in index.html and push:

const WORKSHOP = {
  dateISO: '2026-10-12',   // workshop day → builds the workshop_id
  edition: '13th',
  date:    '12 October 2026',
  ...
};

Use B when you want the plain URL (no params) to represent the current edition.

10. Edit the feedback form

All questions live in one array — FB_QUESTIONS — near the top of the feedback section of index.html. Add, remove, reorder, or reword there; nothing else changes. Step types:

TypeUse for
gridA matrix: several rows sharing one rating scale (satisfaction, venue, quality)
optionsA single multiple-choice question
text / shortLong / short free text
twotextTwo text inputs in one step (e.g. two topics)
unitYes/No + unit name + contact

Answers save into the feedback responses JSON automatically — no database change needed when you tweak questions.

11. Deploy & code changes

  • Code lives in GitHub: rcheva/Vascular-WS (private).
  • Every push to main auto-deploys via Cloudflare Pages.
  • No build step — Pages just serves the files (output directory /).
  • Custom domain vascular-ws.chevahub.com is attached in the Pages project.
To change something small (passcode, a question, a date): edit the file, commit, push. Live in ~1 minute.

12. Security model

KeyWhereCan do
Anon (public) keyBaked in the pageInsert only. Cannot read or delete. Safe to ship.
Service-role keyNever in the page — you paste itFull read + delete. Organiser device only.
Admin passcodeIn the codeSoft guard on the Delete button — an accident-stopper, not real security.

Students can only ever add data. Reading and deleting require the secret key that lives nowhere public. Feedback is anonymous unless someone types their name.

13. Maintenance

  • Before each workshop: un-pause the Supabase project (free tier sleeps after ~1 week idle). Submissions won't save while paused.
  • QR codes: generate with the permanent domain so old printouts keep working.
  • Free-tier limit: the Supabase account allows 2 active free projects total; this app shares the Renal-Review project via its own schema, so it doesn't use a slot.
  • Backups: download CSVs after each workshop; that's your archive.

14. Recommendations

  • Change the admin passcode to something private, and rotate it occasionally.
  • Always download CSVs before deleting anything.
  • Test the day before: open the registration QR, submit a dummy entry, load it on the Data tab, then delete it.
  • Keep it a single file. Resist splitting index.html — the simplicity is the feature.
  • If you grow: consider moving the database to an EU region for stricter GDPR, and swapping the service-key reads for a proper Supabase login.
  • Roadmap ideas (see CLAUDE.md): live polls, an organiser dashboard with live averages, WhatsApp follow-ups, attendance certificates.

15. Quick reference

ThingValue
Live sitevascular-ws.chevahub.com (and vascular-ws.pages.dev)
Admin — QR setup…/?tab=qr&admin=1
Admin — data…/?tab=data&admin=1
View a past edition's dataadd &w=TUH_<date> to the data URL
Code repogithub.com/rcheva/Vascular-WS (private)
Supabase projectRenal-Review · schema vascular
Service-role keySupabase → Settings → API Keys → Legacy → service_role
Full technical specCLAUDE.md in the repo

← Back to the app  ·  Programme page