--- name: nexus-stack description: Stack-Konventionen fuer nexus (Family Knowledge Hub) seit K-101. Verwenden bei jeder Implementierungs-Karte im Repo l.kirchner/nexus-hub - deckt ab uv-Projektlayout, FastAPI-Patterns, Settings, structlog-Redaction-Pflicht, Alembic, Web-Build, Deploy-Artefakt und Projekt-Kommandos. --- # nexus Stack-Konventionen (ADR-0002, eingeführt mit K-101) ## Layout & Werkzeuge - **Backend:** uv-Projekt, Python 3.12, src-Layout `src/nexus/`. Console-Scripts: `nexus-api`, `nexus-worker`. - **Web:** `web/` — Vite + React + TypeScript + Tailwind v4 (`@tailwindcss/vite`). Build-Artefakt `web/dist` wird von FastAPI unter `/` ausgeliefert (API-Routen gewinnen; SPA via `StaticFiles(html=True)`). - **Kommandos** (verbindliche Liste: `docs/05_AGENT_RULES.md` → Projekt-Kommandos): `uv sync`, `uv run pytest`, `uv run ruff check`, `uv run mypy`, `uv run alembic upgrade head`, `npm run build` in `web/`. - Vor jedem Merge lokal grün: ruff + mypy (strict) + pytest; CI (`.gitea/workflows/ci.yml`) führt dieselben Gates aus. ## Settings & Konfiguration - Eine `Settings`-Klasse (`src/nexus/config.py`, pydantic-settings, Prefix `NEXUS_`), Zugriff via `get_settings()` (lru_cache). Tests leeren den Cache (siehe `tests/conftest.py`-Fixture). - Produktion liest `/etc/nexus/env` (systemd `EnvironmentFile`). Neue Settings dort dokumentieren (proxmox-scripts `install/nexus-install.sh` legt die Datei an). - `Settings.__repr__` redacted Secrets (`database_url=***`) — bei neuen Secret-Feldern beibehalten. - Version = Git-SHA: `NEXUS_GIT_SHA` env → `GIT_SHA`-Datei im Artefakt (schreibt deploy.yml) → `"dev"`. ## Logging (PRIV-5 — nicht verhandelbar) - IMMER `nexus.logging_setup.configure_logging()` — nie eigenes logging-Setup, nie `print`. - Content-Keys (`body`, `content`, `text`, `ocr_text`, `title`, `filename`, …) werden vom Redaction-Processor auf `***` gesetzt. Neue content-tragende Felder in `CONTENT_KEYS` ergänzen — niemals umbenennen, um Redaction zu umgehen. - Log-Zeilen tragen IDs + Metadaten, nie Inhalte. Secrets (DB-Passwörter, Tokens) zusätzlich als `secrets=[...]` an `configure_logging` geben. - Jede Karte mit neuen Log-Pfaden ergänzt einen Redaction-Test nach dem Muster `tests/test_logging_redaction.py`. ## Datenbank & Migrationen - SQLAlchemy 2 + Alembic; DSN ausschließlich über `NEXUS_DATABASE_URL` (sqlalchemy-Format `postgresql+psycopg://…`), nie in Dateien. - Migrationen: `alembic/versions/`, Template ist typisiert (`script.py.mako`). Erste Fach-Migration kommt mit K-103 (setzt auch `target_metadata`). - `/healthz` meldet `db: unconfigured | ok | unreachable` — Karten, die die DB anschließen, halten dieses Feld korrekt. ## Deploy (deploy.yml, seit K-101 scharf) - Push auf `main` → Test-Gate (`needs:`) → Artefakt (`src/`, `pyproject.toml`, `uv.lock`, `alembic*`, `start*.sh`, `GIT_SHA`, `web/dist`) → rsync nach `/opt/nexus/current` → `uv sync --frozen --no-dev` → Service-Restart → Healthcheck. - Rollback: voriger Stand liegt in `/opt/nexus/previous` (Prozedur im deploy.yml-Header). - systemd: `nexus.service` → `start.sh` (uvicorn), `nexus-worker.service` → `start-worker.sh`. Runtime-Provisionierung des LXC: proxmox-scripts `install/nexus-runtime.sh` (idempotent). ## Rote Linien - Kein `requirements.txt`, kein pip — uv ist die einzige Quelle der Wahrheit (`uv.lock` committed). - Keine neuen Top-Level-Prozesse außer API + Worker ohne ADR. - API-first: jeder User-Workflow hat API-Tests, bevor/während die UI ihn bekommt.