Local development
How to get the platform running on your machine. Start here on your first day.
Prerequisites
- Node.js (LTS) and pnpm (the workspace package manager).
- Docker — for a local Supabase stack (or the Supabase CLI).
- The Supabase CLI if you want local Postgres + Auth + Realtime.
Clone & install
git clone <repo-url> playlogiq-crm-gamification-hub
cd playlogiq-crm-gamification-hub
pnpm installEnvironment variables
Copy the root example and fill each app’s .env.local:
cp .env.example apps/web/.env.local
cp .env.example apps/api/.env.local
# …and player / worker as neededThe required variables for basic local work (Phase 0/1):
| Variable | Used by | Notes |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | all apps | Your Supabase gateway URL. |
NEXT_PUBLIC_SUPABASE_ANON_KEY | all apps | Public anon key. |
SUPABASE_SERVICE_ROLE_KEY | api, worker | Server-side only — never exposed to the client. |
REDIS_URL | api, worker | Cache, rate limiting, BullMQ. |
App URLs (NEXT_PUBLIC_APP_URL, …_PLAYER_URL, …_API_URL, …_DOCS_URL) and
channel/provider secrets (SMTP, TELEGRAM_BOT_TOKEN, VAPID keys, …) are needed
only for the features that use them. The full, annotated list is in
.env.example.
The
apicontainer also readsALLOW_SERVICE_ROLE_API_KEY(default off) — a dev-only backdoor that maps the service-role key to a super-admin API key. Leave it unset in production. See PAM Integration → Authentication.
Database (Supabase local)
supabase start # local Postgres + Auth + Realtime + Studio
supabase db reset # apply all migrations + seed dataAfter any schema change, regenerate the typed client:
supabase gen types typescript --local > packages/db/src/types.tsSee Database & RLS for the migration and RLS model, and Data model for the entities.
Run the apps
pnpm dev # all apps (Turborepo)
pnpm --filter @playlogiq/web dev # just the dashboard (:3000)
pnpm --filter @playlogiq/api dev # just the API (:3002)| App | Port | URL |
|---|---|---|
| web (dashboard) | 3000 | http://localhost:3000 |
| player (portal) | 3001 | http://localhost:3001 |
| api (REST v1) | 3002 | http://localhost:3002/api/v1 |
| docs | 3003 | http://localhost:3003 |
Quality gates
Run these before committing — CI runs the same:
pnpm lint # ESLint (flat config)
pnpm typecheck # tsc --noEmit across the workspace
pnpm build # Turborepo buildUnit tests (Vitest) live in packages:
pnpm --filter @playlogiq/integrations test # e.g. the mapping engineDatabase/RLS tests run against a throwaway Postgres:
DATABASE_URL=postgresql://user@host:port/db supabase/tests/run.shAdding a database migration
- Create
supabase/migrations/NNN_description.sql(next sequential number). - Make it idempotent where practical (
IF NOT EXISTS,CREATE OR REPLACE,DROP POLICY IF EXISTSbeforeCREATE POLICY). - Add the filename to the
MIGRATIONSlist insupabase/tests/run.sh. - Run
supabase/tests/run.shagainst a clean Postgres to prove it applies and RLS still passes. - Regenerate types (
supabase gen types).
See Conventions for the non-obvious rules, and Deployment for how migrations reach production.
Project layout
The monorepo layout (apps + shared packages) is in Monorepo & apps. Two conventions to internalize early:
apps/web/app/(dashboard)/is a route group — pages render at/,/players, … (not/dashboard/*).- Shared packages export TypeScript source (no build step); apps transpile them.