Technical Sheet - Simulation GM3

Vanilla JS Node.js + Express Supabase (Postgres + Realtime) Zero build step Demo / training use
1. Technology stack 2. Architecture 3. Project structure 4. Data flow 5. REST API & Supabase 6. Data persistence 7. Limits and scalability 8. Requirements

1. Technology stack

LayerTechnology
FrontendSemantic HTML5 + plain CSS3 + JavaScript ES6 (vanilla, no framework, no bundler)
BackendNode.js + Express (static file serving, legacy fallback API)
Realtime persistenceSupabase (Postgres + Realtime), called directly from the browser
Client persistencelocalStorage (scenes, patch, design, theme)
HostingVercel (static output + serverless functions in api/)
GraphicsNative 2D Canvas (Stage View, Catalyst preview)

2. Architecture

Browser (public/)                          Supabase (Postgres + Realtime)
┌───────────────────────┐              ┌───────────────────────────┐
│ console.html            │              │ table: cues                 │
│  ├── app.js (core)        │──REST───▶ │  ├── insert/select/delete       │
│  ├── module-*.js (x9)     │◀─realtime── │  └── Row Level Security policy │
│  └── style.css              │              └───────────────────────────┘
└───────────────────────┘
        │                                Vercel (api/)
        ▼                                ┌───────────────────────┐
   localStorage                          │ /api/config              │
   (scenes, patch,                       │  → exposes Supabase URL   │
    design, theme)                       │    + anon key to frontend │
                                          └───────────────────────┘

Every module-*.js is an independent script (IIFE) that reads/writes shared state on window.GMA3 and injects its own panel into the DOM. Cue data lives in Supabase and is shared/synced in real time across every open session; everything else lives in the browser.

3. Project structure

grandma3-project/
├── server.js                  Express: static serving + legacy in-memory cue API
├── api/                       Vercel serverless functions (config, health)
├── vercel.json                 Static output config, framework auto-detect disabled
├── package.json
├── public/
│   ├── index.html               Landing page ("Enter Simulation")
│   ├── console.html              Console shell: screen tabs + physical deck
│   ├── css/style.css              Green-terminal theme, console/deck skin
│   ├── docs/                     Servable copies of the HTML docs
│   └── js/
│       ├── app.js                  Core: faders, cues (Supabase), scenes, patch,
│       │                          design, command line, encoders, Stage View
│       └── module-*.js              Self-registering panels (9 modules)
├── supabase/schema.sql         Table + RLS policies + realtime publication
├── samples/default-scenes.json  Ready-to-import demo scene pack
└── docs/                       Documentation (Markdown + HTML)

4. Data flow

Fader (drag/click)

pointer event → percentage calculation → state.faders[i] updated → DOM + Stage View repaint

Cue (Supabase)

form submit → supabase.from('cues').insert(...) → Realtime event fired
                                                    ↓
                                    every open session: loadCues() → re-render grid

Scene

Store Scene → localStorage.setItem → render list
GO → localStorage.getItem → state.faders = scene → repaint

Automation

setInterval(N seconds) → next scene → apply faders → sync Catalyst layer

5. REST API & Supabase

MethodRoute / callPurpose
GET/api/healthServer health check
GET/api/configExposes Supabase URL/anon key to the frontend
-supabase.from('cues').insert()Create a cue (primary path)
-supabase.from('cues').select()List cues (primary path)
-supabase.from('cues').delete()Delete a cue (primary path)
POST/GET/DELETE/api/cue/*Legacy in-memory fallback, used only if Supabase isn't configured

Full detail with request/response examples: docs/API.md.

6. Data persistence

DataWhere it livesSurvives a restart?Shared across users?
CuesSupabase (Postgres)YesYes, in real time (Realtime subscription)
ScenesBrowser localStorageYes (per browser)No
Fixture patchlocalStorageYes (per browser)No
DesignlocalStorageYes (per browser)No
ThemelocalStorageYes (per browser)No

7. Limits and scalability

Intended use: demo and internal training. Not designed for multi-tenant production.

Path to a production-ready setup (see also docs/TECHNICAL.md):

  1. Add authentication (Supabase Auth) and scope RLS policies per user/session instead of public access.
  2. Move scenes/patch/design server-side (Supabase tables) instead of per-browser localStorage, so a setup is shared across stations.
  3. Consider rate-limiting/quotas on the public demo instance if left open on the internet.

8. Requirements