Files
roa2web-service-auto/docs/MONOLITH_ARCHITECTURE.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

24 KiB

ROA2WEB Ultrathin Monolith Architecture

Version: 1.0.0 Last Updated: 2025-12-29 Status: Active


🎯 Overview

ROA2WEB uses an ultrathin monolith architecture - a single unified backend and frontend application with modular organization. This architecture provides the simplicity of a monolith with the organizational benefits of microservices.

Key Characteristics

  • Single Backend Process: One FastAPI application serving all modules
  • Single Frontend Build: One Vue.js SPA with lazy-loaded modules
  • Modular Organization: Business logic separated into distinct modules
  • Shared Resources: Database pools, auth, cache shared across modules
  • Independent Modules: Each module can be developed and tested independently

🏗️ Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────────┐
│                              🌐 CLIENT BROWSER                              │
└────────────────────────────────┬────────────────────────────────────────────┘
                                 │ HTTP/HTTPS Requests
                                 ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          📦 UNIFIED VUE.JS FRONTEND                         │
│  Single-page application (SPA) served from /dist                           │
│  Port: 3000 (dev) / 80,443 (production)                                    │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ Frontend Modules (Lazy Loaded)                                      │   │
│  │                                                                      │   │
│  │  • src/modules/reports/        - Reports module UI                  │   │
│  │  • src/modules/data-entry/     - Data entry module UI               │   │
│  │                                                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ Shared Frontend Components                                          │   │
│  │                                                                      │   │
│  │  • src/shared/components/      - Reusable Vue components            │   │
│  │  • src/shared/stores/          - Pinia stores                       │   │
│  │  • src/assets/css/             - Global CSS system                  │   │
│  │  • shared/frontend/            - Login, auth components             │   │
│  │                                                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
└────────────────────────────────┬────────────────────────────────────────────┘
                                 │ API Calls (Axios)
                                 │ Authorization: Bearer <JWT>
                                 ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                        🚀 UNIFIED FASTAPI BACKEND                           │
│  Single Python process running all modules                                  │
│  Port: 8000 (dev) / 8001 (production)                                      │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ 🛡️  Global Middleware Layer                                          │   │
│  │                                                                      │   │
│  │  • CORSMiddleware           - CORS handling                         │   │
│  │  • AuthenticationMiddleware - JWT validation & user injection       │   │
│  │  • Rate Limiting            - 5 req/5 min per IP                    │   │
│  │  • Security Headers         - XSS, CSP, Frame protection            │   │
│  │                                                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ 📊 Backend Modules (backend/modules/)                               │   │
│  │                                                                      │   │
│  │  reports/                                                            │   │
│  │    ├── routers/            - API endpoints                          │   │
│  │    ├── services/           - Business logic with caching            │   │
│  │    ├── models/             - Pydantic models                        │   │
│  │    └── cache/              - L1+L2 cache implementation             │   │
│  │                                                                      │   │
│  │  data_entry/                                                         │   │
│  │    ├── routers/            - API endpoints                          │   │
│  │    ├── services/           - Business logic                         │   │
│  │    ├── models/             - SQLModel ORM models                    │   │
│  │    └── db/                 - SQLite database                        │   │
│  │                                                                      │   │
│  │  telegram/                                                           │   │
│  │    ├── bot/                - Telegram bot handlers                  │   │
│  │    ├── api/                - Internal API for bot                   │   │
│  │    └── db/                 - Bot session management                 │   │
│  │                                                                      │   │
│  │  data/                                                               │   │
│  │    └── telegram_bot.db     - Telegram bot SQLite database           │   │
│  │                                                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ 🔧 Shared Backend Components (shared/)                              │   │
│  │                                                                      │   │
│  │  database/                                                           │   │
│  │    └── oracle_pool.py      - Singleton Oracle connection pool       │   │
│  │                                                                      │   │
│  │  auth/                                                               │   │
│  │    ├── middleware.py       - JWT authentication middleware          │   │
│  │    ├── jwt_handler.py      - Token creation/validation              │   │
│  │    └── models.py           - Auth data models                       │   │
│  │                                                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
└────────────────────────────────┬────────────────────────────────────────────┘
                                 │ Database Queries
                                 │ (Oracle + SQLite)
                                 ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                            🗄️  DATABASE LAYER                               │
