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

422 lines
18 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 🚀 Project Overview
**ROA2WEB** - Modern ERP Application with ultrathin monolith architecture:
1. **Reports Module** (`backend/modules/reports/`) - Read-only reports from Oracle (raportări)
2. **Data Entry Module** (`backend/modules/data_entry/`) - Data input with approval workflow (introduceri date)
3. **Telegram Bot Module** (`backend/modules/telegram/`) - Telegram bot integration
**Main Branch**: `main` (use for PRs)
**Working Directory**: Repository root
**Quick Reference**: See `README.md` for complete setup, commands, deployment, and testing instructions.
---
## 📁 Module-Specific Instructions
> **IMPORTANT**: When working on a specific module, read its documentation first!
| Module | Documentation Location | Description |
|--------|----------------------|-------------|
| **Data Entry** | `docs/data-entry/DATA-ENTRY-MODULE.md` | Bonuri fiscale, chitanțe, workflow aprobare |
| **Reports** | This file (below) | Rapoarte Oracle read-only |
| **Telegram Bot** | `docs/telegram/README.md` | Bot Telegram |
### When to Use Which Instructions
**Working on Data Entry** (`backend/modules/data_entry/` or `src/modules/data-entry/`):
**FIRST read `docs/data-entry/DATA-ENTRY-MODULE.md`** for:
- SQLModel + Alembic patterns (NOT Oracle)
- SQLite database (NOT Oracle pool)
- Workflow states (DRAFT → PENDING → APPROVED)
- Receipt/Attachment/AccountingEntry models
- Expense types and auto-generation logic
- Oracle nomenclatures integration
**Working on Reports Module** (`backend/modules/reports/` or `src/modules/reports/`):
→ Use instructions from this file (below)
**Working on shared components** (`shared/auth/`, `shared/database/`, `shared/frontend/`):
→ These are used by ALL modules - be careful with changes!
`shared/frontend/` contains: LoginView.vue, auth store factory, login styles
---
## 🏗️ Architecture
> **Important Architecture Decisions:** See `docs/ARCHITECTURE-DECISIONS.md` for critical decisions about:
> - Why single worker (`--workers 1`) is required for Telegram bot
> - Ultrathin monolith vs microservices rationale
> - IIS sub-application deployment strategy
> - Performance characteristics and scaling considerations
### Ultrathin Monolith Structure
```
.
├── backend/ # Unified FastAPI backend (port 8000/8001)
│ ├── modules/ # Business logic modules
│ │ ├── reports/ # Reports module (Oracle read-only)
│ │ ├── data_entry/ # Data entry module (SQLite + workflow)
│ │ ├── telegram/ # Telegram bot module
│ │ └── data/ # Shared data (telegram_bot.db)
│ ├── config.py # Centralized configuration
│ └── main.py # FastAPI app entry point
├── src/ # Unified Vue.js 3 frontend
│ ├── modules/ # Feature modules
│ │ ├── reports/ # Reports frontend
│ │ └── data-entry/ # Data entry frontend
│ ├── shared/ # Shared frontend components
│ │ ├── components/ # Reusable Vue components
│ │ └── stores/ # Pinia stores
│ ├── assets/ # Global CSS, images
│ ├── router/ # Vue Router
│ └── App.vue # Root component
├── shared/ # Shared backend components
│ ├── database/ # Oracle pool
│ ├── auth/ # JWT auth & middleware
│ └── frontend/ # Shared frontend assets
│ ├── components/ # LoginView.vue
│ ├── stores/ # Auth store factory
│ └── styles/ # Login CSS
├── docs/ # Architecture & style guides
├── deployment/ # Production deployment scripts
└── ssh-tunnel/ # SSH tunnel for Oracle DB access
```
### Starting Services
**Quick Start** (Unified backend + frontend):
```bash
./start-prod.sh # Prod env: Backend :8001, Frontend :3000
./start-test.sh # Test env: Backend :8001, Frontend :3000
```
**Individual Service Control**:
```bash
./start-frontend.sh restart # Restart frontend only (~7s - fastest!)
./start-backend.sh # Start unified backend :8000 or :8001
./status.sh # Show services status + health checks
```
**Infrastructure**:
```bash
./ssh-tunnel-prod.sh start # Oracle DB tunnel (production: 10.0.20.36)
./ssh-tunnel-test.sh start # Oracle TEST tunnel (LXC: 10.0.20.121)
```
**Benefits**:
- **Single backend process**: All modules in one FastAPI app
- **Faster startup**: No multi-service coordination overhead
- **Easier debugging**: Single process to monitor
- **Shared resources**: Connection pools, cache, and middleware
### Key Architectural Decisions
**Core Architecture:**
- **Ultrathin Monolith**: Single backend process with modular structure (`backend/modules/`)
- **Single Worker Mode**: `--workers 1` (required for Telegram bot - see ADR-002 in `docs/ARCHITECTURE-DECISIONS.md`)
- **Shared Database Pool**: Singleton `OraclePool` in `shared/database/oracle_pool.py` (python-oracledb with connection pooling)
- **Centralized Auth**: JWT-based auth in `shared/auth/` with middleware auto-injecting `request.state.user`
**Module-Specific:**
- **Module-Based Cache**: Each module can have its own cache strategy (Reports uses L1+L2 hybrid cache)
- **Telegram Bot**: Integrated module with SQLite database (`backend/modules/data/telegram_bot.db`)
- **FastAPI Structure**: Modules in `backend/modules/*/`, each with services, routers, models/schemas
**Infrastructure:**
- **SSH Tunnel**: Required for Oracle DB connections (development/Linux) - see Database Setup
- **IIS Sub-Application**: Deployed at `/roa2web` path, not root (production)
> **For detailed rationale and trade-offs**, see `docs/ARCHITECTURE-DECISIONS.md`
---
## 🗄️ Database Setup
**Schema**: `CONTAFIN_ORACLE` (authentication and user management)
**Connection**: SSH tunnel required (Oracle on remote network)
### SSH Tunnel (Development/Linux)
```bash
./ssh-tunnel-prod.sh start # localhost:1526 → remote:1521
./ssh-tunnel-prod.sh status # Check tunnel
./ssh-tunnel-prod.sh stop # Stop tunnel
```
**IMPORTANT**: Always ensure SSH tunnel is running before starting backend services.
### Environment Variables (`backend/.env`)
```bash
# Oracle Database (through SSH tunnel)
ORACLE_USER=CONTAFIN_ORACLE
ORACLE_PASSWORD=your_password
ORACLE_HOST=localhost
ORACLE_PORT=1526
ORACLE_SID=ROA
# JWT Authentication
JWT_SECRET_KEY=your_secret_key
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=30
# Module Configuration
MODULE_REPORTS_ENABLED=true
MODULE_DATA_ENTRY_ENABLED=true
MODULE_TELEGRAM_ENABLED=true
```
**Windows Production**: Direct Oracle connection, no SSH tunnel required.
**Environment Files**: Multiple .env files available (.env.dev, .env.test, .env.prod) - see `backend/ENV-SETUP.md` for details.
---
## 🔑 Authentication Flow
1. **Login**: `POST /api/auth/login` → calls `pack_drepturi.verificautilizator(username, password)`
2. **Token**: JWT includes `username`, `user_id`, `companies[]`, `permissions[]`, `exp`, `iat`, `type`
3. **Middleware**: `AuthenticationMiddleware` in `shared/auth/middleware.py` validates tokens, injects user
4. **Protected Routes**: All routes except `excluded_paths` require valid JWT
**Key Files**:
- `shared/auth/middleware.py` - FastAPI middleware with rate limiting (5 req/5 min)
- `shared/auth/jwt_handler.py` - Token creation/validation
- `backend/main.py` - Main FastAPI app with auth router registration
---
## 📝 Common Development Tasks
### Adding a New API Endpoint
**IMPORTANT**: Always use the cache system for database queries to improve performance.
1. Create **service** in `backend/modules/reports/services/your_service.py` (NOT in router!)
2. Define Pydantic schemas in `modules/*/schemas/` or `modules/*/models/`
3. **Add caching** using `@cached` decorator in service methods
4. Create router in `backend/modules/reports/routers/your_router.py` (calls service)
5. Register router in `app/main.py`: `app.include_router(your_router, prefix="/api/your_prefix")`
**Service Example with Caching** (RECOMMENDED):
```python
# app/services/your_service.py
from app.cache.decorators import cached
from database.oracle_pool import oracle_pool
class YourService:
@staticmethod
@cached(cache_type='schema', key_params=['company_id'])
async def _get_schema(company_id: int) -> str:
"""Get schema for company (CACHED 24h)"""
async with oracle_pool.get_connection() as connection:
with connection.cursor() as cursor:
cursor.execute("""
SELECT schema FROM CONTAFIN_ORACLE.v_nom_firme
WHERE id_firma = :company_id
""", {'company_id': company_id})
result = cursor.fetchone()
return result[0] if result else None
@staticmethod
@cached(cache_type='your_data', key_params=['filter_params', 'username'])
async def get_your_data(filter_params: YourFilter, username: str) -> YourResponse:
"""
Get your data from Oracle (CACHED 10 min)
Cache automatically:
- Generates unique key from filter_params + username
- Stores in L1 (memory) + L2 (SQLite)
- Returns cached data on subsequent calls
- Tracks performance metrics
"""
schema = await YourService._get_schema(filter_params.company_id)
async with oracle_pool.get_connection() as connection:
with connection.cursor() as cursor:
cursor.execute(f"""
SELECT * FROM {schema}.your_table
WHERE your_condition = :param
""", {'param': filter_params.param})
rows = cursor.fetchall()
# Process results...
return YourResponse(data=processed_data)
```
**Router Example** (calls service):
```python
# app/routers/your_router.py
from app.services.your_service import YourService
@router.get("/", response_model=YourResponse)
async def get_your_data(
filter_params: YourFilter = Depends(),
current_user: CurrentUser = Depends(get_current_user)
):
"""Get your data - delegated to service with caching"""
return await YourService.get_your_data(filter_params, current_user.username)
```
**Cache Configuration** (add to `app/cache/config.py` if new cache type):
```python
# Add TTL for your cache type
ttl_your_data: int = int(os.getenv('CACHE_TTL_YOUR_DATA', '600')) # 10 min default
# Add to get_ttl_for_type() method:
'your_data': self.ttl_your_data,
```
**Cache Best Practices**:
- ✅ Use `@cached` decorator for ALL database queries
- ✅ Place logic in services (NOT routers)
- ✅ Cache schema lookups separately (long TTL: 24h)
- ✅ Choose appropriate TTL (frequently changing data: 5-10 min, static data: 30 min - 24h)
- ✅ Include `username` in `key_params` for user-specific data
- ✅ Include filter parameters in `key_params` for query variations
- ❌ Don't query Oracle directly in routers (use services with caching)
- ❌ Don't skip caching for performance-critical endpoints
### Adding a New Frontend Page/Component
**IMPORTANT**: Follow the established CSS architecture and design system.
**Before writing ANY CSS**: Read **`docs/ONBOARDING_CSS.md`** (5-minute quick start) → See "Documentation Index" below for complete guide list.
**Golden Rules**:
- ✅ Use global patterns first (`.roa-card`, `.roa-metric`, `.roa-badge-*`) - check `CSS_PATTERNS.md`
- ✅ Use design tokens (`var(--color-primary)`) not hardcoded values (`#2563eb`)
-**Use shared CSS** from `src/assets/css/` - NEVER create new CSS when shared classes exist
- ✅ For inline stats/totals use `.summary-stats-inline`, `.stat-item`, `.stat-label`, `.stat-value` from `stats.css`
- ❌ Never use `:deep()` in components (use `src/assets/css/vendor/` for PrimeVue overrides)
- ❌ Never duplicate CSS (write once, use everywhere)
- ❌ Never add new scoped CSS for patterns that already exist in shared CSS files
**Tables - Unified Column Structure & Filter Buttons**:
-**ALWAYS use separate columns** for related data (Debit | Credit, not Debit+Credit stacked)
-**Use PrimeVue DataTable** with one value per `<Column>` component
-**Add filter/action buttons** (clear, export Excel, export PDF, refresh) **on separate row below filters**
-**PrimeVue Button** components with **icon + label** (not icon-only!)
-**Export ALL data** from backend (page_size: 999999), not just current page
-**Never group multiple values** vertically in a single column
-**Never use HTML `<button>` for filter actions** (use PrimeVue `<Button>`)
-**Never put action buttons on same row as filters** (separate row!)
-**Never export only current page** (must fetch all data for export)
- 📖 **See**: `CSS_PATTERNS.md` → Table Patterns → Unified Table Column Structure & Filter/Action Buttons
### Adding a New Telegram Bot Command
**IMPORTANT**: Follow established command patterns and formatting.
**Before coding**: Read **`docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md`** for command patterns → See "Documentation Index" for complete guides.
**Standard Pattern** (add handler in `app/bot/handlers.py`):
```python
async def your_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
telegram_id = update.effective_user.id
# 1. Check authentication (use helpers.py)
user = await get_user_by_telegram_id(telegram_id)
if not user:
await update.message.reply_text("⚠️ Account not linked. Use /start with code.")
return
# 2. Check active company (use session.py)
active_company = await get_active_company(telegram_id)
if not active_company:
await update.message.reply_text("⚠️ Select company first: /selectcompany")
return
# 3. Call backend API (use api/client.py)
# 4. Format response (use formatters.py)
# 5. Add tests + update MANUAL_TESTING_CHECKLIST.md
```
### Adding Shared Functionality
1. Place in `shared/{database|auth|utils}/`
2. Import using `sys.path.append()` pattern (see `backend/app/main.py:21`)
3. Add tests in `shared/tests/`
### Frontend API Integration
```javascript
// Store pattern (src/stores/yourStore.js)
import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:8001/api',
headers: { 'Authorization': `Bearer ${token}` }
});
const response = await api.get('/endpoint');
```
---
## 🔒 Security
- **Git Hooks**: Security scanning in `security/install_hooks.sh`
- **Environment Files**: Never commit `.env` (use `.env.example` as template)
- **SSH Keys**: In `ssh-tunnel/secrets/` (gitignored)
- **JWT Secrets**: Generate strong secrets for production
- **Rate Limiting**: Built into auth middleware (5 requests per 5 minutes)
---
## 📚 Documentation Index
### Quick Start & Commands
**`README.md`** - Project overview, setup, development commands, testing, deployment
### Data Entry App (Bonuri Fiscale)
- **`docs/data-entry/CLAUDE.md`** - ⚠️ **READ FIRST** when working on data-entry
- `docs/data-entry/README.md` - Quick start guide
- `docs/data-entry/REQUIREMENTS.md` - Functional requirements
- `docs/data-entry/ARCHITECTURE.md` - Technical architecture (SQLModel, workflow)
### Architecture & Planning
- `DEVELOPMENT_BLUEPRINT.md` - Detailed development plan
### Frontend Development
- **`docs/ONBOARDING_CSS.md`** - CSS system quick start (START HERE for new components)
- **`docs/CSS_PATTERNS.md`** - Complete CSS patterns library (cards, forms, buttons, etc.)
- **`docs/DESIGN_TOKENS.md`** - Design tokens (colors, spacing, typography)
- `docs/STYLING_GUIDELINES.md` - CSS best practices and conventions
- `docs/COMPONENT_STYLING.md` - Component-specific styling guide
- `docs/FORM_TEMPLATE.md` - Standardized form template
- `Frontend module documentation in src/modules/` - Frontend architecture and setup
- `Playwright E2E testing (see tests/ directory)` - Playwright E2E testing guide
### Backend Development
- `Backend module documentation in backend/modules/` - Backend architecture and API details
- API endpoints documented in `README.md` (Authentication, Companies, Dashboard, Invoices, Treasury, Telegram)
### Telegram Bot Development
- **`docs/telegram/README.md`** - Complete bot architecture and development guide (START HERE)
- **`docs/telegram/TELEGRAM_BUTTON_INTERFACE_PLAN.md`** - Command reference and patterns
- `tests/MANUAL_TESTING_CHECKLIST.md` - Manual testing procedures
### Deployment
- `deployment/windows/README.md` - Windows deployment quick start
- `deployment/windows/docs/WINDOWS_DEPLOYMENT.md` - Complete Windows guide
- `deployment/windows/docs/TELEGRAM_BOT_TROUBLESHOOTING.md` - Bot troubleshooting
### Troubleshooting
**`README.md`** - Common issues (SSH tunnel, backend, frontend, database)
**Backend**: Check `.env`, SSH tunnel status, port 8001 availability
**Frontend**: Clear node_modules, check Node.js version (16+), Vite auto-ports
**Database**: Verify SSH tunnel, Oracle listener, credentials, test `/health`
---
## 🔧 Tech Stack
**Backend**: FastAPI, python-oracledb, JWT (PyJWT), Pydantic, pytest
**Frontend**: Vue.js 3 (Composition API), PrimeVue, Pinia, Vite, Axios, Chart.js, Playwright
**Telegram Bot**: python-telegram-bot, SQLite + aiosqlite, httpx, FastAPI (internal), pytest
**Infrastructure**: Oracle Database, SSH Tunnel, Nginx (Linux prod), Docker (Linux prod), IIS + NSSM (Windows prod)
---
**For detailed information on any topic, always check the Documentation Index above first.**