PlayTelly
PlayTelly is a multi-tenant streaming + venue-ticketing platform. It's roughly
15 repositories that work together — one backend (CoreAPI), one auth
service (AuthAPI), a shared login page (tellyid), several admin
frontends, two customer-facing apps, and a deployment repo (playtelly-iac)
that runs the whole thing in staging/production once you're past local dev.
Repositories
| Repository | Role |
|---|---|
CoreAPI |
The backend. Owns the real tenancy graph (orgs/workspaces/teams/roles) plus every product domain (media, playback, distribution, ticketing, ...). See §2 below — it's actually two apps sharing one binary and one database. |
AuthAPI |
Login, sessions, tokens. Bridges Zitadel (the actual credential store) into a PlayTelly-shaped JWT. See Auth, Identity & RBAC for the full picture. |
tellyid |
The one shared, hosted login page every other frontend redirects to. |
OrgConsole (aka BizConsole) |
Org-level admin console. |
PlatformConsole |
Platform-level admin console — much smaller in practice than it looks; see CLAUDE.md §4. |
SpatioViewAdmin |
Ticketing admin portal (internally still sometimes called "TicketAdmin"). |
ticketcms |
Public customer-facing ticket storefront. |
PlayoutAdmin, TellyboardAdmin |
Other capability-app admin frontends. |
SpatioViewMobile |
Expo/React Native app — despite the ticketing-sounding name, its CoreAPI traffic is 100% native media/playback, no ticketing. |
ConciergeGuestApp |
Guest-facing WebRTC calling + chat app. |
Quickstart |
Docker Compose + Makefile — the local dev entry point. |
playtelly-iac |
Kustomize + ArgoCD + APISIX — the staging/production deployment repo. Completely separate mechanism from Quickstart; see Deployment. |
documentations |
This site. |
How the pieces talk to each other
graph LR
Z["Zitadel\n(credential vault)"]
A["AuthAPI"]
C["CoreAPI"]
T["tellyid\n(shared login)"]
Consoles["OrgConsole / PlatformConsole /\nSpatioViewAdmin / PlayoutAdmin / ..."]
Cms["ticketcms\n(legacy HS256, own login)"]
T -->|redirect_uri| Consoles
Consoles -->|POST /api/v1/login| A
A -->|verify password| Z
A -->|PSK: fetch role| C
Consoles -->|Bearer/cookie, ~all real traffic| C
Cms -->|separate legacy auth, unrelated to Zitadel| C
Every admin console is, in practice, a CoreAPI frontend — each touches
AuthAPI for exactly two things (token refresh, a session SSE stream) plus the
one-time login redirect through tellyid. Everything else — every real
feature, every table read/write — goes to CoreAPI directly. Full detail,
including the two consoles' actual vs. advertised API surface, in
CLAUDE.md §3–4 and Auth, Identity & RBAC.
CoreAPI is two applications in one binary
This is the single most important thing to know before touching CoreAPI's code: one Go binary, two independent route trees, one shared database.
- CoreAPI-native —
media,playback,distribution,provisioning,concierge,spatial,scheduling, plus native slices ofidentity/tenancy/notifications. Mounted under/api/v1/*. - Ticketing (a ported legacy system) — mounted at root paths:
/auth,/api/admin,/api/customer,/api/ticketGroups,/payment, etc. Same database connection —johorzoois a schema inside the onecoreapidatabase, not a separate one.
They use two incompatible response envelopes ({success,data,error} vs.
{respCode,respDesc,result}) and, in places, two different auth stacks —
native is RS256 throughout; ticketing's customer-facing routes are still
legacy HS256, while its admin routes migrated to RS256 in 2026. See
Auth, Identity & RBAC for exactly which routes use which, and
CLAUDE.md §2 for the full domain-folder-vs-mounted-app distinction (some
domain folders, like catalogue, straddle both apps).
New CoreAPI-native domains should follow media or distribution as the
reference layout — see the Development Guide and
Domains for the full 18-domain v3.4 ontology.
Running it: local dev vs. staging/production
These are two entirely different mechanisms — don't assume config from one applies to the other.
| Local dev | Staging / Production | |
|---|---|---|
| Repo | Quickstart |
playtelly-iac |
| Mechanism | docker compose via make <target> |
Kubernetes + Kustomize, synced by ArgoCD (GitOps) |
| Data | ephemeral, reseeded on down -v |
persistent, real |
| Where to start | Make Targets, Walkthrough | Deployment |
Bootstrapping a brand-new, empty environment (either kind) — how the first platform admin, the system roles, and the tenancy tables actually come into existence — is covered start-to-finish in Auth, Identity & RBAC §3.
Development Workflow
All feature work branches off staging and merges back to staging when
complete. Production releases are cut from staging → main.
staging
└── feature/your-feature ← branch from here, merge back when done
After merging, update the docs if your change affects anything other
developers need to know about — a new endpoint, a new domain, changed
environment variables, or updated setup steps. Edit the relevant .md files
directly in this repository and push to main.
Where to Go Next
- New to the codebase? → Installation, then Walkthrough
- How auth/RBAC actually works? → Auth, Identity & RBAC
- Deploying or debugging staging/prod? → Deployment
- Adding a domain or feature? → Development Guide
- What are the 18 domains, who owns each? → Domains, Ontology — Owners
- Managing the local stack? → Make Targets
- Testing an email/POS/payment integration? → Integrations