Phase 0: Fundament der Feuerwehr-Verwaltungsplattform
Legt den kompletten Unterbau an, auf dem die Fachmodule aufsetzen. Betrieb: - docker-compose.yml mit Traefik, App, Worker, PostgreSQL 17 + PostGIS, Redis, MinIO und Gotenberg; Entwicklungs-Override ohne Traefik, dafuer mit Mailpit und Adminer - Mehrstufiges Dockerfile: eigener Benutzer, tini als PID 1, Healthcheck - .env.example mit einem Kommentar zu jeder Variable Mandantentrennung: - Row Level Security auf allen mandantenpflichtigen Tabellen - Zwei getrennte Datenbankverbindungen: florian_app mit aktiver RLS fuer die Anwendung, Eigentuemer-Zugang nur fuer Migration, Seed und Anmeldung - fuerOrganisation() als einziger Weg zu Fachdaten Nachvollziehbarkeit: - AuditLog append-only per Trigger; UPDATE ist dauerhaft gesperrt, DELETE nur im gekennzeichneten Aufbewahrungslauf - Geheimnisse werden vor dem Schreiben entfernt Anmeldung: - OIDC gegen ein extern betriebenes authentik, Rollen aus Gruppen nur als Vorbelegung beim ersten Login - Lokaler E-Mail/Passwort-Login als Rueckfallweg - Terminal per PIN und RFID mit zwei Schranken (Geraet, dann Person) Weiteres: - lib/authz.ts mit 9 Rollen und 38 Einzelrechten - lib/storage.ts (MinIO), lib/audit.ts, lib/warteschlange.ts (BullMQ) - Integrationen fuer Mail, Telegram und LLM hinter abschaltbaren Interfaces - tRPC v11, Basis-Layout mit Seitenleiste und dunkler Darstellung - Seed mit einer Beispielwehr: 16 Personen, 3 Fahrzeuge, 40 Geraete - 32 Vitest-Tests (davon 8 gegen eine echte Datenbank), 10 Playwright-Tests - README, Anleitung mit Screenshots, Roadmap, Aufwandsschaetzung, Devlog, Versionierungsregeln und Changelog Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# =============================================================================
|
||||
# Entwicklungs-Override. Docker Compose lädt diese Datei automatisch zusätzlich
|
||||
# zu docker-compose.yml — für den Produktionsbetrieb daher explizit nur die
|
||||
# Hauptdatei angeben:
|
||||
# docker compose -f docker-compose.yml up -d
|
||||
#
|
||||
# Unterschiede zur Produktion:
|
||||
# - kein Traefik (die Dienste hängen direkt an localhost-Ports)
|
||||
# - Quellcode als Bind-Mount, Hot Reload über "next dev"
|
||||
# - Mailpit als lokaler SMTP-Auffangkorb
|
||||
# - Adminer zum Draufschauen auf die Datenbank
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
traefik:
|
||||
# Wird in der Entwicklung nicht gebraucht. Mit dem Profil "proxy" trotzdem
|
||||
# startbar: docker compose --profile proxy up -d
|
||||
profiles: ["proxy"]
|
||||
|
||||
postgres:
|
||||
ports:
|
||||
- "${POSTGRES_PORT:-5432}:5432"
|
||||
|
||||
redis:
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
|
||||
minio:
|
||||
ports:
|
||||
- "${MINIO_API_PORT:-9000}:9000"
|
||||
- "${MINIO_CONSOLE_PORT:-9001}:9001"
|
||||
environment:
|
||||
# Ohne TLS-Terminierung zeigt die Konsole auf localhost.
|
||||
MINIO_BROWSER_REDIRECT_URL: http://localhost:${MINIO_CONSOLE_PORT:-9001}
|
||||
MINIO_SERVER_URL: http://localhost:${MINIO_API_PORT:-9000}
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
|
||||
gotenberg:
|
||||
ports:
|
||||
- "${GOTENBERG_PORT:-3101}:3000"
|
||||
|
||||
app:
|
||||
build:
|
||||
target: builder
|
||||
command: ["npm", "run", "dev"]
|
||||
ports:
|
||||
# "next dev" laeuft im Container auf 3100 (siehe package.json).
|
||||
- "${APP_PORT:-3100}:3100"
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
# Datei-Watching funktioniert über Bind-Mounts von Windows aus nur mit
|
||||
# Polling zuverlässig.
|
||||
WATCHPACK_POLLING: "true"
|
||||
CHOKIDAR_USEPOLLING: "true"
|
||||
volumes:
|
||||
- ./src:/app/src
|
||||
- ./prisma:/app/prisma
|
||||
- ./public:/app/public
|
||||
- ./tests:/app/tests
|
||||
- ./next.config.ts:/app/next.config.ts
|
||||
- ./tsconfig.json:/app/tsconfig.json
|
||||
- ./postcss.config.mjs:/app/postcss.config.mjs
|
||||
# Anonyme Volumes: node_modules und .next bleiben im Container.
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
|
||||
worker:
|
||||
build:
|
||||
target: builder
|
||||
command: ["npm", "run", "worker:dev"]
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
ROLLE: worker
|
||||
volumes:
|
||||
- ./src:/app/src
|
||||
- ./prisma:/app/prisma
|
||||
- /app/node_modules
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Nur Entwicklung: SMTP-Auffangkorb. Alle Mails landen hier statt beim
|
||||
# Empfänger. Weboberfläche: http://localhost:${MAILPIT_UI_PORT:-8125}
|
||||
# ---------------------------------------------------------------------------
|
||||
mailpit:
|
||||
image: axllent/mailpit:latest
|
||||
container_name: florian-mailpit
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MP_MAX_MESSAGES: 500
|
||||
TZ: ${TZ:-Europe/Berlin}
|
||||
ports:
|
||||
- "${MAILPIT_UI_PORT:-8125}:8025"
|
||||
- "${MAILPIT_SMTP_PORT:-1125}:1025"
|
||||
networks:
|
||||
- intern
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Nur Entwicklung: schlanke Datenbankoberfläche. http://localhost:${ADMINER_PORT:-8081}
|
||||
# Anmeldung: System PostgreSQL, Server "postgres", Benutzer/Passwort aus .env
|
||||
# ---------------------------------------------------------------------------
|
||||
adminer:
|
||||
image: adminer:latest
|
||||
container_name: florian-adminer
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
ADMINER_DEFAULT_SERVER: postgres
|
||||
ADMINER_DESIGN: dracula
|
||||
ports:
|
||||
- "${ADMINER_PORT:-8081}:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- intern
|
||||
Reference in New Issue
Block a user