a8e808e71c
Initial commit. Establishes the .planning/ tree mirroring processor's shape (ROADMAP.md as nav hub + per-phase folders with READMEs and granular task files). Six phases: 1. Slice 1 schema + deploy pipeline — what Rally Albania 2026 needs. Org catalog (orgs, users, vehicles, devices) + event participation (events, classes, entries, entry_crew, entry_devices). db-init/ for the positions hypertable + faulty column. snapshot/apply tooling. Gitea CI dry-run. Dogfood seed of Rally Albania 2026. Nine task files with full Goal / Deliverables / Specification / Acceptance criteria / Risks / Done sections. 2. Course definition — stages, segments, geofences, waypoints, SLZs. PostGIS extension introduced here. 3. Timing & penalty tables — co-developed with processor Phase 2. entry_segment_starts, entry_crossings, entry_penalties, stage_results, penalty_formulas. 4. Permissions & policies — Directus 11 dynamic-filter Policies per logical role. Deployment-time work, deferred to keep early phases focused on the data model. 5. Custom extensions — TypeScript hooks/endpoints implementing the cross-plane workflows the schema implies (faulty-flag → Redis stream emit, stage-open materializer, etc.). 6. Future / optional — retroactivity preview UI, command-routing Flows, audit trails, federation rule import. Not committed. Non-negotiable design rules captured in ROADMAP.md: schema authority in Directus + snapshot-as-code + db-init for non-Directus DDL + sequential idempotent migrations + entrypoint apply order + no application logic in Flows + permissions deferred to Phase 4. Architectural anchors point at the wiki at ../docs/wiki/ — the schema draft, the Rally Albania 2025 source page, plus the existing processor/postgres-timescaledb/live-channel pages. Each task file calls out the wiki refs an implementing agent should read first. README.md mirrors the processor service README structure: quick start, local Docker test, prod/stage deployment notes, env vars, CI behavior.
95 lines
4.6 KiB
Markdown
95 lines
4.6 KiB
Markdown
# directus
|
|
|
|
The TRM business plane. Directus 11 instance owning the relational schema (`organizations`, `users`, `events`, `entries`, course definition, penalty system, timing tables), exposing it through auto-generated REST/GraphQL APIs and the admin UI, and enforcing role-based permissions.
|
|
|
|
For the architectural specification see [`../docs/wiki/entities/directus.md`](../docs/wiki/entities/directus.md). For the work plan and task status see [`.planning/ROADMAP.md`](./.planning/ROADMAP.md).
|
|
|
|
This service is part of the [TRM](https://git.dev.microservices.al/trm) (Time Racing Management) platform.
|
|
|
|
---
|
|
|
|
## Schema management — at a glance
|
|
|
|
Schema is **defined and migrated through Directus**, with two artifact directories:
|
|
|
|
- **`snapshots/schema.yaml`** — Directus collections, fields, relations. Generated locally via `directus schema snapshot`, applied at container startup via `directus schema apply`.
|
|
- **`db-init/*.sql`** — schema Directus does not manage: the [[postgres-timescaledb]] `positions` hypertable, the `faulty` column, PostGIS-specific DDL, etc. Sequential numbered files (`001_`, `002_`, …) applied by `scripts/apply-db-init.sh` with a `migrations_applied` guard table to skip already-run files.
|
|
|
|
Apply order at boot: **db-init first, then `directus schema apply`, then `directus start`.** Any failure halts boot.
|
|
|
|
---
|
|
|
|
## Quick start (local)
|
|
|
|
**Prerequisites:** Docker, the `directus/directus:11.x` image (pulled by compose), a running Postgres 16 + TimescaleDB + PostGIS instance.
|
|
|
|
```bash
|
|
git clone <repo-url>
|
|
cd directus
|
|
cp .env.example .env
|
|
# Edit .env — at minimum set DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE, KEY, SECRET
|
|
docker compose -f compose.dev.yaml up --build
|
|
```
|
|
|
|
Admin UI lands at `http://localhost:8055`. Default admin credentials are read from `ADMIN_EMAIL` / `ADMIN_PASSWORD` in `.env`.
|
|
|
|
After making schema changes in the admin UI, snapshot before commit:
|
|
|
|
```bash
|
|
pnpm run schema:snapshot
|
|
git add snapshots/schema.yaml && git commit
|
|
```
|
|
|
|
---
|
|
|
|
## Test the image locally
|
|
|
|
`compose.dev.yaml` builds the image from source and runs it next to a TimescaleDB+PostGIS container. Useful for verifying Dockerfile changes, db-init migrations, or snapshot apply behavior before pushing.
|
|
|
|
```bash
|
|
docker compose -f compose.dev.yaml down -v # wipe volumes for a fresh run
|
|
docker compose -f compose.dev.yaml up --build
|
|
```
|
|
|
|
The entrypoint runs db-init, then `directus schema apply`, then `directus start`. Watch the logs to confirm each step exits 0.
|
|
|
|
---
|
|
|
|
## Production / stage deployment
|
|
|
|
This service is **not** deployed standalone. It runs as part of the platform stack defined in the [`deploy/`](https://git.dev.microservices.al/trm/deploy) repo, which Portainer pulls and runs on the stage and production hosts.
|
|
|
|
The image itself is published to `git.dev.microservices.al/trm/directus:main` on every push to `main` (see CI behavior below). The `deploy/` repo's `compose.yaml` references that image.
|
|
|
|
To pin a specific commit in production, set `DIRECTUS_TAG=<sha>` in the deploy stack's environment variables.
|
|
|
|
> **Note:** The `deploy/compose.yaml` will need a `directus` service entry referencing this image, plus a TimescaleDB+PostGIS service if not already present, before this service can run in stage/production. See `.planning/phase-1-slice-1-schema/07-image-and-dockerfile.md`.
|
|
|
|
---
|
|
|
|
## Environment variables
|
|
|
|
See `.env.example` for the full list. Required for boot:
|
|
|
|
| Variable | Description |
|
|
|---|---|
|
|
| `DB_CLIENT` | `pg` (always) |
|
|
| `DB_HOST` / `DB_PORT` / `DB_DATABASE` / `DB_USER` / `DB_PASSWORD` | Postgres connection |
|
|
| `KEY` | Directus instance key (random UUID) |
|
|
| `SECRET` | Directus JWT signing secret (random) |
|
|
| `ADMIN_EMAIL` / `ADMIN_PASSWORD` | Bootstrap admin (only used on first init) |
|
|
| `PUBLIC_URL` | External-facing URL of the instance |
|
|
|
|
All other Directus envs (cache, logging, CORS, etc.) follow upstream defaults unless overridden.
|
|
|
|
---
|
|
|
|
## CI behavior
|
|
|
|
Gitea Actions workflow is at `.gitea/workflows/build.yml`.
|
|
|
|
- **Push to `main`** (only when `snapshots/`, `db-init/`, `extensions/`, `Dockerfile`, or the workflow file itself changes): builds the image, spins up a throwaway Postgres + TimescaleDB + PostGIS via `services:`, runs `apply-db-init.sh` and `directus schema apply --yes` against it as a **dry-run**, then publishes the image tagged `:main` if the dry-run exits 0. Auto-deploys to stage if a Portainer webhook is configured via `secrets.PORTAINER_WEBHOOK_URL`.
|
|
- **Manual trigger** (`workflow_dispatch`): same flow, run on demand.
|
|
|
|
The dry-run is non-negotiable — it catches snapshot drift, broken db-init scripts, and incompatible schema changes before they touch any real DB.
|