Skip to main content

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):

  1. 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.)
  2. tbl_client_schema — one row per schema: schemaCode (the actual PG schema name), schemaName / schemaTitle / schemaDescription (display only), productId (FK into tbl_products), clientId, vendor (TM / TDC / SeatGeek). (Only TM (Archtics/Host) and TDC have a fan-backend integration; SeatGeek is 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 Premium row exists in tbl_products, but its Cortex pages were never built, so a schema registered under the Premium product dead-ends the workspace picker ("Continue" does nothing). Set productId to 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)

RepoWhereWhat
flex-v3-backendsrc/config/teams/<schema>.config.ts + register in index.tsone 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-backendsrc/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-frontendsrc/common/app-config/team/<schema>/ + registrybranding/app config for the Flex schema: logos, colors, ticketVendor (copy the flex_v3_sandbox folder)
premium-frontendsrc/common/app-config/team/<schema>/ + registrysame, for the Premium schema
cortex-frontendsrc/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–SS15Fetch 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).
  1. 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.
  2. 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).
  3. Configure pricing → fetch combinations from a reference event → select price codes. Use real, non-zero prices.
  4. 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