# CLAUDE.md

This file provides guidance to Claude Code when working with code in this repository.

## Project Overview

**ROA2WEB** - Modern ERP Application with ultrathin monolith architecture:
- **Reports Module** (`backend/modules/reports/`) - Read-only reports from Oracle
- **Data Entry Module** (`backend/modules/data_entry/`) - Data input with approval workflow
- **Telegram Bot Module** (`backend/modules/telegram/`) - Telegram bot integration

**Main Branch**: `main` | **Setup & Commands**: See `README.md`

---

## Module-Specific Instructions

> **IMPORTANT**: Read module documentation FIRST before working on a module!

| Module | Documentation | Key Points |
|--------|--------------|------------|
| **Data Entry** | `docs/data-entry/DATA-ENTRY-MODULE.md` | SQLModel, SQLite, workflow states |
| **Reports** | This file + `README.md` | Oracle read-only, caching |
| **Telegram** | `docs/telegram/README.md` | Bot commands, formatting |

---

## Quick Reference

### Architecture
See `docs/ARCHITECTURE-DECISIONS.md` for:
- Single worker (`--workers 1`) - required for Telegram bot
- Ultrathin monolith rationale
- IIS deployment strategy

### Starting Services
```bash
./start-prod.sh         # Backend :8000 + Frontend :3000 (PROD)
./start-prod.sh stop    # Stop all services
./ssh-tunnel-prod.sh    # Oracle DB tunnel (REQUIRED on Linux)
./status.sh             # Check services
```

### Playwright Testing
```bash
# Pentru testare UI cu Playwright:
./start-test.sh         # Pornește în mod TEST
./start-test.sh stop    # Oprește serverele

# Credențiale TEST:
# User: MARIUS M
# Pass: 123
# Firma: MARIUSM AUTO
```

### Database
- **Schema**: `CONTAFIN_ORACLE`
- **Connection**: SSH tunnel required (Linux dev)
- **Env**: `backend/.env` (see `backend/ENV-SETUP.md`)

---

## Key Rules (ALWAYS FOLLOW)

### Git Commits
- **NU da commit automat!** Întreabă utilizatorul ÎNAINTE de a face commit
- Arată ce fișiere s-au modificat (`git status`) și propune mesajul de commit
- Așteaptă confirmarea explicită înainte de `git commit`

### Frontend Development
**Before writing CSS**: Read `docs/ONBOARDING_CSS.md` (5 min)

#### CSS Design Tokens - OBLIGATORIU ⚠️
- **CITEȘTE ÎNTÂI**: `docs/DESIGN_TOKENS.md` înainte de a scrie CSS
- Folosește **DOAR** design tokens, NICIODATĂ valori hardcodate:
  - Spacing: `var(--space-xs)` (4px), `var(--space-sm)` (8px), `var(--space-md)` (16px)
  - Font weight: `var(--font-medium)` (500), `var(--font-semibold)` (600), `var(--font-bold)` (700)
  - Colors: `var(--green-50)`, `var(--blue-50)`, `var(--surface-card)`, etc.
  - Radius: `var(--radius-sm)` (4px), `var(--radius-md)` (8px)
- ❌ GREȘIT: `padding: 8px`, `font-weight: 500`, `background: #f0fdf4`
- ✅ CORECT: `padding: var(--space-sm)`, `font-weight: var(--font-medium)`, `background: var(--green-50)`

#### Alte reguli CSS
- Use shared CSS from `src/assets/css/` - NEVER duplicate
- Check `docs/CSS_PATTERNS.md` for existing patterns
- **Theme toggle**: App has 3 modes (auto/light/dark) - test BOTH themes!

**Tables**:
- Use separate columns (Debit | Credit, not stacked)
- Filter buttons on separate row below filters
- Export ALL data, not just current page

### Backend Development
- Place logic in **services**, not routers
- Use `@cached` decorator for ALL database queries
- Cache schema lookups separately (24h TTL)

**Service pattern**:
```python
from app.cache.decorators import cached

class YourService:
    @staticmethod
    @cached(cache_type='your_data', key_params=['company_id', 'username'])
    async def get_data(company_id: int, username: str):
        # Query Oracle here
```

### Authentication
- JWT structure: `username`, `user_id`, `companies[]`, `permissions[]`, `exp`, `iat`, `type`
- Middleware: `shared/auth/middleware.py` (auto-injects `request.state.user`)
- Rate limiting: 5 req/5 min for `/auth/*`

---

## Documentation Index

| Topic | File | Description |
|-------|------|-------------|
| **Setup** | `README.md` | Commands, testing, deployment |
| **Architecture** | `docs/ARCHITECTURE-DECISIONS.md` | Critical decisions |
| **CSS Quick Start** | `docs/ONBOARDING_CSS.md` | START HERE for frontend |
| **CSS Patterns** | `docs/CSS_PATTERNS.md` | Cards, forms, buttons, tables |
| **Design Tokens** | `docs/DESIGN_TOKENS.md` | Colors, spacing, dark mode |
| **Data Entry** | `docs/data-entry/DATA-ENTRY-MODULE.md` | SQLModel, workflow |
| **Telegram** | `docs/telegram/README.md` | Bot development |
| **Deployment** | `deployment/linux/README.md` | Deploy from LXC |

---

## Learned Patterns & Known Issues

> **Patterns/Gotchas from previous sessions**: Auto-loaded from `.claude/rules/auto-build-memory.md`

### Known Issues & Fixes

#### Mobile File Upload ERR_NETWORK (Android/iOS)
**Problem**: File uploads fail with `ERR_NETWORK` (status 0) on mobile browsers.

**Cause**: Android/iOS browsers invalidate File object references after accessing properties due to SnapshotState in W3C File API. See [Chromium Bug #40703873](https://issues.chromium.org/40703873).

**Solution**: Clone the file into memory immediately after selection:
```javascript
const handleFile = async (file) => {
  // FIX: Clone file to memory to avoid SnapshotState invalidation
  const arrayBuffer = await file.arrayBuffer()
  const clonedFile = new File([arrayBuffer], file.name, {
    type: file.type,
    lastModified: file.lastModified
  })
  selectedFile.value = clonedFile
}
```

**Applied in**: `src/modules/data-entry/components/ocr/OCRUploadZone.vue`

---

## Security

- Never commit `.env` files
- SSH keys in `ssh-tunnel/secrets/` (gitignored)
- Rate limiting in auth middleware

---

## Tech Stack

**Backend**: FastAPI, python-oracledb, JWT, Pydantic
**Frontend**: Vue.js 3, PrimeVue, Pinia, Vite
**Telegram**: python-telegram-bot, SQLite, httpx
**Infra**: Oracle DB, SSH Tunnel, IIS (Windows prod)
