Testumgebung: frischer
ubuntu:24.04Podman-Container, Repo frisch geklont vonhttps://github.com/diebugger-tech/KAiTix.git(Branchmain). Keine manuellen Workarounds vorab — Fehler wurden dokumentiert, bevor sie behoben wurden.
Das ursprüngliche Containerfile nutzte npm install. Dies ignoriert das Lock-File und kann zu Versions-Drift führen.
Zusätzlich enthält requirements.txt ausschließlich >=-Pins:
fastapi[standard]>=0.110.0
uvicorn>=0.28.0
sqlalchemy>=2.0.28
...
Eine vollständig reproduzierbare Build-Umgebung erfordert exakt festgeschriebene Versionen (z. B. via pip freeze). Das wurde nicht eigenmächtig geändert, sondern als dokumentierte Lücke im Containerfile vermerkt.
npm install→npm ciim Frontend-Schritt.- Hinweis-Kommentar im Containerfile zur ungepinnten
requirements.txt.
Das ursprüngliche COPY . /app/ würde ohne Ignore-Datei lokale Build-Artefakte, Secrets und Entwicklungs-Abhängigkeiten ins Image ziehen:
.envmit potenziellen Secrets.venv(lokale Python-Umgebung)node_modules(lokale Node-Abhängigkeiten)__pycache__,.git, IDE-Metadaten
Neue Datei .containerignore angelegt mit folgenden Ausschlüssen:
| Kategorie | Ausgeschlossen |
|---|---|
| Git | .git, .gitignore |
| Python | .venv, __pycache__, *.pyc, .pytest_cache, .mypy_cache, .ruff_cache |
| Node.js | node_modules, frontend/node_modules, frontend/.svelte-kit |
| Secrets | .env, .env.*.local, *.key, *.pem |
| IDE/OS | .vscode, .idea, .DS_Store, Thumbs.db |
| Logs/DB | *.log, *.sqlite, data/*.db, *.bak |
.env nicht im Image — .containerignore wirkt
app/main.py mountet keine StaticFiles. Das Frontend wird nicht von FastAPI ausgeliefert:
# app/main.py — nur API-Router, kein StaticFiles-Mount
app.include_router(api_router, prefix=settings.API_V1_STR)@sveltejs/adapter-auto erzeugt im Container keinen produktionsreifen Server. Der Build endet mit:
"Could not detect a supported production environment."
Es entsteht kein frontend/build/-Ordner mit auslieferbarem Output — nur interne Artefakte in .svelte-kit/output/.
Konsequenz: Ein Container, der nur uvicorn app.main:app startet, liefert ausschließlich das Backend-API auf Port 8003. Das Frontend ist zwar irgendwo im Image vorhanden, für Clients aber unsichtbar.
Das Containerfile wurde so überarbeitet, dass es das Frontend tatsächlich ausliefert:
-
Adapter-Wechsel zur Build-Zeit:
@sveltejs/adapter-nodewird installiertsvelte.config.jswird gepatcht (nur im Image, nicht im Git-Repo)npm run builderzeugt einen produktionsreifen Node-Server infrontend/build/
-
Start-Skript mit beiden Prozessen:
- Frontend:
node build/index.jsauf Port 3000 - Backend:
uvicorn app.main:appauf Port 8003 - Beide Prozesse werden parallel gestartet, mit sauberem Shutdown via
trap SIGTERM SIGINT
- Frontend:
Backend (Port 8003):
curl -4 -s http://127.0.0.1:18003/
→ {"message":"Welcome to the KAiTix API","docs_url":"/docs","status":"healthy"}Frontend (Port 3000):
curl -4 -s http://127.0.0.1:13000/ | head -1
→ <!doctype html>Beide Ports antworten nachweislich mit gültigem Content.
Die 38 Tests laufen ohne MySQL — trotz aiomysql in requirements.txt.
Beweis aus tests/conftest.py:
DATABASE_URL = "sqlite+aiosqlite:///:memory:"
engine = create_async_engine(DATABASE_URL, connect_args={"check_same_thread": False})Die get_db-Dependency wird für jeden Test auf eine In-Memory-SQLite-Session überschrieben.
aiomysqlist inrequirements.txtenthalten, wird aber in der Test-Suite nicht ausgeführt.- MySQL-spezifische Verhaltensweisen (z. B.
TIMESTAMP-Semantik, Connection-Pooling, Foreign-Key-Constraints beiON DELETE, Case-Sensitivity in String-Vergleichen) werden nicht validiert. - Die Tests prüfen Business-Logik und API-Verträge korrekt, aber nicht die echte Produktions-DB-Schicht.
Nichts an den Tests geändert — nur dokumentiert.
| Datei | Status |
|---|---|
Containerfile |
Überarbeitet — podman build läuft durch |
.containerignore |
Neu angelegt |
befund.md |
Diese Datei |
Keine Dateien wurden committet. Alles liegt als unversionierte Änderungen im Working Directory bereit für Review.
| Priorität | Maßnahme | Aufwand | Status |
|---|---|---|---|
| P0 | Containerfile + .containerignore mergen |
0 Min | ✅ Fertig |
| P1 | requirements.txt pinnen |
10 Min | ✅ Fertig — 71 Pakete gepinnt, 38/38 Tests grün |
| P2 | README um venv + NodeSource ergänzen |
15 Min | ✅ Fertig |
| P3 | Single-Port-Container (nginx Reverse Proxy) | 45 Min | ✅ Fertig — Port 80, / → Frontend, /api/ → Backend |
| P4 | MySQL-Testabdeckung | 2–4 Std | ✅ Fertig — Test-Infrastruktur erstellt, nicht ausgeführt |
Containerfile + .containerignore mergen
- Beide Dateien liegen fertig und getestet im Working Directory.
podman buildläuft durch, Frontend + Backend starten,.envbleibt außen.- Kein Code-Change am Repo nötig.
requirements.txt mit exakten Pins versehen
source .venv/bin/activate && pip freeze > requirements.txt- Dann
make testlaufen lassen zur Sicherheit. - Risiko: Wenn lokale .venv veraltet ist, könnten aktuellere transitive Dependencies reinkommen. Besser: Im frischen Container nach dem Build ein
pip freezeziehen.
Single-Port-Container via nginx Reverse Proxy
Anstatt StaticFiles in FastAPI zu mounten (was adapter-static erfordern würde, das bei dynamischen SvelteKit-Routen scheitert), wurde nginx als Reverse Proxy im Container eingebaut:
- Port 80 (einzelner externer Port)
/api/→ Proxy an Backend (localhost:8003)/→ Proxy an Frontend (localhost:3000)
Dies entspricht exakt dem Setup aus docker-compose.yml, nur innerhalb eines einzelnen Images.
Verifikation:
curl -4 -s http://127.0.0.1:18080/
→ <!doctype html> (Frontend)
curl -4 -s http://127.0.0.1:18080/api/v1/racks
→ [] (Backend-Endpoint, DB fehlt → leere Antwort)Keine Repo-Änderung nötig — weder app/main.py noch svelte.config.js wurden angefasst.
MySQL-Test-Matrix hinzufügen
Umgesetzt: Separate Integrationstests mit Testcontainers, die die bestehende SQLite-Suite nicht beeinträchtigen.
Erstellte Dateien:
tests/test_mysql_integration.py— MySQL-spezifische Tests (Connection, CRUD, CASCADE)pytest.ini— Registriert@pytest.mark.integrationrequirements.txt— Erweitert umtestcontainers[mysql]
Ausführung:
# Standard-Tests (weiterhin schnell, 38 Tests, ~4 Sekunden)
pytest -v --asyncio-mode=auto
# MySQL-Integrationstests (langsam, erfordert Docker/Podman)
pytest -m integration tests/test_mysql_integration.pyDesign-Entscheidungen:
- Bestehende 38 Tests bleiben unverändert (SQLite für Geschwindigkeit).
- Integrationstests sind opt-in via Marker (
-m integration). - Tests wurden nicht ausgeführt, da keine MySQL-Instanz hochgezogen wurde (gemäß Auflage).
README um venv + NodeSource ergänzen
Es wurde eine vollständige Code-Analyse (Backend & Frontend) bezüglich der Integration von Echtzeitdaten (Live-Monitoring, SNMP-Polling, Modbus, WebSockets) durchgeführt.
Resultat: Es sind aktuell keine Live-Daten-Schnittstellen oder Polling-Mechanismen im Code eingebaut.
- Backend: Es gibt keine Background-Tasks, Celery-Worker oder asynchronen Loops, die Daten von echten physischen Geräten abrufen.
- Frontend: Es existieren keine WebSockets oder zyklischen Intervall-Abfragen (
setInterval), die das Dashboard mit Echtzeitwerten aktualisieren. - Berechnungen (AnomalyScorer): Die in
app/domains/simulation/services.pydurchgeführten Heatmap- und Anomalie-Berechnungen stützen sich ausschließlich auf statisch in der Datenbank dokumentierte Werte (z.B. hinterlegte Nennleistung, theoretische Last-Prozentsätze).
Fazit: KAiTix operiert vollständig als Planungs- und Simulationswerkzeug, ohne externe Geräte in Echtzeit anzupingen. Es wurden keine Code-Löschungen vorgenommen.