How to Onboard a New Team (Client + Schemas)
There is no "create team" button. A team is born across two database tables and five code config files, and only then does Cortex (and the fan apps) know it exists. This guide is the full recipe — a good first exercise is to create your own client with a Flex and a Premium schema.
Use this when: creating a personal sandbox team, or onboarding a real client.
The moving parts
Both backends validate every X-Team-Schema against a hard-coded TypeScript whitelist — the
team config registry. That's the SQL-injection barrier (see
schema-safe code), and it's why a new team is a code change, not
just data. Until your configs are merged and deployed, the new team only works against locally
running backends.
Step 1 — Create the client and schemas in the dashboard DB
In the dev RDS, in the Cortex dashboard schema (not a team schema):
tbl_clients— one row:clientId(uuid),clientName. This is the top of the hierarchy. (The old one-client-per-vendor restriction is gone — one client can hold schemas for multiple vendors.)tbl_client_schema— one row per schema:schemaCode(the actual PG schema name),schemaName/schemaTitle/schemaDescription(display only),productId(FK intotbl_products),clientId,vendor(TM/TDC/SeatGeek). (OnlyTM(Archtics/Host) andTDChave a fan-backend integration;SeatGeekis a client classification only — you can't yet stand up a working SeatGeek fan team.)
⚠️ Register premium schemas under the Flex product. Cortex has no Premium product UI — premium teams are administered under Flex (the Suites & Premium Boxes section). A
Premiumrow exists intbl_products, but its Cortex pages were never built, so a schema registered under the Premium product dead-ends the workspace picker ("Continue" does nothing). SetproductIdto the Flex product for both your Flex and Premium schemas — reference premium teams (tm_premium_sandbox,dbacks_premium_sandbox) are all registered under Flex.
Every team in the platform is a row in tbl_client_schema, so the table itself is one big example
sheet — open it and copy a neighbouring row for reference. Naming convention for personal
sandboxes: tm_sandbox_<name>_flex and tm_sandbox_<name>_premium (the sandbox segment
is optional).
No user mapping is needed if you're a super user; otherwise add rows to
tbl_users_schema_mapping.
Step 2 — Team configs in code (5 files)
| Repo | Where | What |
|---|---|---|
flex-v3-backend | src/config/teams/<schema>.config.ts + register in index.ts | one config per schema. Sandbox = dsn: 'sandbox', siteName: 'integ3', sandbox clientId/integratorId (copy any existing tm_flex_*.config.ts). Flex and Premium schemas both live here — same backend |
cortex-backend | src/config/teams/ (same pattern) | adds vendor, productType, urlType: 'sandbox' (copy flex_v3_sandbox.config.ts). Premium schemas use productType: PRODUCT_TYPE.FLEX too — copy tm_premium_sandbox.config.ts as-is (premium is administered under Flex; the picker dead-ends if you use the Premium product — see the Step 1 callout) |
flex-v3-frontend | src/common/app-config/team/<schema>/ + registry | branding/app config for the Flex schema: logos, colors, ticketVendor (copy the flex_v3_sandbox folder) |
premium-frontend | src/common/app-config/team/<schema>/ + registry | same, for the Premium schema |
cortex-frontend | src/config/schemas/ | per-schema overrides (timezone etc.) in schemas-config.ts (+ venue-map-source-config.ts). Largely a scaffold today — check those files for the current shape |
Always use sandbox credentials for personal teams — the four Archtics values are the prod/sandbox switch (see Environments & Sandboxes). Restart the local backends after registering.
Step 3 — Build the PG schema
flex-v3-backend has an internal builder API (guarded by the internal API key):
POST http://localhost:5011/builder/schema
x-internal-api-key: <key>
{ "teamSchema": "tm_sandbox_demo_flex" }
Idempotent: creates the schema and every tbl_* table from the entity definitions (re-running
adds whatever is missing). GET /builder/schemas lists all flex schemas;
POST /builder/schemas/sync-all re-syncs every schema after entity changes.
Step 4 — Set up the product in Cortex
Log into Cortex, pick your new workspace, and build a program (Chapter 16 has the concepts).
💡 Gotchas from a real sandbox run — do these before "add events" will work:
- Fetch events first. Flex Events → Import → enter codes SS1–SS15 → Fetch from Ticketmaster → Validate → Import. They land as Drafts.
- Future-date events while they're Drafts. The Archtics sandbox SS events are often dated in the past; edit each event's date to the future. The date locks once the event is published, so fix it before publishing.
- Publishing an event requires a venue. Create one in Venues & Maps — just a venue name + map name; the map image is optional, because the actual seats come from the TM manifest, not an uploaded map. Assign the venue to each event, then publish.
- The program needs ≥1 class name + non-zero pricing before it can publish (Inventory Configuration → class name; Configure Pricing → price every code).
- Create Program (e.g. Build-Your-Own, seat level) → set min/max events → add events (only published events are selectable). Sandbox event codes are SS1–SS15.
- Class name: fetch the options from one event, then "configure all same for all" copies the event/price/ticket-type codes to the rest (per-event under the hood).
- Configure pricing → fetch combinations from a reference event → select price codes. Use real, non-zero prices.
- Optional add-ons → build inventory → wait for all events to build → publish.
Publish guards to expect: every active event must itself be published (remove or publish
stragglers), and only one program can be active at a time — deactivate the old one first.
Images can be reused from existing assets or uploaded in Cortex. Then open the fan app at
/<schemaCode>/events_home and buy something with the sandbox card.
Known quirk: new programs have occasionally inherited Live Nation seed data; if your fresh program shows someone else's branding, check what the seeder wrote before debugging your config.
See also
- How to run the stack locally — do this first
- Environments & Sandboxes — sandbox credentials, test cards
- Working with team schemas — why the whitelist exists