Consolidate Reports and Data Entry apps into a single Vue.js SPA with: Architecture: - Module-based structure with lazy-loaded routes (@reports, @data-entry) - Error boundaries per module to prevent cascade failures - Dual API proxy in Vite for microservices (reports:8001, data-entry:8003) - Pinia store factories for shared auth, company, and period stores - Vite path aliases for clear module boundaries (@shared, @reports, @data-entry) Service Management: - Granular service control scripts (backend-reports.sh, backend-data-entry.sh, bot.sh, frontend.sh) - 87% faster frontend restart: 7s vs 53s full restart - 38% faster full startup: 33s vs 53s via parallel backend initialization - Enhanced start-dev.sh with proper service timeouts (OCR: 30s, Vite: 15s, Bot: 10s) - status.sh for comprehensive health checks Features: - Auto-select first company on login with period auto-load - Hamburger menu with feature toggle support - JWT token auto-injection via axios interceptors - Unified header with company/period selectors - IIS web.config for production deployment with multi-API routing UX Improvements: - Vue watchers for reactive company/period loading - Lazy store initialization with graceful error handling - Period persistence per user+company in localStorage - Feature flags for optional modules Deployment: - Single IIS site serves unified frontend with API proxy rules - Maintains separate backend processes for microservices - Windows line ending fixes (.env CRLF → LF conversion) Stats: 112 files changed, 38,342 insertions(+), 2,342 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
394 lines
16 KiB
Markdown
394 lines
16 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 two main modules:
|
|
1. **Reports App** (`reports-app/`) - Read-only reports from Oracle (raportări)
|
|
2. **Data Entry App** (`data-entry-app/`) - Data input with approval workflow (introduceri date)
|
|
|
|
**Main Branch**: `main` (use for PRs)
|
|
**Working Directory**: Repository root
|
|
|
|
**Quick Reference**: See `README.md` for complete setup, commands, deployment, and testing instructions.
|
|
|
|
---
|
|
|
|
## 📁 Application-Specific Instructions
|
|
|
|
> **IMPORTANT**: When working on a specific application, ALWAYS read its dedicated CLAUDE.md first!
|
|
|
|
| Application | CLAUDE.md Location | Description |
|
|
|-------------|-------------------|-------------|
|
|
| **Data Entry** | `data-entry-app/CLAUDE.md` | Bonuri fiscale, chitanțe, workflow aprobare |
|
|
| **Reports** | This file (below) | Rapoarte Oracle read-only |
|
|
| **Telegram Bot** | `reports-app/telegram-bot/README.md` | Bot Telegram |
|
|
|
|
### When to Use Which Instructions
|
|
|
|
**Working on `data-entry-app/`**:
|
|
→ **FIRST read `data-entry-app/CLAUDE.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
|
|
|
|
**Working on `reports-app/` or `shared/`**:
|
|
→ Use instructions from this file (below)
|
|
|
|
**Working on shared components** (`shared/auth/`, `shared/database/`, `shared/frontend/`):
|
|
→ These are used by BOTH apps - be careful with changes!
|
|
→ `shared/frontend/` contains: LoginView.vue, auth store factory, login styles
|
|
|
|
---
|
|
|
|
## 🏗️ Architecture
|
|
|
|
### Microservices Structure
|
|
```
|
|
.
|
|
├── shared/ # Shared components (DB pool, auth, frontend)
|
|
│ ├── database/ # Oracle pool (used by both apps)
|
|
│ ├── auth/ # JWT auth (used by both apps)
|
|
│ └── frontend/ # Shared Vue components, stores, styles
|
|
│ ├── components/ # LoginView.vue
|
|
│ ├── stores/ # auth.js (Pinia store factory)
|
|
│ └── styles/ # login.css
|
|
│
|
|
├── reports-app/ # READ-ONLY reports from Oracle
|
|
│ ├── backend/ # FastAPI API (port 8001)
|
|
│ ├── frontend/ # Vue.js 3 UI (port 3000-3005)
|
|
│ └── telegram-bot/ # Telegram bot (port 8002 internal)
|
|
│
|
|
├── data-entry-app/ # DATA INPUT with approval workflow
|
|
│ ├── backend/ # FastAPI API (port 8003) - SQLite + SQLModel
|
|
│ ├── frontend/ # Vue.js 3 UI (port 3010)
|
|
│ └── CLAUDE.md # ⚠️ READ THIS for data-entry work!
|
|
│
|
|
├── docs/ # Architecture & style guides
|
|
├── deployment/ # Production deployment scripts
|
|
└── ssh-tunnel/ # SSH tunnel for Oracle DB access
|
|
```
|
|
|
|
### Starting Services
|
|
|
|
**Quick Start** (All services with parallel backend startup):
|
|
```bash
|
|
./start-dev.sh # Dev: Backend :8001, :8003, Bot :8002, Frontend :3000 (~11s)
|
|
./start-test.sh # Test: Same ports (~33s - Oracle pool init takes longer)
|
|
```
|
|
|
|
**Individual Service Control** (for quick development iterations):
|
|
```bash
|
|
./frontend.sh restart # Restart frontend only (~7s - fastest!)
|
|
./backend-reports.sh start # Start Reports backend :8001
|
|
./backend-data-entry.sh stop # Stop Data Entry backend :8003
|
|
./bot.sh status # Check Telegram bot :8002 status
|
|
./status.sh # Show all services status + health checks
|
|
```
|
|
|
|
**Infrastructure**:
|
|
```bash
|
|
./ssh_tunnel.sh start # Oracle DB tunnel (production: 10.0.20.36)
|
|
./ssh-tunnel-test.sh start # Oracle TEST tunnel (LXC: 10.0.20.121)
|
|
```
|
|
|
|
**Benefits**:
|
|
- **87% faster frontend restart**: 7s vs 53s full restart
|
|
- **38% faster full startup**: 33s vs 53s (test) via parallel backend init
|
|
- **Granular control**: Restart individual services without affecting others
|
|
|
|
### Key Architectural Decisions
|
|
- **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`
|
|
- **Two-Tier Cache System**: Hybrid L1 (Memory) + L2 (SQLite) cache in `backend/app/cache/` - **MANDATORY for all new endpoints**
|
|
- **SSH Tunnel**: Required for Oracle DB connections (development/Linux) - see Database Setup
|
|
- **FastAPI Structure**: Services in `backend/app/services/` with `@cached` decorator, routers in `backend/app/routers/`, models in `backend/app/models/` or `schemas/`
|
|
- **Telegram Bot**: Standalone SQLite database for bot data, communicates with backend via HTTP API
|
|
|
|
---
|
|
|
|
## 🗄️ Database Setup
|
|
|
|
**Schema**: `CONTAFIN_ORACLE` (authentication and user management)
|
|
**Connection**: SSH tunnel required (Oracle on remote network)
|
|
|
|
### SSH Tunnel (Development/Linux)
|
|
```bash
|
|
./ssh_tunnel.sh start # localhost:1526 → remote:1521
|
|
./ssh_tunnel.sh status # Check tunnel
|
|
./ssh_tunnel.sh stop # Stop tunnel
|
|
```
|
|
|
|
**IMPORTANT**: Always ensure SSH tunnel is running before starting backend services.
|
|
|
|
### Environment Variables (`reports-app/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
|
|
|
|
# Telegram Bot Integration
|
|
TELEGRAM_BOT_INTERNAL_API=http://localhost:8002
|
|
```
|
|
|
|
**Windows Production**: Direct Oracle connection, no SSH tunnel required. Ensure `TELEGRAM_BOT_INTERNAL_API` is set for auth code management.
|
|
|
|
---
|
|
|
|
## 🔑 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
|
|
- `reports-app/backend/app/main.py` - Auth router inline definition
|
|
|
|
---
|
|
|
|
## 📝 Common Development Tasks
|
|
|
|
### Adding a New API Endpoint
|
|
**IMPORTANT**: Always use the cache system for database queries to improve performance.
|
|
|
|
1. Create **service** in `reports-app/backend/app/services/your_service.py` (NOT in router!)
|
|
2. Define Pydantic schemas in `app/schemas/` or `app/models/`
|
|
3. **Add caching** using `@cached` decorator in service methods
|
|
4. Create router in `reports-app/backend/app/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 **`reports-app/telegram-bot/TELEGRAM_COMMANDS.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)
|
|
- **`data-entry-app/CLAUDE.md`** - ⚠️ **READ FIRST** when working on data-entry
|
|
- `data-entry-app/README.md` - Quick start guide
|
|
- `docs/data-entry/REQUIREMENTS.md` - Functional requirements
|
|
- `docs/data-entry/ARCHITECTURE.md` - Technical architecture (SQLModel, workflow)
|
|
|
|
### Architecture & Planning
|
|
- **`docs/ARCHITECTURE_SCHEMA.md`** - Architecture diagrams, cache system, and schemas
|
|
- `docs/MICROSERVICES_GUIDE.md` - Microservices architecture details
|
|
- `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
|
|
- `reports-app/frontend/README.md` - Frontend architecture and setup
|
|
- `reports-app/frontend/tests/README.md` - Playwright E2E testing guide
|
|
|
|
### Backend Development
|
|
- `reports-app/backend/README.md` - Backend architecture and API details
|
|
- API endpoints documented in `README.md` (Authentication, Companies, Dashboard, Invoices, Treasury, Telegram)
|
|
|
|
### Telegram Bot Development
|
|
- **`reports-app/telegram-bot/README.md`** - Complete bot architecture and development guide (START HERE)
|
|
- **`reports-app/telegram-bot/TELEGRAM_COMMANDS.md`** - Command reference and patterns
|
|
- `tests/MANUAL_TESTING_CHECKLIST.md` - Manual testing procedures
|
|
|
|
### Deployment
|
|
- **`DEPLOYMENT_GUIDE.md`** - Production deployment (Linux/Docker & Windows/IIS)
|
|
- `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.**
|