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

66 lines
3.1 KiB
Markdown

# 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)](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) 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](https://openrouter.ai) 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.