A TypeScript monorepo delivering three product pillars in one native application — there is no Moodle, LibreBooking, or pretix in the target system. Those were an early reference approach and have been removed; do not reintroduce them.
Architecture rebuild: the provider-neutral Kubernetes bootstrap is under
deploy/, contributor commands are indocs/development.md, and coding-agent constraints are inAGENTS.md/CLAUDE.md.docker-compose*.yml,docker/, andk8s/deployment.yamlremain legacy migration references only.
| Pillar | Description |
|---|---|
| 🎓 Learning | Native course authoring, publishing, purchase, viewer, progress, assessment |
| 🎸 Booking | Teacher discovery, availability, exact teacher-defined slots, Stripe payment |
| 🎪 Events | Teacher-published events plus normalized external discovery (Ticketmaster, later Classictic) and Europeana cultural-heritage content |
All three are modules of the same application, not separate platforms.
| Workload | Role |
|---|---|
apps/web |
Next.js UI |
apps/api |
GraphQL API + webhooks (Stripe at /api/webhooks/stripe) |
apps/worker |
Async jobs: webhook processing, email, external-event ingestion, retries (being introduced — async work currently runs in-process in the API) |
Shared code lives in packages/database (Prisma, db push workflow), packages/graphql-schema,
and packages/mcp-server.
- Keycloak is the identity authority (OIDC, PKCE, server-side sessions).
- The application PostgreSQL database owns profiles, roles, marketplace, bookings, courses,
entitlements, and progress.
UserExternalIdentitymaps the immutable Keycloaksubto the platform user. - Stripe test mode only in development. Payment state is a state machine; the signed webhook — never the browser redirect — confirms payment.
- External providers (Ticketmaster, Europeana, later Classictic) are read-only discovery inputs behind server-side adapters.
Production and development both target DigitalOcean Kubernetes (DOKS), reached through a
Cloudflare Tunnel — there is no public LoadBalancer or ingress controller. GitHub Actions builds
SHA-tagged images, syncs secrets from GitHub environment secrets, and applies manifests to the
cluster; local development does not require cluster access. See deploy/README.md
for the Kustomize layout and docs/deployment.md for the deployment path.
- Node.js ≥ 20 + npm ≥ 10
- Docker with Compose v2 only if you want the legacy local stack (Postgres, Redis, Keycloak, MinIO)
npm ci
cp .env.example .env
npm run db:generatenpm run dev
# or a single workspace:
npm run dev --workspace @my-music-coach/web
npm run dev --workspace @my-music-coach/apiSee docs/development.md for the full command reference (build, test, lint,
database commands, and rendering the Kubernetes manifests without touching a cluster).
The Compose topology in docker-compose.yml (Postgres, Redis, Keycloak,
MinIO, the app workloads, and the MCP server) remains available as a migration reference. It is
not the target architecture — that's the DOKS layout under deploy/.
docker compose config # render only
docker compose up -d --build
docker compose down- Backend: Node.js · TypeScript · Apollo Server 4 (GraphQL) · Prisma · PostgreSQL 16
- Frontend: Next.js 14 · TypeScript · Tailwind CSS · Apollo Client
- Auth: Keycloak (OpenID Connect, PKCE, server-side sessions) — central identity for the app
- Payments: Stripe (test mode in development), Stripe Connect for teacher/seller payouts
- AI: MCP Server
- Infrastructure: DigitalOcean Kubernetes (Kustomize) behind a Cloudflare Tunnel; Docker Compose kept only as a legacy local-dev reference
apps/api/ GraphQL API (Apollo Server + Express)
apps/web/ Next.js 14 frontend
apps/worker/ Async job runner (being introduced)
packages/database/ Prisma schema (PostgreSQL)
packages/graphql-schema/ Shared GraphQL SDL
packages/mcp-server/ MCP server (AI tools)
deploy/ Provider-neutral Kustomize scaffold (target Kubernetes layout)
docker/ Legacy Compose build contexts (gateway, keycloak) — migration reference
docker-compose.yml Legacy local dev stack — migration reference, not the target architecture
k8s/ Legacy Kubernetes manifest — migration reference, not the target layout
docs/
development.md Contributor commands (install, build, test, lint, manifest rendering)
deployment.md Deployment path and GitHub Actions/DOKS details
cloudflare-tunnel.md Cloudflare Tunnel setup and routing
AGENTS.md/CLAUDE.md— coding-agent guidance and guardrailsdocs/development.md— install, build, test, lint, and manifest renderingdocs/deployment.md— deployment path (GitHub Actions → DOKS)docs/cloudflare-tunnel.md— Cloudflare Tunnel setup and routingdeploy/README.md— target Kubernetes (Kustomize) layout