Identity and workspaces
The Hub has no password field. Every sign-in is an OAuth 2.0 authorization-code exchange with PKCE against your own World Space ID server, and what comes back is a subject claim — an opaque, stable identifier for that member.
state value is deleted the moment the callback reads it — before anything else happens. A replayed callback URL finds nothing and stops with a readable page, not a stack trace.Credits and payments
One rule holds this together: the balance is the ledger. Nothing anywhere updates a stored number to mean "how many credits you have". Every movement appends a row, and each row records the balance it produced.
| Door | When it fires | What stops a double grant |
|---|---|---|
| Webhook | The gateway calls us, usually within seconds | All three call one function, which writes a ledger row under the key payment:<order_id>. That key is UNIQUE, so whichever door wins, the member is credited exactly once. |
| The return trip | The browser lands back from checkout | |
| A status poll | Anyone opens a pending order |
{"cost": 0} gets charged the real price.402 Payment Required with the exact shortfall — and the record you were saving is still saved. Losing typed work to protect a counter is the wrong trade.Space Docs — letterheads and invoices
Set your brand once and every document inherits it. Change the company address and it changes on the next document — not on two hundred old ones, which is why the brand is its own row rather than a copy stamped onto each letter.
Space People — the employee record
The longest-lived object in the product. It outlasts every project the person touches, so it gets real columns, real dates and real foreign keys — and five child tables, because each of them is a list somebody queries on its own.
| Tab | What lives there |
|---|---|
| Overview | Contact details, address, emergency contact, skills, direct reports |
| Job & pay | Title, department, manager, type, mode, tenure, band, CTC, statutory IDs, salary account |
| Documents | Offer letters, contracts, IDs, certifications — stored with the record and downloadable again later |
| Leave | Balances against quota, requests with approve/reject, and a workspace-wide approvals queue answered by a join |
| Assets | What was issued, when, and whether it came back |
| Onboarding | An ordered checklist with progress, editable per person |
| Speaker profile | The switch that makes this person available to the Event Producer, with the bio that gets read on stage |
| Notes | 1:1s, milestones, concerns — timestamped and attributed |
{"id": …, "status": "On leave"} and only the status changes — the job
title, the bank details and the document file are all still there. Without that
rule, a status dropdown quietly empties a personnel file and nobody notices until
the audit.
Event Producer
A production is a graph, not a document. Days hold sessions; sessions reference tracks and speakers; speakers appear in many sessions. Stored as JSON, the one question the product exists to answer — what is on which stage at 3pm, who is on it, and what is the booth doing — would need every event in the workspace loaded to answer.
Space Decks
A real canvas, not a template filler. Drag anything, resize anything, double-click text to type into it, and every element keeps its position as a percentage so a slide looks the same on a phone thumbnail and a 4K projector.
The other nineteen
Everything else in the suite, and what it is for. All of it persists to your workspace, all of it respects the same roles, and all of it shares the identity you signed in with.
How it is built
Plain PHP 8 and MySQL on the server, one bundled React app in the browser, and no framework to keep up with. It runs on shared hosting because most of the world's organisations are on shared hosting.
Browser
One bundled app. Twenty-five modules, one design system, light and dark.
API
Prepared statements everywhere, workspace scoping on every query, an Origin check on every state-changing request, and rate limits counted per key and per IP.
Database
Thirty-eight tables. The money and records modules are normalized because they are queried; the document-shaped modules use a versioned per-workspace store with optimistic concurrency.
World Space ID
Your existing identity server. The Hub is a registered client of it and holds nothing but a subject claim and a rotating refresh token, encrypted at rest.
Bring your World Space ID. Nothing else to set up.