Files

13 KiB

Runtime Report — ERP Nutzfahrzeuge

Date: 2026-07-17 Phase: 5 — Runtime Verification Runtime: /opt/venv/bin/python (execution environment)


Summary

Check Status
Backend startup PASS
Health endpoint PASS (200, {"status":"ok"})
Root endpoint PASS (200, app metadata)
Auth login (GET) PASS (405 Method Not Allowed — POST-only)
OpenAPI/Swagger PASS (200, full schema)
Frontend build artifacts PASS (.next/ with BUILD_ID, server/, static/)
Runtime errors NONE (clean logs, no tracebacks)
PostgreSQL Running (localhost:5432, accepting connections)
Redis ⚠️ NOT installed (JWT-based refresh tokens, no Redis storage needed)

Overall verdict: Backend starts and runs cleanly. All public endpoints respond as expected. No runtime errors detected.


1. Startup Verification

Start command:

cd backend && /opt/venv/bin/python -m uvicorn app.main:app --host 0.0.0.0 --port 8000

Result: Server started successfully (PID 3383733).

Startup log:

INFO:     Started server process [3383733]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

Import check: from app.main import app — OK (no ImportError)

Core dependencies verified:

  • uvicorn
  • fastapi
  • sqlalchemy
  • asyncpg

2. Health Check

Endpoint: GET http://localhost:8000/api/v1/health

Response:

  • HTTP Status: 200 OK
  • Body: {"status":"ok"}

Verdict: Health endpoint reachable and returning expected payload.


3. Endpoint Verification

3.1 Root Endpoint

  • URL: GET http://localhost:8000/
  • HTTP Status: 200 OK
  • Body: {"name":"ERP Nutzfahrzeuge","version":"1.0.0","docs":"/docs"}

3.2 Auth Login (GET — should fail)

  • URL: GET http://localhost:8000/api/v1/auth/login
  • HTTP Status: 405 Method Not Allowed
  • Body: {"detail":"Method Not Allowed"}
  • Expected behavior: Login is POST-only; GET correctly rejected.

3.3 OpenAPI Schema

  • URL: GET http://localhost:8000/openapi.json
  • HTTP Status: 200 OK
  • Schema version: OpenAPI 3.1.0
  • Title: ERP Nutzfahrzeuge Backend API
  • Version: 1.0.0

4. Available API Endpoints (from OpenAPI)

Auth (/api/v1/auth)

Method Path Description Auth
POST /api/v1/auth/login Login with email+password → JWT tokens No
POST /api/v1/auth/refresh Exchange refresh token for new token pair No
GET /api/v1/auth/me Get current user profile Bearer

Users (/api/v1/users)

Method Path Description Auth
GET /api/v1/users/ List users (paginated, admin only) Bearer
POST /api/v1/users/ Create user (admin only) Bearer
PUT /api/v1/users/{user_id} Update user (admin only) Bearer
DELETE /api/v1/users/{user_id} Soft-delete user (admin only) Bearer

Vehicles (/api/v1/vehicles)

Method Path Description Auth
GET /api/v1/vehicles/ List vehicles (filter, sort, paginate) Bearer
POST /api/v1/vehicles/ Create vehicle Bearer
GET /api/v1/vehicles/{vehicle_id} Get single vehicle Bearer
PUT /api/v1/vehicles/{vehicle_id} Update vehicle Bearer
DELETE /api/v1/vehicles/{vehicle_id} Soft-delete vehicle Bearer
POST /api/v1/vehicles/{vehicle_id}/mobile-de/push Push to mobile.de (async, 202) Bearer
GET /api/v1/vehicles/{vehicle_id}/mobile-de/status Get mobile.de sync status Bearer

Contacts (/api/v1/contacts)

Method Path Description Auth
GET /api/v1/contacts/ List contacts (filter, sort, paginate) Bearer
POST /api/v1/contacts/ Create contact (admin/verkaeufer) Bearer
GET /api/v1/contacts/{contact_id} Get contact with persons Bearer
PUT /api/v1/contacts/{contact_id} Update contact Bearer
DELETE /api/v1/contacts/{contact_id} Soft-delete contact Bearer
POST /api/v1/contacts/{contact_id}/persons Add contact person Bearer
DELETE /api/v1/contacts/{contact_id}/persons/{person_id} Remove contact person Bearer

