ITADN
zeepkist/zeepcentraal
README.md

ZeepCentraal (V3)

A Bun workspace monorepo for ZeepCentraal services.

What This Repository Is

  • A modular API backend built with Elysia and Bun.
  • A PostgreSQL-backed data layer using Drizzle ORM.
  • A background processing system using graphile-worker for durable jobs and cron scheduling.

Workspace Layout

  • packages/core: shared config, auth, errors, integrations, and utility primitives.
  • packages/database: Drizzle schema, migrations, and data services.
  • packages/server: HTTP API process (Elysia routes and plugins).
  • packages/jobs: background worker process (graphile-worker tasks + cron scheduler).
  • packages/workshop: Steam metadata, SteamCMD downloads, parsing, and workshop reconciliation.

Prerequisites

Before you start, install:

  • Bun (latest stable): https://bun.sh
  • PostgreSQL (running locally or remotely and reachable from DATABASE_URL)
  • Git
  • Docker (optional, only needed for container builds/runs)
  • SteamCMD (only needed when running workshop jobs outside Docker)

Quick Start

1. Clone and install dependencies

git clone <repo-url>
cd zeepcentraal
bun install

2. Create environment file

macOS/Linux:

cp .env.example .env

PowerShell:

Copy-Item .env.example .env

3. Configure required environment values

At minimum, set these values in .env:

VariableRequiredNotes
DATABASE_URLYesPostgreSQL connection string
TRIGGER_JOB_TOKENYesToken used for protected job trigger endpoints
JWT_SECRETYesMust be at least 32 characters
CORS_ALLOWED_ORIGINSNoComma-separated website origins; defaults to FRONTEND_URL
TRUST_PROXYNoTrust forwarded client IP headers for rate limiting

The remaining values in .env.example are optional or have defaults, but you should configure them for your environment (Steam, Discord, Wasabi/S3, and OpenTelemetry).

4. Apply database migrations

bun run db:migrate

If you changed schema and need to generate new migrations first:

bun run db:generate
bun run db:migrate

5. Start local development processes

Run API and jobs in separate terminals.

Terminal 1 (API):

bun run dev:server

Terminal 2 (jobs):

bun run dev:jobs

Health check:

curl http://localhost:3000/healthz

Expected response:

{"status":"ok"}

Development Commands

CommandWhat it does
bun run dev:serverStarts API in watch mode
bun run dev:jobsStarts jobs worker in watch mode
bun run db:studioOpens Drizzle Studio
bun run db:generateGenerates Drizzle migrations
bun run db:migrateApplies pending migrations
bun run typecheckRuns TypeScript type check
bun run testRuns test suite
bun run lintRuns Biome checks
bun run lint:fixApplies Biome autofixes
bun run lint:stagedApplies Biome fixes to staged files
bun run build:serverCompiles server binary to dist/
bun run build:jobsCompiles jobs binary to dist/

Releases

bun run release versions the whole monorepo from conventional commits.

Git Hooks

bun install configures native Git hooks from .githooks through local core.hooksPath. Before each commit the pre-commit hook applies Biome fixes to staged files, then runs the full typecheck and test suite. Use git commit --no-verify only when an emergency bypass is required.

Build and Docker

Build local binaries:

bun run build:server
bun run build:jobs

Build Docker images:

docker build -f Dockerfile.server -t zeepcentraal-server .
docker build -f Dockerfile.jobs -t zeepcentraal-jobs .
docker build -f Dockerfile.migrate -t zeepcentraal-migrate .
docker build -f Dockerfile.zsl -t zeepcentraal-import-zsl .

Run Docker images with environment values:

docker run --env-file .env -p 3000:3000 zeepcentraal-server
docker run --env-file .env zeepcentraal-jobs
docker run --env-file .env zeepcentraal-migrate

Run ZSL import container:

git clone --branch data https://github.com/zeepkist/super-league.git super_league_data
docker build -f Dockerfile.zsl -t zeepcentraal-import-zsl .
docker run --env-file .env zeepcentraal-import-zsl