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>
177 lines
4.9 KiB
Markdown
177 lines
4.9 KiB
Markdown
# 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_extra` → `json_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
|