│                                                                              │
│  ┌─────────────────────────┐          ┌─────────────────────────┐          │
│  │  Oracle Database        │          │  SQLite Databases       │          │
│  │  (via SSH Tunnel)       │          │  (Local Files)          │          │
│  │                         │          │                         │          │
│  │  • CONTAFIN_ORACLE     │          │  • data_entry.db        │          │
│  │  • Financial schemas   │          │  • telegram_bot.db      │          │
│  │  • User management     │          │  • cache.db             │          │
│  │                         │          │                         │          │
│  │  Port: 1521 (remote)   │          │  Path: backend/modules/ │          │
│  │        1526 (tunnel)    │          │        /data/           │          │
│  │                         │          │                         │          │
│  └─────────────────────────┘          └─────────────────────────┘          │
└─────────────────────────────────────────────────────────────────────────────┘

📁 Directory Structure

Backend Structure

backend/
├── main.py                    # FastAPI app entry point
├── config.py                  # Centralized configuration
├── .env                       # Environment variables
├── .env.dev                   # Development environment
├── .env.test                  # Test environment
├── .env.prod                  # Production environment
│
└── modules/                   # Business logic modules
    ├── __init__.py
    │
    ├── reports/               # Reports module (Oracle read-only)
    │   ├── __init__.py
    │   ├── routers/           # API endpoints
    │   │   ├── dashboard.py
    │   │   ├── invoices.py
    │   │   └── treasury.py
    │   ├── services/          # Business logic
    │   │   ├── dashboard_service.py
    │   │   └── invoice_service.py
    │   ├── models/            # Pydantic models
    │   ├── schemas/           # Response schemas
    │   └── cache/             # Cache implementation
    │       ├── decorators.py  # @cached decorator
    │       └── manager.py     # L1+L2 cache manager
    │
    ├── data_entry/            # Data entry module (SQLite + workflow)
    │   ├── __init__.py
    │   ├── routers/           # API endpoints
    │   │   ├── receipts.py
    │   │   └── entries.py
    │   ├── services/          # Business logic
    │   ├── models/            # SQLModel ORM models
    │   │   ├── receipt.py
    │   │   ├── attachment.py
    │   │   └── accounting_entry.py
    │   ├── db/                # Database
    │   │   ├── session.py     # SQLite session
    │   │   └── migrations/    # Alembic migrations
    │   └── utils/             # Helper functions
    │
    ├── telegram/              # Telegram bot module
    │   ├── __init__.py
    │   ├── bot/               # Bot implementation
    │   │   ├── handlers.py    # Command handlers
    │   │   ├── helpers.py     # Helper functions
    │   │   └── formatters.py  # Message formatters
    │   ├── api/               # Internal API
    │   │   └── auth.py        # Auth code management
    │   ├── db/                # Bot database
    │   │   └── session.py     # Session management
    │   └── bot_main.py        # Bot entry point
    │
    └── data/                  # Shared data
        └── telegram_bot.db    # Telegram bot database

Frontend Structure

