Files
roa2web-service-auto/docs/ARCHITECTURE-DECISIONS.md
Marius Mutu c5e051ad80 feat: Migrate to ultrathin monolith architecture
Consolidate 3 separate applications (reports-app, data-entry-app, telegram-bot) into a unified
architecture with single backend and frontend:

Backend Changes:
- Unified FastAPI backend at backend/ with modular structure
- Modules: reports, data_entry, telegram in backend/modules/
- Centralized config.py and main.py with all routers registered
- Single worker mode (--workers 1) for Telegram bot compatibility
- Shared Oracle connection pool and JWT authentication
- Unified requirements.txt and environment configuration

Frontend Changes:
- Single Vue.js SPA with module-based routing
- Unified frontend at src/ with modules in src/modules/{reports,data-entry}/
- Shared components and stores in src/shared/
- Error boundaries for module isolation
- Dual API proxy in Vite for module communication

Infrastructure:
- New unified startup scripts: start-prod.sh, start-test.sh, start-backend.sh
- Environment templates: .env.dev.example, .env.test.example, .env.prod.example
- Updated deployment scripts for Windows IIS
- Simplified SSH tunnel management

Documentation:
- Comprehensive CLAUDE.md with architecture overview
- Module-specific docs in docs/{data-entry,telegram}/
- Architecture decision records in docs/ARCHITECTURE-DECISIONS.md
- Deployment guides consolidated in deployment/windows/docs/

This migration reduces complexity, improves maintainability, and enables easier
deployment while maintaining all existing functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-29 23:48:14 +02:00

4.9 KiB

Architecture Decision Records (ADR)

This document records important architectural decisions made during ROA2WEB development.


ADR-001: Ultrathin Monolith Architecture (2025-12-24)

Status: Accepted

Context: Originally designed as separate microservices (Reports, Data Entry, Telegram Bot as independent services).

Decision: Consolidated into ultrathin monolith - single FastAPI application with modular structure.

Consequences:

  • Single Windows service to manage
  • Shared database connection pool
  • Simpler deployment
  • Lower memory usage
  • Easier debugging
  • ⚠️ Requires careful module isolation

Implementation:

  • All modules under backend/modules/
  • Single ROA2WEB-Backend service
  • Module enable/disable via .env flags

ADR-002: Single Worker Configuration (2025-12-29)

Status: Accepted

Context: Telegram bot integration causes conflicts when multiple uvicorn workers run simultaneously. Each worker spawns its own bot instance, but Telegram API allows only ONE bot to poll for updates.

Problem:

telegram.error.Conflict: terminated by other getUpdates request

Decision: Always use --workers 1 for the unified backend service.

Rationale:

  1. Telegram Bot Requirement: Single bot instance only
  2. SQLite Cache: Multiple workers cause locking conflicts
  3. Performance: Async I/O means single worker handles 100+ concurrent requests
  4. Resources: Lower memory (~400 MB vs ~1.6 GB with 4 workers)

Consequences:

  • Telegram bot works perfectly
  • No SQLite cache conflicts
  • Cache stats endpoint works (no 502 errors)
  • Lower memory usage
  • Same performance (I/O bound, not CPU bound)
  • ⚠️ Cannot scale horizontally with multiple processes

Implementation:

  • Configured in NSSM: --workers 1
  • NOT configurable in .env
  • Documented in TELEGRAM-BOT-DEPLOYMENT.md

Alternatives Considered:

  • Separate bot service: More complexity, no significant benefit
  • Redis pub/sub for bot: Over-engineering for current scale

Performance Characteristics:

  • Concurrent users: 100+
  • Requests per minute: 1000+
  • Response time: 50-200ms (DB query time)
  • Adequate for: 50-100 concurrent users

ADR-003: IIS Sub-Application Deployment (2025-12-29)

Status: Accepted

Context: Application deployed at /roa2web path on IIS, not at root.

Decision: Use Vite base: '/roa2web/' and axios baseURL: import.meta.env.BASE_URL + 'api' for all frontend API calls.

Consequences:

  • Works correctly on production sub-path
  • Works correctly on development root path
  • ⚠️ All axios instances must use BASE_URL
  • ⚠️ Router must use base path

Implementation:

  • vite.config.js: base: process.env.NODE_ENV === 'production' ? '/roa2web/' : '/'
  • All axios.create(): baseURL: import.meta.env.BASE_URL + 'api/...'
  • IIS web.config: Reverse proxy rules for /api/*localhost:8000

ADR-004: Pydantic v2 Migration (2025-12-29)

Status: In Progress

Context: Pydantic v2 changed schema_extrajson_schema_extra.

Decision: Update all models incrementally to use json_schema_extra.

Implementation:

  • backend/modules/reports/models/trial_balance.py updated
  • backend/modules/data_entry/schemas/ocr.py already correct
  • ⚠️ Warning eliminated in logs

ADR-005: Web.config as Static File (2025-12-29)

Status: Accepted

Context: IIS requires web.config for URL rewrite rules, but it wasn't consistently deployed.

Decision:

  1. Store canonical web.config in deployment/windows/config/
  2. Create Create-WebConfig.ps1 script for manual creation
  3. Include in deployment package

Consequences:

  • Consistent configuration across deployments
  • Easy to recreate if deleted
  • Version controlled

Implementation:

  • Canonical: deployment/windows/config/web.config
  • Deployed to: C:\inetpub\wwwroot\roa2web\frontend\web.config
  • Creation script: Create-WebConfig.ps1

Future Decisions to Document

Pending Considerations

  1. Horizontal Scaling:

    • If needed: Load balancer + multiple app instances
    • Alternative: Separate bot service to allow multiple workers
    • Current decision: Single worker sufficient
  2. Cache Strategy:

    • Current: SQLite L2 cache + memory L1
    • Alternative: Redis for distributed cache
    • Decision: Keep SQLite for simplicity
  3. Database Connection Pool:

    • Current: Shared pool across all modules
    • Sizing: 5-10 connections
    • Per-module pools: Not needed yet

Decision Process

When making architectural decisions:

  1. Document the context - Why is this decision needed?
  2. List alternatives - What other options exist?
  3. Explain rationale - Why this option over others?
  4. Note consequences - What are the trade-offs?
  5. Implementation details - How is this implemented?
  6. Reference documentation - Where to find more details?

Last Updated: 2025-12-29