Files (/api/v1/vehicles/{vehicle_id}/files)

Method Path Description Auth
GET /api/v1/vehicles/{vehicle_id}/files List files for vehicle Bearer
POST /api/v1/vehicles/{vehicle_id}/files Upload file (multipart, max 20MB) Bearer
GET /api/v1/vehicles/{vehicle_id}/files/{file_id} Download file Bearer
DELETE /api/v1/vehicles/{vehicle_id}/files/{file_id} Delete file Bearer

OCR (/api/v1/ocr)

Method Path Description Auth
POST /api/v1/ocr/upload Upload scan for OCR (async, 202) Bearer
GET /api/v1/ocr/results/{result_id} Get OCR result Bearer
GET /api/v1/ocr/results List OCR results Bearer
POST /api/v1/ocr/results/{result_id}/apply Apply OCR data to vehicle Bearer

Sales (/api/v1/sales)

Method Path Description Auth
GET /api/v1/sales/ List sales (filter by status/date) Bearer
POST /api/v1/sales/ Create sale (sets vehicle to 'sold') Bearer
GET /api/v1/sales/{sale_id} Get sale with nested data Bearer
PUT /api/v1/sales/{sale_id} Update sale Bearer
DELETE /api/v1/sales/{sale_id} Cancel sale (soft delete) Bearer
POST /api/v1/sales/{sale_id}/contract Regenerate contract PDF Bearer
GET /api/v1/sales/{sale_id}/contract Download contract PDF Bearer
POST /api/v1/sales/{sale_id}/verify-ust-id Verify USt-IdNr. via BZSt API Bearer

DATEV (/api/v1/datev)

Method Path Description Auth
POST /api/v1/datev/export Create DATEV export (CSV) Bearer
GET /api/v1/datev/exports List DATEV exports Bearer
GET /api/v1/datev/exports/{export_id}/download Download DATEV CSV Bearer

Copilot (/api/v1/copilot)

Method Path Description Auth
POST /api/v1/copilot/chat Send message to AI Copilot Bearer
POST /api/v1/copilot/action Execute confirmed action Bearer
GET /api/v1/copilot/history Get chat history Bearer
POST /api/v1/copilot/voice Voice input (base64 audio) Bearer

Retouch (/api/v1/retouch)

Method Path Description Auth
POST /api/v1/retouch/process Upload image for retouching (async, 202) Bearer
GET /api/v1/retouch/results/{result_id} Get retouch result Bearer
POST /api/v1/retouch/price-compare Compare prices for vehicle Bearer

Health

Method Path Description Auth
GET /api/v1/health Health check No
GET / Root info No

5. Frontend Build Verification

Location: frontend/.next/

Build artifacts confirmed:

  • BUILD_ID — present (20 bytes)
  • build-manifest.json — present
  • app-build-manifest.json — present
  • routes-manifest.json — present
  • server/ — directory present
  • static/ — directory present
  • prerender-manifest.json — present
  • required-server-files.json — present
  • trace/ — build trace present

Verdict: Frontend build artifacts are complete and present.


6. Environment Verification

Required Environment Variables (from .env.example)

Variable Required Status Notes
DATABASE_URL Yes Set (local PostgreSQL) postgresql+asyncpg://erp_test_user:***@localhost:5432/erp_test
REDIS_URL Yes Set in .env.example Redis NOT installed; JWT refresh tokens are stateless (no Redis storage needed)
JWT_SECRET Yes Placeholder in .env.example Must be set to a secure random string for production
JWT_ALGORITHM Optional Default HS256
JWT_ACCESS_TTL_MINUTES Optional Default 15
JWT_REFRESH_TTL_DAYS Optional Default 7
CORS_ORIGINS Yes Set http://localhost:3000,http://localhost:3001
UPLOAD_DIR Optional Default /tmp/uploads Must be persistent volume in production
APP_NAME Optional Default ERP Nutzfahrzeuge
APP_ENV Optional Default development Set to production for deployment
MOBILE_DE_API_KEY Optional Empty Required for mobile.de integration
MOBILE_DE_SELLER_ID Optional Empty Required for mobile.de integration
OPENROUTER_API_KEY Optional Not in .env.example Required for AI Copilot features (currently empty/non-functional)

