7f7da15965
Completed: - Phase 0: Project Setup (T001-T003) - Docker Compose, FastAPI skeleton, React SPA - Phase 1: Auth System (T004-T008) - DB models, JWT auth, RBAC middleware, user management - Phase 2: Contacts & Tags (T009-T011) - CRUD API + UI - Phase 3: Equipment Catalog (T012-T014) - Models, API, UI with barcode/QR - Phase 4: Crew Management (T015-T017) - Models, availability, UI - Phase 5: Vehicle Fleet (T018-T020) - Models, assignments, UI - Phase 6: Projects (T021-T023) - Project hierarchy models, CRUD API, list/detail UI
161 lines
8.1 KiB
Markdown
161 lines
8.1 KiB
Markdown
# Architecture Decision Records (ADR) – Rentman.io Clone
|
||
|
||
> **Version:** 1.0
|
||
> **Date:** 2026-05-31
|
||
> **Project:** Rentman.io-Nachbau
|
||
> **Architect:** Solution Architect (A0 Software Orchestrator)
|
||
|
||
---
|
||
|
||
## ADR-001: Backend-Framework
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** FastAPI (Python)
|
||
|
||
**Alternatives considered:**
|
||
- **NestJS (Node.js/TypeScript):** Same language for frontend/backend, but Python has stronger ecosystem for data processing, PDF generation, and ORM maturity (SQLAlchemy > TypeORM in stability). Higher learning curve for team.
|
||
- **Laravel (PHP):** Mature, batteries-included, but monolithic by nature; API-centric design is less natural.
|
||
- **Flask:** Too minimal; FastAPI provides async support, auto-generated OpenAPI docs, Pydantic validation for free.
|
||
|
||
**Rationale:** FastAPI combines high performance (async) with automatic documentation and validation that reduces manual work. Python's ecosystem for reports/exports (openpyxl, WeasyPrint) outweighs the language mismatch with frontend.
|
||
|
||
---
|
||
|
||
## ADR-002: Frontend-Strategie
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** React SPA with Vite + TypeScript, PWA via Service Workers + Capacitor
|
||
|
||
**Alternatives considered:**
|
||
- **Next.js (SSR):** Adds complexity for an internal business app where SEO is irrelevant and CSR is sufficient. SSR would require Node.js runtime in production.
|
||
- **Vue/Nuxt:** Simpler than React, but smaller ecosystem for complex interactive UI components (Gantt charts, drag-and-drop scheduling).
|
||
- **SvelteKit:** Promising but still too new; fewer UI component libraries.
|
||
|
||
**Rationale:** React has the largest ecosystem for business UIs (React Query, Zustand, Radix, TanStack Table). SPA (CSR) is sufficient because the app is used behind authentication. PWA support provides mobile app without separate native codebase. Capacitor grants access to barcode scanning via native plugin.
|
||
|
||
---
|
||
|
||
## ADR-003: Multi-Tenant-Strategie
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Shared Database with `account_id` (tenant_id) column on every table
|
||
|
||
**Alternatives considered:**
|
||
- **Database-per-tenant:** Strongest isolation, but high operational overhead (managing hundreds of databases), harder cross-tenant analytics, expensive cloud costs.
|
||
- **Schema-per-tenant:** Middle ground, but ORM support is complex (dynamic schema switching), and PostgreSQL schema limits are lower than tables.
|
||
|
||
**Rationale:** Shared DB with tenant_id is simplest to implement and operate for an MVP. Row-level isolation is enforced at query level (SQLAlchemy session filter). For future scaling, read replicas or partition by tenant can be added.
|
||
|
||
---
|
||
|
||
## ADR-004: Datenbank-Wahl (Dev vs Production)
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** SQLite for local development, PostgreSQL for testing and production
|
||
|
||
**Alternatives considered:**
|
||
- **SQLite only:** Simple, but lacks concurrent write performance for 50+ users, no JSONB indexing, limited migration capabilities (ALTER COLUMN).
|
||
- **PostgreSQL only:** Requires every developer to run PostgreSQL locally or via Docker. Adds friction for quick tests.
|
||
|
||
**Rationale:** SQLite allows "clone and run" developer experience. PostgreSQL is required for realistic testing and production scale. SQLAlchemy + Alembic handle dialect differences. All CI tests run on PostgreSQL to catch incompatibilities early.
|
||
|
||
---
|
||
|
||
## ADR-005: Projekt-Hierarchie-Modellierung
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Project → Subproject → FunctionGroup → Function (→ Crew/Equipment)
|
||
|
||
**Alternatives considered:**
|
||
- **Flat project with tags:** Simpler, but fails to represent hierarchical structure of real events (e.g., a festival with multiple stages, each with sound/light/video functions).
|
||
- **Nested Set (MPTT):** Complex for tree operations, harder to query for availability (time-based conflicts across subtrees).
|
||
|
||
**Rationale:** Rentman's original model is hierarchical because real AV projects are hierarchical. The 4-level depth with optional Subprojects and FunctionGroups gives maximum flexibility without over-complexity. Each level can have its own time periods, enabling partial rental (e.g., sound equipment only for 2 days within a 7-day project).
|
||
|
||
---
|
||
|
||
## ADR-006: Preisberechnung-Strategie
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Calculated fields stored on Project (updated at query time or via trigger)
|
||
|
||
**Alternatives considered:**
|
||
- **Real-time calculation on every read:** Accurate but slow for list views showing 50+ projects.
|
||
- **Materialized view:** Efficient but complex to maintain (must refresh after any change to sub-items).
|
||
|
||
**Rationale:** Store calculated `price` and `cost` on the `Project` row, updated whenever sub-items (equipment, crew functions) are modified. Application-layer recalculation after each CUD operation on related entities. Cache in Redis for dashboard aggregations.
|
||
|
||
---
|
||
|
||
## ADR-007: PDF/Template-Engine
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** HTML-based templates with WeasyPrint rendering
|
||
|
||
**Alternatives considered:**
|
||
- **ReportLab:** Python-native, more control over layout, but template creation is code-only, requiring developer for each template.
|
||
- **LaTeX:** Professional quality, but heavy dependency; not UX-friendly for admin users to edit templates.
|
||
- **WYSIWYG (e.g., GrapesJS):** Full drag-and-drop, but generates messy HTML, hard to placeholders, and adds significant frontend complexity.
|
||
|
||
**Rationale:** HTML templates with placeholder syntax (`{{project_name}}`, `{{items_table}}`) offer the best balance: designers can create templates with CSS, non-technical admins can modify content, and WeasyPrint converts to high-quality PDF. This mirrors Rentman's approach (HTML-like template with placeholders).
|
||
|
||
---
|
||
|
||
## ADR-008: Offline-Sync-Strategie
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Last-Write-Wins (LWW) with conflict warnings
|
||
|
||
**Alternatives considered:**
|
||
- **CRDT (Conflict-free Replicated Data Types):** No conflicts, but requires specialized data structures and complex merge logic.
|
||
- **OT (Operational Transformation):** Similar to Google Docs, overkill for checkmarks and status updates.
|
||
|
||
**Rationale:** Offline capabilities are needed for equipment packing (checkboxes, status changes) where conflicts are rare (usually one person per project scans items). LWW is simple, implementable with IndexedDB timestamps, and sufficient. When a conflict is detected (same item modified offline by two users), show a warning and let the user decide.
|
||
|
||
---
|
||
|
||
## ADR-009: API-Versionierung und -Dokumentation
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** URL-based versioning (`/api/v1/...`) with OpenAPI auto-generation
|
||
|
||
**Alternatives considered:**
|
||
- **Header-based versioning (`Accept: application/vnd.rentman.v1+json`):** Cleaner, but harder to test and document.
|
||
- **No versioning:** Faster now, but breaking changes inevitable.
|
||
|
||
**Rationale:** URL versioning is simplest for client developers (visible, testable via browser/curl). FastAPI's automatic OpenAPI generation ensures docs are always in sync with code.
|
||
|
||
---
|
||
|
||
## ADR-010: Deployment-Plattform
|
||
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Docker Compose as deployable unit, Coolify for production management
|
||
|
||
**Alternatives considered:**
|
||
- **Kubernetes (K8s):** Overkill for a single-server deployment; adds complexity without immediate benefit.
|
||
- **Manual VPS setup:** Error-prone, hard to reproduce, no rollback.
|
||
- **PaaS (Heroku, Render):** Expensive at scale, less control over infrastructure.
|
||
|
||
**Rationale:** Docker Compose works identically on dev machines and production. Coolify provides a web-based management layer similar to CapRover/Porter without the Kubernetes complexity. Easy SSL, environment management, database backups, and app restarts.
|
||
|
||
---
|
||
|
||
## Open Decisions (Not Yet Resolved)
|
||
|
||
1. **Authentication Provider (V2):** Should OAuth2/OIDC (Google, Azure AD) be added in MVP or V2? Current decision: Basic JWT only for MVP; OIDC in V2.
|
||
2. **Barcode type:** QR-Code (primary) + Code128 (optional). Label size: 50×25mm standard. Label printer integration not in scope.
|
||
3. **Email provider:** SMTP (default) with optional SendGrid/Mailgun API. Transactional emails only.
|
||
4. **Datev or full accounting export:** Not in scope for MVP.
|
||
5. **Pricing model:** Open Source (MIT) core with optional SaaS hosting. Decision to be made by product owner.
|