Task 1.2 — db-init runner script

scripts/apply-db-init.sh implements the boot-time runner that walks
db-init/*.sql in numeric-prefix order, applies each via psql, and
records successful applications in a migrations_applied guard table
so re-runs are no-ops.

All 7 acceptance criteria pass live against the dev compose stack:
empty dir, missing env var, apply, idempotent re-run, checksum
mismatch, filename collision, broken SQL.

Two retroactive Dockerfile corrections folded in (exposed by the
first live-test attempt of 1.2's script):

1. apk add bash. The directus/directus:11.17.4 base is Alpine and
   ships ash via BusyBox, not bash. The script uses bash-specific
   features (associative arrays, [[ ]], mapfile, BASH_REMATCH) and
   fails at line 69 in sh.

2. .gitattributes added at repo root forcing LF on *.sh, *.sql,
   *.yaml, *.yml. Without it, Windows checkouts with core.autocrlf=true
   (the Git-for-Windows default) silently inject CRLF, causing
   "bad interpreter: /usr/bin/env bash^M" inside the Linux container.
   This failure mode only manifests in the container.

Both corrections are documented in 01-project-scaffold.md's Done
section; 02-db-init-runner.md's Done section captures the live-test
results, the corrected docker compose run --entrypoint commands, and
the gotcha about compose env defaults masking missing-env-var tests.

ROADMAP marks 1.2 done; 1.3 next.
This commit is contained in:
2026-05-01 22:35:17 +02:00
parent 387c3c4cfa
commit dec2d190ce
7 changed files with 418 additions and 9 deletions
+2 -2
View File
@@ -42,7 +42,7 @@ These rules govern every task. Any deviation must be discussed and documented as
### Phase 1 — Slice 1 schema + deploy pipeline
**Status:** 🟨 In progress (1.1 done; 1.2 next)
**Status:** 🟨 In progress (1.1, 1.2 done; 1.3 next)
**Outcome:** A Directus instance with the org-level catalog (orgs, users, organization_users, vehicles, devices and their org junctions) and event-participation collections (events, classes, entries, entry_crew, entry_devices) live and snapshot-tracked. `db-init/` covers the TimescaleDB extension, the `positions` hypertable, and the `faulty` column. Image builds via Gitea Actions with a CI dry-run that catches snapshot drift before deploy. Rally Albania 2026 is registered as the first event in admin UI to dogfood the registration workflow. **This is what Rally Albania 2026 needs.**
[**See `phase-1-slice-1-schema/README.md`**](./phase-1-slice-1-schema/README.md)
@@ -50,7 +50,7 @@ These rules govern every task. Any deviation must be discussed and documented as
| # | Task | Status | Landed in |
|---|------|--------|-----------|
| 1.1 | [Project scaffold](./phase-1-slice-1-schema/01-project-scaffold.md) | 🟩 | pending user commit |
| 1.2 | [db-init runner script](./phase-1-slice-1-schema/02-db-init-runner.md) | | |
| 1.2 | [db-init runner script](./phase-1-slice-1-schema/02-db-init-runner.md) | 🟩 | pending user commit |
| 1.3 | [Initial migrations (extensions, positions hypertable, faulty column)](./phase-1-slice-1-schema/03-initial-migrations.md) | ⬜ | — |
| 1.4 | [Org-level catalog collections](./phase-1-slice-1-schema/04-org-catalog-collections.md) | ⬜ | — |
| 1.5 | [Event-participation collections](./phase-1-slice-1-schema/05-event-participation-collections.md) | ⬜ | — |