Files
ai.allucanget.biz/docs/9-architectural-decisions.md
T
2026-04-27 18:19:40 +02:00

3.1 KiB

9. Architecture Decisions

Important, expensive, large scale or risky architecture decisions including rationales. With "decisions" we mean selecting one alternative based on given criteria.

Refer to section 4 (Solution Strategy) where the most important decisions are already captured. Avoid redundancy.

Consider using ADRs (Architecture Decision Records) for every important decision.

ADR-001: Use DuckDB as the embedded database

Status: accepted

Context: The application needs persistent storage for user data. A full RDBMS (PostgreSQL, MySQL) would require a separate server process and adds operational complexity.

Decision: Use DuckDB as an embedded, file-based database accessed in-process by the FastAPI backend.

Consequences: No separate DB server needed. Limited to single-writer access patterns. Suitable for the expected load.


ADR-002: Use FastAPI for the backend

Status: accepted

Context: The backend needs async performance for concurrent AI generation requests and automatic OpenAPI documentation.

Decision: Use FastAPI with uvicorn as the ASGI server.

Consequences: Async endpoints enable high concurrency. Auto-generated OpenAPI docs simplify frontend integration and testing.


ADR-003: Use Flask for the frontend

Status: accepted

Context: A lightweight server-side rendering layer is needed for the UI with minimal frontend complexity.

Decision: Use Flask with Jinja2 templates to serve HTML pages.

Consequences: Simple, familiar framework. No JavaScript build toolchain required. Frontend calls FastAPI over HTTP.


ADR-004: Serialize DuckDB writes with asyncio.Lock

Status: accepted

Context: FastAPI runs async coroutines concurrently in a single process. DuckDB's optimistic concurrency model raises errors when multiple coroutines issue writes simultaneously to the same connection.

Decision: All write operations (INSERT, UPDATE, DELETE) acquire a single process-wide asyncio.Lock before executing. The lock is released immediately after the statement completes.

Consequences: Writes are serialised within the process, eliminating concurrency errors. Read performance is unaffected. Throughput is acceptable for the expected user load. If write throughput becomes a bottleneck in future, migrating to PostgreSQL is the preferred path.


ADR-005: Use OpenRouter as the unified AI provider gateway

Status: accepted

Context: The application needs access to multiple AI model providers (OpenAI, Anthropic, Stability AI, Runway, etc.) for text, image, and video generation.

Decision: Route all AI generation requests through the OpenRouter API, which exposes an OpenAI-compatible REST interface for hundreds of models.

Consequences: Single API key and base URL for all model providers. Model switching requires only a change to the model field in the request payload. If OpenRouter is unavailable, all generation endpoints return 502 Bad Gateway. Pricing and rate limits are governed by OpenRouter's policies per model.