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

565 lines
24 KiB
Markdown

# 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:
```bash
# 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:
```bash
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)
---
## 📚 Related Documentation
- **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.**