src/
├── main.js                    # App entry point
├── App.vue                    # Root component
│
├── modules/                   # Feature modules
│   ├── reports/               # Reports module
│   │   ├── views/             # Page components
│   │   │   ├── DashboardView.vue
│   │   │   ├── InvoicesView.vue
│   │   │   └── TreasuryView.vue
│   │   ├── components/        # Module-specific components
│   │   ├── stores/            # Module-specific Pinia stores
│   │   │   ├── dashboard.js
│   │   │   └── invoices.js
│   │   ├── services/          # API client
│   │   │   └── api.js
│   │   └── utils/             # Helpers
│   │
│   └── data-entry/            # Data entry module
│       ├── views/             # Page components
│       │   ├── ReceiptsView.vue
│       │   └── EntriesView.vue
│       ├── components/        # Module-specific components
│       ├── stores/            # Module-specific Pinia stores
│       │   └── receipts.js
│       └── services/          # API client
│           └── api.js
│
├── shared/                    # Shared components
│   ├── components/            # Reusable Vue components
│   │   ├── ErrorBoundary.vue
│   │   ├── CompanySelector.vue
│   │   └── PeriodSelector.vue
│   └── stores/                # Shared Pinia stores
│       ├── auth.js
│       ├── companies.js
│       └── accountingPeriod.js
│
├── router/                    # Vue Router
│   ├── index.js               # Main router
│   ├── reports.js             # Reports routes
│   └── data-entry.js          # Data entry routes
│
├── assets/                    # Global assets
│   ├── css/                   # Global CSS system
│   │   ├── core/              # Design tokens
│   │   ├── components/        # Component styles
│   │   ├── patterns/          # UI patterns
│   │   ├── layout/            # Layout styles
│   │   ├── utilities/         # Utility classes
│   │   └── vendor/            # PrimeVue overrides
│   └── images/                # Images
│
└── views/                     # Global views
    └── LoginView.vue          # Login page

🔄 Request Flow

1. User Authentication Flow

User Login Request
    ↓
Frontend (LoginView.vue)
    ↓ POST /api/auth/login
Backend (main.py)
    ↓
AuthenticationMiddleware (excluded for /login)
    ↓
Auth Router (/api/auth/login)
    ↓
Oracle Database (pack_drepturi.verificautilizator)
    ↓
JWT Token Generation
    ↓
Response with access_token + refresh_token
    ↓
Frontend stores token in localStorage
    ↓
Subsequent requests include: Authorization: Bearer <token>

2. Reports Data Flow (with Cache)

User Request (Dashboard data)
    ↓
Frontend (DashboardView.vue)
    ↓ GET /api/reports/dashboard
Backend Middleware
    ├─ CORS check ✓
    ├─ JWT validation ✓
    └─ User injection into request.state
    ↓
Reports Router (/api/reports/dashboard)
    ↓
DashboardService.get_dashboard_data()
    ↓
@cached decorator checks cache
    ├─ L1 Cache (Memory) HIT? → Return cached data
    ├─ L2 Cache (SQLite) HIT? → Store in L1, return data
    └─ MISS → Query Oracle
        ↓
    Oracle Database (via connection pool)
        ↓
    Process and cache result (L1 + L2)
        ↓
    Return data
    ↓
Response with cache metadata headers
    ↓
Frontend updates Pinia store
    ↓
Vue component reactively updates UI

3. Data Entry Flow (with Workflow)

User Creates Receipt
    ↓
Frontend (ReceiptsView.vue)
    ↓ POST /api/data-entry/receipts
Backend Middleware (JWT validation)
    ↓
Data Entry Router
    ↓
ReceiptService.create_receipt()
    ↓
SQLModel ORM
    ↓
SQLite Database (data_entry.db)
    ├─ Insert Receipt (status: DRAFT)
    ├─ Insert Attachments
    └─ Generate AccountingEntries
    ↓
Response with receipt ID
    ↓
Frontend updates Pinia store
    ↓
UI shows new receipt in DRAFT state
    ↓
User submits for approval
    ↓ POST /api/data-entry/receipts/{id}/submit
Backend updates status: DRAFT → PENDING
    ↓
Workflow continues (PENDING → APPROVED/REJECTED)

🚀 Module Independence

Benefits of Modular Monolith

  1. Development:

    • Each module can be developed independently
    • Clear boundaries between features
    • Easy to understand and navigate
  2. Testing:

    • Modules can be tested in isolation
    • Shared components tested once
    • Integration tests verify module interactions
  3. Deployment:

    • Single deployment process
    • No service coordination complexity
    • Atomic updates (all or nothing)
  4. Performance:

    • No network latency between modules
    • Shared connection pools
    • Efficient resource utilization

