diff --git a/.claude/settings.json b/.claude/settings.json index e959a79..d57769e 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,7 +1,7 @@ { "statusLine": { "type": "command", - "command": "/home/claude/.claude/statusline.sh" + "command": "/home/moltbot/.claude/statusline.sh" }, "permissions": { "allow": [ diff --git a/README.md b/README.md index 04d7a2a..5c260c4 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ This starts SSH tunnel (if needed), unified backend (port 8000), and frontend (p - **Modular Architecture**: Independent modules with clear separation of concerns - **Oracle Integration**: Direct Oracle stored procedure calls with caching - **Responsive Design**: Mobile-friendly Vue.js interface -- **Telegram Integration**: Alternative bot-based interface +- **Telegram Integration**: Bot-based interface cu procesare bonuri fiscale prin OCR (PDF/foto → preview → salvare Oracle) --- diff --git a/docs/telegram/README.md b/docs/telegram/README.md index 39b752e..7dc58e2 100644 --- a/docs/telegram/README.md +++ b/docs/telegram/README.md @@ -1,399 +1,225 @@ # ROA2WEB Telegram Bot -> **Architecture:** Ultrathin Monolith - Telegram bot runs as a background task within the unified backend on port 8000. -> See `docs/telegram/DEPLOYMENT.md` for single-worker requirement. - -> **Telegram Frontend for ROA2WEB ERP System** with Direct Command Interface +> **Architecture:** Ultrathin Monolith — bot rulează ca background task în backend-ul unificat pe portul 8000. +> Vezi `docs/telegram/DEPLOYMENT.md` pentru cerința single-worker. ## Overview -ROA2WEB Telegram Bot provides a command-based interface to the ROA2WEB Financial ERP system through Telegram. Users can access dashboards, invoices, treasury data, and company information using simple slash commands. +Botul Telegram ROA2WEB oferă acces la sistemul ERP financiar prin comenzi simple și procesare bonuri fiscale prin OCR. -### Key Features +### Funcționalități principale -- **Direct Command Interface**: Simple `/` commands for all operations -- **Simplified Authentication** 🆕: Multiple linking methods (Deep Link, QR Code, Manual) - 77% faster than before! -- **One-Click Connection**: Deep link automatically opens Telegram with pre-populated code -- **QR Code Support**: Scan from mobile to link instantly (cross-device) -- **Secure Authentication**: Account linking with Oracle backend and JWT token management -- **Financial Data Access**: Query dashboards, invoices, treasury data, and company information -- **Company Selection**: Set active company for all subsequent queries -- **Multi-language**: Romanian and English support -- **Session Management**: Active company persistence with SQLite database -- **Docker Ready**: Containerized deployment with Docker Compose +- **Autentificare** prin cod de legătură (Deep Link / QR Code / Manual) +- **Date financiare**: dashboard, facturi, trezorerie, sold clienți/furnizori +- **Bonuri fiscale**: trimite PDF sau fotografie → OCR → preview → salvare în Oracle -## Architecture +--- -### System Components +## Arhitectură + +Modulul este integrat în monolitul unificat: ``` -telegram-bot/ -├── app/ -│ ├── agent/ # Session management -│ │ └── session.py # Active company persistence -│ ├── api/ # Backend API client -│ │ └── client.py # HTTP client for ROA2WEB backend -│ ├── auth/ # Authentication & linking -│ │ └── linking.py # Account linking logic -│ ├── bot/ # Telegram bot handlers -│ │ ├── handlers.py # Command handlers -│ │ ├── helpers.py # Helper functions -│ │ ├── formatters.py # Response formatting -│ │ └── keyboards.py # Inline keyboard helpers -│ ├── db/ # SQLite database (standalone) -│ │ ├── database.py # Connection & schema -│ │ └── operations.py # CRUD operations -│ ├── internal_api.py # FastAPI for backend communication -│ └── main.py # Main entry point -├── data/ # SQLite database storage (gitignored) -├── tests/ # Unit & integration tests -├── Dockerfile # Container configuration -├── requirements.txt # Python dependencies -└── .env.example # Environment variables template +backend/modules/telegram/ +├── agent/ +│ └── session.py # Gestionare sesiune (firma activă) +├── api/ +│ └── client.py # HTTP client pentru ROA2WEB backend +├── auth/ +│ ├── email_auth.py +│ └── linking.py # Legare cont Oracle ↔ Telegram +├── bot/ +│ ├── handlers.py # Handlere comenzi (/dashboard, /facturi, etc.) +│ ├── formatters.py # Formatare răspunsuri Markdown +│ ├── keyboards.py # Taste inline +│ ├── helpers.py +│ └── menus.py +├── db/ +│ ├── database.py # SQLite — schemă și conexiune +│ └── operations.py # CRUD operații +├── handlers/ +│ └── receipt_handlers.py # Procesare bonuri fiscale (OCR flow) +├── routers/ +│ ├── auth_codes.py +│ └── internal_api.py # FastAPI endpoint pentru backend callbacks +└── bot_main.py # Punct intrare bot (ApplicationBuilder) ``` -### Data Flow +### Flux date — Bonuri fiscale -1. **User sends command** → Telegram → Bot Command Handlers -2. **Authentication check** → SQLite database → JWT validation -3. **API calls** → ROA2WEB Backend → Oracle database -4. **Response formatting** → Telegram user +``` +User trimite PDF/foto + ↓ +handle_document_message() / handle_photo_message() + ↓ +submit_ocr_job() → OCR Worker Pool (docTR + pypdfium2) + ↓ +wait_for_result() — polling până la 120s + ↓ +_format_receipt_preview() → mesaj Telegram cu butoane Confirmă/Anulează + ↓ +handle_receipt_callback() → confirm + ↓ +_resolve_schema() → CONTAFIN_ORACLE.v_nom_firme (schema firmei active) + ↓ +_save_to_oracle() → write_receipt() → PACK_CONTAFIN (COD din seq_cod.nextval) + ↓ +"✅ Bon salvat! Cod document: XXXXXXX" +``` -### Database Schema (SQLite) +### Flux date — Comenzi financiare -The bot uses a standalone SQLite database for: +``` +User → Comandă Telegram → handlers.py → API client → Backend API → Oracle DB → Formater → User +``` -- **telegram_users**: User accounts and Oracle account linking -- **telegram_auth_codes**: Temporary 8-character linking codes (15 min expiry) -- **telegram_sessions**: Active company selection and session state +--- -## Setup & Configuration +## Setup -### Prerequisites - -- ROA2WEB backend running (the bot runs as part of the unified backend) -- Telegram Bot Token (from @BotFather) - -### Step 1: Create Telegram Bot (One-time) - -1. Open Telegram and search for `@BotFather` -2. Send `/newbot` command -3. Follow prompts to create bot -4. Save the bot token provided - -### Step 2: Configure Environment - -Add to `backend/.env`: +### Configurare `.env` ```bash -# Telegram Bot Configuration +# backend/.env sau backend/.env.test MODULE_TELEGRAM_ENABLED=true TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather ``` -### Step 3: Start the Application +### Pornire ```bash -# From project root - starts backend with Telegram bot integrated -./start.sh prod - -# Or for testing: -./start.sh test +./start.sh prod # Pornește tot (backend + frontend + bot) +./start.sh test # Mod test (conexiune Oracle directă, fără SSH tunnel) ``` -The bot starts automatically as a background task when `MODULE_TELEGRAM_ENABLED=true`. +Botul pornește automat ca background task când `MODULE_TELEGRAM_ENABLED=true`. -> **Important:** Backend must run with `--workers 1` for Telegram bot to work correctly. -> See `docs/telegram/DEPLOYMENT.md` for details. +> **Important:** Backend-ul trebuie rulat cu `--workers 1`. Vezi `docs/telegram/DEPLOYMENT.md`. -## Usage +--- -### Available Commands +## Comenzi disponibile -| Command | Description | -|---------|-------------| -| `/start [code]` | Start bot or link account with 8-char code | -| `/help` | Show available commands and usage guide | -| `/companies` | View accessible companies/firms | -| `/selectcompany [name]` | Select or search for active company | -| `/dashboard` | View financial dashboard for active company | -| `/sold` | View balance (alias for `/dashboard`) | -| `/facturi [filter]` | View invoices (optional filters: neplatite, platite) | -| `/trezorerie` | View treasury/payment data | -| `/clear` | Clear active company selection | -| `/unlink` | Unlink Telegram account from Oracle | +| Comandă | Descriere | +|---------|-----------| +| `/start [cod]` | Pornire bot sau legare cont cu cod 8 caractere | +| `/help` | Afișează comenzile disponibile | +| `/companies` | Lista firme accesibile | +| `/selectcompany [nume]` | Selectează firma activă | +| `/dashboard` | Dashboard financiar pentru firma activă | +| `/sold` | Sold (alias `/dashboard`) | +| `/facturi [filtru]` | Facturi (filtre: `neplatite`, `platite`) | +| `/trezorerie` | Date trezorerie (casă + bancă) | +| `/clear` | Șterge selecția firmei active | +| `/unlink` | Deconectează contul Telegram de la Oracle | -### Authentication Flow (Updated 2025 - FAZA 1 Improvements) +### Bonuri fiscale (fără comandă explicită) -The bot now supports **3 easy methods** for account linking: +Trimite direct un **fișier PDF** sau o **fotografie** a bonului fiscal → botul pornește automat fluxul OCR. -#### Method 1: Deep Link (Recommended - One Click) 🚀 +--- -1. **Login** to ROA2WEB web application at http://localhost:3000 -2. **Navigate** to `/telegram` (Settings → Telegram) -3. **Click** "Generează Cod" button -4. **Click** "🚀 Deschide în Telegram" button -5. **Telegram opens automatically** with code pre-populated -6. **Done!** Account linked in <30 seconds +## Autentificare -**Benefits:** -- ⚡ **Zero manual copying** - code is pre-filled -- 🎯 **One click** - Telegram opens automatically -- ⏱️ **Super fast** - complete in ~30 seconds -- 📱 **Works on desktop and mobile** (same device) +### Metoda 1: Deep Link (recomandat) -#### Method 2: QR Code (Cross-Device) 📷 +1. Login în aplicația ROA2WEB → `/telegram` +2. Click "Generează Cod" +3. Click "🚀 Deschide în Telegram" → Telegram se deschide cu codul pre-completat +4. Gata — cont legat în ~30 secunde -Perfect when working on desktop but have Telegram on mobile: +### Metoda 2: QR Code (cross-device) -1. **Login** to ROA2WEB web app (desktop) -2. **Navigate** to `/telegram` -3. **Click** "Generează Cod" -4. **Scan QR Code** displayed on screen with Telegram on mobile -5. **Telegram opens** with code pre-populated -6. **Done!** Account linked +1. Login pe desktop → `/telegram` → "Generează Cod" +2. Scanează QR Code-ul afișat cu Telegram pe mobil +3. Gata -**Benefits:** -- 📱 **Cross-device** - desktop browser → mobile Telegram -- 📷 **Easy scanning** - just point camera at screen -- ✅ **No typing** - code automatically loaded +### Metoda 3: Manual -#### Method 3: Manual (Traditional Fallback) ⌨️ +1. Login → `/telegram` → "Generează Cod" → copiază codul +2. Trimite codul la bot (ex: `ABC123XY`) -If deep link or QR code don't work: +**Detalii tehnice:** +- Cod 8 caractere, valabil 15 minute +- Backend salvează codul via `POST /internal/save-code` +- Bot verifică codul și leagă conturile în SQLite +- User primește JWT token -1. **Login** to ROA2WEB web application -2. **Navigate** to `/telegram` -3. **Click** "Generează Cod" -4. **Click** copy button (📋) to copy code -5. **Open Telegram** manually -6. **Send code** to bot: - - **Direct input**: `ABC123XY` (just paste) - - **Classic format**: `/start ABC123XY` -7. **Done!** Account linked +--- -**Technical Details:** -- Backend generates **8-character code** (valid 15 minutes) -- Backend saves code to telegram-bot via internal API (`POST /internal/save-code`) -- Bot verifies code and links accounts in SQLite database -- Bot receives **JWT token** from backend -- User can now use commands to query financial data +## Bonuri fiscale — detalii tehnice -**Improvement Metrics:** -- ⏱️ Time: **3 minutes → 40 seconds** (77% reduction) -- 📉 Steps: **7 → 4** (43% reduction) -- ✅ Manual copying: **Eliminated** (with Method 1 or 2) +### OCR Pipeline -### Usage Examples +- **Engine principal:** docTR (CPU-only, fără NVIDIA/CUDA) +- **PDF decode:** pypdfium2 (fallback când poppler-utils nu e instalat) +- **Profil fallback:** GENERIC când CUI-ul furnizorului nu are profil dedicat +- **Timeout OCR:** 120 secunde +- **Pending TTL:** 600 secunde (bon în așteptare expiră după 10 minute) -``` -User: /companies -Bot: Lists all accessible companies with ID, name, and CUI +### Scriere Oracle -User: /selectcompany ACME -Bot: Shows selection keyboard for companies matching "ACME" -[User clicks company button] -Bot: Company selected: ACME SRL +- COD unic generat din `seq_cod.nextval` (nu MAX+1 — evită race conditions) +- Conexiunea se face AS schema owner (nu read user) — cerut de `PACK_CONTAFIN` care folosește `SESSION_USER` în SQL dinamic +- Pool per `(server_id, schema)` — fiecare schemă Oracle are propriul connection pool +- 3 linii contabile per bon: cheltuială (6x/401), TVA (4426/401), plată (401/5311 sau 401/5121) -User: /dashboard -Bot: Displays dashboard statistics for ACME SRL: - - Total balance - - Invoices issued/paid/unpaid - - Total collections and payments +### Câmpuri extrase de OCR → preview Telegram -User: /facturi neplatite -Bot: Shows list of unpaid invoices for ACME SRL +| Câmp OCR | Afișat în preview | +|----------|-------------------| +| `partner_name` | Furnizor | +| `cui` | CUI furnizor | +| `receipt_date` | Data | +| `receipt_number` | Nr. bon | +| `amount` | Total RON | +| `tva_total` | TVA RON | -User: /trezorerie -Bot: Displays treasury data (cash balance, bank accounts, etc.) +--- -User: /clear -Bot: Active company cleared. Use /selectcompany to select another. -``` - -## Docker Deployment - -### Build Image +## Teste ```bash -# From telegram-bot directory -docker build -t roa-telegram-bot . +# Toate testele modulului Telegram +pytest backend/modules/telegram/tests/ -v + +# Teste cu DB live Oracle +ORACLE_INTEGRATION_USER=MARIUSM_AUTO \ +PASSWORD=ROMFASTSOFT \ +DSN=10.0.20.121:1521/ROA \ +pytest backend/modules/telegram/tests/ -v + +# Doar testele E2E (necesită DB) +pytest backend/modules/telegram/tests/test_e2e_receipt_flow.py -v ``` -### Run Container +**Stare teste (la merge):** 48 pass + 2 skipped (real DB, rulează cu env vars). -```bash -docker run -d \ - --name roa-telegram-bot \ - -e TELEGRAM_BOT_TOKEN=your_token \ - -e BACKEND_URL=http://backend:8001 \ - -v $(pwd)/data:/app/data \ - roa-telegram-bot -``` - -### Docker Compose - -See `docker-compose.yml` in project root for full orchestration with backend and database. - -## Development - -### Project Structure - -- **app/main.py**: Bot entry point and Telegram application setup -- **app/bot/handlers.py**: All command handlers (`/start`, `/dashboard`, etc.) -- **app/bot/helpers.py**: Helper functions for company selection and prompts -- **app/bot/formatters.py**: Response formatting utilities -- **app/auth/linking.py**: Account linking and JWT management -- **app/api/client.py**: HTTP client for backend API calls -- **app/agent/session.py**: Session management (active company persistence) -- **app/db/**: SQLite database operations -- **app/internal_api.py**: FastAPI for backend callbacks - -### Running Tests - -```bash -# Run all tests -pytest tests/ -v - -# Run specific test suites -pytest tests/test_auth.py -v # Authentication tests -pytest tests/test_session_company.py -v # Session & company tests -pytest tests/test_helpers.py -v # Helper function tests -pytest tests/test_formatters.py -v # Formatter tests - -# Run with coverage -pytest tests/ --cov=app --cov-report=html -``` - -### Adding New Commands - -1. Add handler function in `app/bot/handlers.py`: -```python -async def my_command(update: Update, context: ContextTypes.DEFAULT_TYPE): - # Implementation - pass -``` - -2. Register handler in `app/main.py`: -```python -application.add_handler(CommandHandler("mycommand", my_command)) -``` - -3. Add to `__all__` export in `handlers.py` - -## User Experience Improvements (2025) - -### FAZA 1: Authentication Simplification ✅ - -**Implemented:** January 2025 -**Status:** Production Ready - -**What Changed:** -- Added **Deep Link** button - one-click Telegram opening -- Added **QR Code** generation for cross-device linking -- Improved **Manual method** with copy button -- Reduced linking time by **77%** (3 min → 40 sec) -- Reduced steps by **43%** (7 → 4 steps) - -**Documentation:** -- **Complete Plan:** [TELEGRAM_AUTH_IMPROVEMENT_PLAN.md](./TELEGRAM_AUTH_IMPROVEMENT_PLAN.md) -- **Testing Guide:** [TESTING_INSTRUCTIONS_FAZA1.md](./TESTING_INSTRUCTIONS_FAZA1.md) -- **Implementation Summary:** [FAZA1_IMPLEMENTATION_SUMMARY.md](./FAZA1_IMPLEMENTATION_SUMMARY.md) - -**Frontend Changes:** -- `src/modules/reports/views/TelegramView.vue` - Complete UI refactor -- Added `qrcode.vue` dependency for QR generation -- Environment variable: `VITE_TELEGRAM_BOT_USERNAME` - -### FAZA 2: Email Magic Link (Optional - Future) - -**Status:** Planned -**Estimated:** 3.5 hours development - -**What's Planned:** -- Email with magic link option -- Professional HTML email template -- Auto-detect SMTP configuration -- Checkbox "Send code via email" - -**Prerequisites:** -- SMTP server configuration (Gmail, SendGrid, AWS SES) -- User email addresses in Oracle database - -**Note:** FAZA 2 is completely optional. FAZA 1 provides excellent UX for most users. +--- ## Troubleshooting -### Bot Not Responding +### Botul nu răspunde -- Check bot is running: `ps aux | grep python.*main.py` -- Check logs: `tail -f logs/telegram-bot.log` -- Verify TELEGRAM_BOT_TOKEN is correct -- Ensure backend is accessible at BACKEND_URL +- Verifică log: `tail -f /tmp/unified_backend_test.log` +- Verifică `MODULE_TELEGRAM_ENABLED=true` în `.env` +- Backend rulează cu `--workers 1`? -### Authentication Issues +### OCR eșuat / timeout -- Check auth code expiry (15 minutes) -- Verify backend internal API is accessible (port 8002) -- Check SQLite database permissions -- **Deep Link not working?** Browser may block protocol handler - click "Allow" when prompted -- **QR Code not scanning?** Ensure good lighting and camera focus -- **Manual method always works** as fallback +- Worker pool se pre-warmează la pornire (~11 secunde) +- Dacă modifici `ocr_worker_process.py`, restart complet necesar (`./start.sh test stop && ./start.sh test`) — uvicorn --reload nu reîncarcă procesele separate -### Database Issues +### Oracle write eșuat -- Ensure `data/` directory exists and is writable -- Check database file: `sqlite3 data/telegram_bot.db ".schema"` -- Automatic cleanup runs hourly for expired data +- `ORA-01017`: credențiale incorecte — verifică `backend/secrets/.oracle_pass` +- `ORA-00001`: bon duplicat (constraint unique) +- `ORA-28000`: user Oracle blocat — prea multe login-uri eșuate; DBA trebuie să deblocheze +- **Nu schimba** `secrets/*.oracle_pass` cât botul rulează — provoacă spam failed logins → ORA-28000 -### Deep Link Issues (FAZA 1) +### SSH Tunnel warnings (inofensive în test) -**Problem:** Deep link button doesn't open Telegram - -**Solutions:** -1. **Desktop:** Browser may ask permission - click "Allow" to open Telegram -2. **Mobile:** Ensure Telegram app is installed -3. **Fallback:** Use QR Code (Method 2) or Manual (Method 3) - -**Browser Compatibility:** -- ✅ Chrome/Edge - Works perfectly -- ⚠️ Firefox - May show permission prompt -- ⚠️ Safari - May show permission prompt -- ✅ Mobile browsers - Works on all major browsers - -**Problem:** QR Code doesn't display - -**Solutions:** -1. Check browser console for errors (F12) -2. Ensure `qrcode.vue` package is installed: `npm list qrcode.vue` -3. Rebuild frontend: `cd frontend && npm run build` -4. **Fallback:** Use Manual method (always works) - -## API Integration - -The bot communicates with ROA2WEB backend via HTTP API: - -- `POST /api/telegram/auth/verify-user` - Verify user_id -- `POST /api/telegram/auth/refresh-token` - Refresh JWT -- `GET /api/companies` - Get user companies -- `GET /api/dashboard/{company_id}` - Dashboard data -- `GET /api/invoices/{company_id}` - Invoice list -- `GET /api/treasury/{company_id}` - Treasury data - -All requests include JWT token in Authorization header (except verify-user endpoint). - -## Security - -- JWT tokens are stored encrypted in SQLite -- Auth codes expire after 15 minutes -- Sessions are automatically cleaned up -- Environment variables never committed to git -- Rate limiting on authentication endpoints - -## License - -See main project LICENSE file. - -## Support - -For issues, questions, or contributions, see the main ROA2WEB project documentation. +``` +[SSH-MONITOR] [vending] FAIL — Restart failed (code 1) +``` +Normal în modul test dacă `sshpass` nu e instalat. Nu afectează funcționalitatea.