Infrastructure Status

Service Status Notes
PostgreSQL Running localhost:5432, accepting connections
Redis ⚠️ Not installed Not required for JWT; may be needed for async task queues (OCR, retouch, mobile.de push)
OpenRouter API ⚠️ Not configured AI Copilot features will not work without API key

7. Errors Found

No errors, tracebacks, warnings, or critical messages found in runtime logs.

Log output was clean:

INFO:     Started server process [3383733]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:48688 - "GET /api/v1/health HTTP/1.1" 200 OK
INFO:     127.0.0.1:48700 - "GET / HTTP/1.1" 200 OK
INFO:     127.0.0.1:48706 - "GET /api/v1/auth/login HTTP/1.1" 405 Method Not Allowed
INFO:     127.0.0.1:48710 - "GET /openapi.json HTTP/1.1" 200 OK

8. Known Risks

# Risk Severity Mitigation
1 Redis not installed — async task processing (OCR, retouch, mobile.de push) may fail or fall back to synchronous processing Medium Install Redis or verify async tasks have graceful fallback. Check if background tasks use in-memory queues.
2 OPENROUTER_API_KEY not set — AI Copilot (/api/v1/copilot/*) will not function Medium Set OPENROUTER_API_KEY in production environment for Copilot features.
3 JWT_SECRET is placeholderchange-me-to-a-secure-random-string in .env.example High Generate a cryptographically secure secret (≥256 bits) for production.
4 PostgreSQL is local only — no connection pooling or HA configured Medium Configure PgBouncer or use managed PostgreSQL (e.g., Coolify managed DB) for production.
5 UPLOAD_DIR = /tmp/uploads — ephemeral storage, files lost on container restart High Mount a persistent volume for UPLOAD_DIR in production.
6 CORS_ORIGINS — currently allows localhost:3000,3001 only Low Add production frontend origin to CORS_ORIGINS for deployment.
7 MOBILE_DE_API_KEY empty — mobile.de push/status endpoints will fail Low Set API key when mobile.de integration is needed.
8 No HTTPS/TLS — backend runs on plain HTTP Medium Use reverse proxy (nginx/Traefik) or Coolify proxy for TLS termination.
9 No rate limiting — no rate limiting middleware detected Medium Add rate limiting (e.g., slowapi) before public exposure.

9. Recommendations

Immediate (before deployment)

  1. Generate a secure JWT_SECRET and configure in production environment
  2. Set APP_ENV=production for deployment
  3. Configure persistent volume for UPLOAD_DIR
  4. Add production frontend origin to CORS_ORIGINS
  5. Install Redis if async task processing (OCR, retouch, mobile.de) is required
  6. Set OPENROUTER_API_KEY if AI Copilot features are needed

Deployment preparation

  1. Create Dockerfile / docker-compose.yml for containerized deployment
  2. Configure reverse proxy with TLS termination (Coolify proxy or nginx)
  3. Set up PostgreSQL as managed service or with backup strategy
  4. Add health check to Coolify resource configuration (GET /api/v1/health)
  5. Configure log rotation and monitoring

Post-deployment

  1. Run smoke tests against production endpoints
  2. Verify JWT auth flow end-to-end
  3. Test file upload with persistent volume
  4. Monitor for async task failures (OCR, retouch)

10. Sign-off

Item Status
App starts without errors Yes
Health endpoint returns 200 Yes
Bounded error output shows no critical runtime failure Yes (zero errors)
Frontend build artifacts present Yes
Deployment docs ready Yes (see deploy/ directory)
Ready for deployment ⚠️ Conditional — requires secure JWT_SECRET, persistent storage, and Redis decision

Runtime verification: PASSED Deployment readiness: CONDITIONAL (env vars + infrastructure must be configured)