# 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.sh prod # Backend :8000 + Frontend :3000 (PROD) ./start.sh prod stop # Stop all services ./start.sh test # Start in TEST mode ./start.sh test stop # Stop TEST services ./ssh-tunnel.sh # Oracle DB tunnel (for servers with SSH access) ./status.sh # Check services ``` ### Playwright Testing ```bash # Pentru testare UI cu Playwright: ./start.sh test # Pornește în mod TEST ./start.sh test 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 ### Mobile Development Rules ⚠️ **Before writing mobile UI**: Read `docs/MOBILE_PATTERNS.md` #### Required Components All mobile pages **MUST** use these shared components: - **MobileTopBar**: Required for all mobile views (title, actions, back navigation) - **MobileBottomNav**: Required for all mobile views (persistent navigation) - **BottomSheet**: Required for filters on mobile (NEVER inline filters) - **MobileSelectionFooter**: Required when items are selectable (batch actions) ```javascript // Import from shared components import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue' import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue' import BottomSheet from '@shared/components/mobile/BottomSheet.vue' import MobileSelectionFooter from '@shared/components/mobile/MobileSelectionFooter.vue' ``` #### Layout Rules 1. **Filters → BottomSheet**: Pe mobil, filtrele se pun ÎNTOTDEAUNA în BottomSheet, NU inline 2. **Selection Actions → Footer**: Când sunt elemente selectate, acțiunile apar în MobileSelectionFooter, NU în header 3. **Touch Targets**: Minimum **44x44px** pentru toate elementele interactive (butoane, linkuri, checkbox-uri) 4. **Content Padding**: Conținutul trebuie să aibă `padding-top: 56px` și `padding-bottom: 56px` pentru barele fixe #### Mobile Code Review Checklist ✓ ```markdown □ Folosește MobileTopBar cu props corecte (title, showBack/showMenu, actions) □ Folosește MobileBottomNav pentru navigare □ Filtrele sunt în BottomSheet (nu inline pe pagină) □ Selecția afișează MobileSelectionFooter (nu butoane în header) □ Touch targets ≥ 44x44px □ Padding pentru bare fixe (top: 56px, bottom: 56px) □ Testat în dark mode □ Folosește design tokens (nu valori hardcodate) □ Nu duplică CSS din componentele mobile ``` ### 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 | | **Mobile Patterns** | `docs/MOBILE_PATTERNS.md` | Mobile components, touch UX | | **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 | | **Troubleshooting** | `docs/troubleshooting/` | Debugging guides, memory leaks | --- ## 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)