Module Communication

Within Backend:

  • Modules can directly import from each other
  • Use shared utilities from shared/
  • Share database connections and auth

Within Frontend:

  • Modules use shared Pinia stores
  • Shared components in src/shared/
  • Routing handles module navigation

🔧 Configuration Management

Environment-Based Configuration

The backend supports multiple environment configurations:

# Development
backend/.env.dev          # Local development settings
PORT=8000
DEBUG=True
ORACLE_HOST=localhost
ORACLE_PORT=1526

# Testing
backend/.env.test         # Testing environment
PORT=8001
DEBUG=False
ORACLE_HOST=10.0.20.121

# Production
backend/.env.prod         # Production settings
PORT=8001
DEBUG=False
ORACLE_HOST=10.0.20.36

Module Toggle Configuration

Modules can be enabled/disabled via environment variables:

MODULE_REPORTS_ENABLED=true
MODULE_DATA_ENTRY_ENABLED=true
MODULE_TELEGRAM_ENABLED=true

📊 Shared Resources

1. Database Connection Pool

Oracle Pool (shared/database/oracle_pool.py):

  • Singleton pattern
  • Configured pool size (min=2, max=10)
  • Automatic reconnection
  • Connection health checks
  • Used by Reports module

2. Authentication & Authorization

JWT Authentication (shared/auth/):

  • Centralized token management
  • Middleware auto-injection of user
  • Rate limiting (5 req/5 min)
  • Used by all modules

3. Cache System (Reports Module)

Two-Tier Cache:

  • L1: In-memory (LRU, 1000 entries)
  • L2: SQLite persistent cache
  • Automatic TTL management
  • Performance tracking

4. Frontend Shared Components

Shared UI (src/shared/ and shared/frontend/):

  • Authentication components
  • Company/Period selectors
  • Error boundaries
  • Global CSS system

🎯 Migration from Microservices

What Changed

Before (Microservices):

reports-app/backend/      → Port 8001
data-entry-app/backend/   → Port 8003
telegram-bot/             → Port 8002

After (Monolith):

backend/                  → Single port 8000/8001
  └── modules/
      ├── reports/
      ├── data_entry/
      └── telegram/

Migration Benefits

  1. Simpler deployment (1 service instead of 3)
  2. Faster startup (no multi-service coordination)
  3. Easier debugging (single process)
  4. Shared connection pools (better resource utilization)
  5. No inter-service network latency
  6. Atomic deployments (all modules update together)

What Stayed the Same

  • Module boundaries and organization
  • Business logic and models
  • Frontend structure
  • Database schemas
  • API contracts
  • Authentication flow

🔒 Security Considerations

Middleware Stack

All requests pass through:

  1. CORS validation
  2. JWT authentication
  3. Rate limiting
  4. Security headers injection

Module Isolation

While modules share the same process:

  • Each has its own routers
  • Business logic is separated
  • Database access is controlled
  • Permissions are enforced at API level

📈 Scalability

Horizontal Scaling

The monolith can be scaled horizontally:

  • Multiple instances behind load balancer
  • Stateless design (JWT, no sessions)
  • Shared database (Oracle)
  • Redis for distributed cache (future)

Vertical Scaling

Optimize single instance:

  • Increase worker processes
  • Connection pool tuning
  • Cache optimization
  • Query optimization

Future: Microservices Migration

If needed, modules can be extracted:

  • Each module already has clear boundaries
  • Services are independent
  • API contracts are defined
  • Database can be split (if needed)

  • Setup & Commands: README.md
  • CSS Architecture: docs/ONBOARDING_CSS.md
  • Data Entry Module: docs/data-entry/ARCHITECTURE.md
  • Telegram Bot: docs/telegram/README.md
  • Deployment: deployment/windows/README.md (Windows) or DOKPLOY_DEPLOYMENT.md (Linux)

For questions about this architecture, consult the development team or open an issue in the repository.