enclosure
Django API scaffold with JSON logs, dotenv settings, health checks, and auto-discovered Django Ninja Extra controllers.
uv sync
uv run python manage.py migrate
uv run python manage.py runserver
Siren browser
The TypeScript Siren browser is available at GET /. It starts from /siren/, follows advertised links, and renders forms for advertised actions.
After changing its source, build the static files before starting Django or building the image:
cd browser
npm ci
npm run typecheck
npm run build
The built files live in the Django browser adapter's static directory. The production image runs collectstatic, and WhiteNoise serves the manifest-versioned assets.
Isolated scaffolding API
The container runtime reuses the existing PostgreSQL state; it does not createor own a database service or volume. It reuses the host DATABASE_URL alreadyin the ignored .env file. Compose overrides only its network address topostgres:5432 because the API joins the externalmodwire-records_default Docker network. The host configuration remains onlocalhost:5433; credentials have one source of truth.
Released runtime images are pulled from GHCR. The default is latest; pin theservice to one immutable release with ENCLOSURE_RUNTIME_VERSION, for example:
ENCLOSURE_RUNTIME_VERSION=0.2.1 make runtime-up
The packages are private. Authenticate GitHub CLI once with read:packages;runtime commands then use its token through a temporary Docker configurationthat is deleted immediately after the pull:
gh auth refresh -h github.com -s read:packages
Each GitHub release publishes linux/amd64 and linux/arm64 variants ofghcr.io/szpak-dev/enclosure-runtime. Docker selects the matching image onIntel Linux, Intel macOS, or Apple Silicon macOS hosts. Local image builds arean explicit development mode and never occur during normal installation:
make runtime-build-up
Validate and start only the API:
make runtime-config
make runtime-up
curl --fail http://127.0.0.1:8100/health/
Container startup never applies migrations. Before a migration, create aPostgreSQL backup and capture the exact Django migration plan:
make runtime-db-prepare
Review both paths printed by that command. Apply the reviewed plan only bypassing those same artifacts through the guarded command:
CONFIRM_EXISTING_DATABASE_MIGRATION=reviewed \
MODWIRE_DATABASE_BACKUP=.dev/database-safety/modwire-records-TIMESTAMP.dump \
MODWIRE_DATABASE_MIGRATION_PLAN=.dev/database-safety/migration-plan-TIMESTAMP.txt \
make runtime-db-migrate
make runtime-down removes the API container only. The external PostgreSQLcontainer, network, and modwire-records_postgres_data volume are untouched.
For non-container development, keep using the host DATABASE_URL (currentlythe host-side PostgreSQL port) with the original uv run commands above. Itsdefault HTTP port remains 8000, separate from the container runtime on8100.
API
The auth-free API entry point is GET /api/. Mutating record endpoints useX-Actor-Id and X-Actor-Type for attribution; actor types are user andagent.