Files
roa2web-service-auto/docs/telegram/README.md
Marius Mutu b0f4800e5f docs: update README and Telegram bot documentation
- README: updated Telegram integration description to mention OCR bonuri
- docs/telegram/README.md: rewrote in Romanian, added bonuri fiscale
  workflow (PDF/foto → OCR → preview → Oracle)
- .claude/settings.json: fix statusline path for current user

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 09:30:00 +00:00

226 lines
6.9 KiB
Markdown

# ROA2WEB Telegram Bot
> **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
Botul Telegram ROA2WEB oferă acces la sistemul ERP financiar prin comenzi simple și procesare bonuri fiscale prin OCR.
### Funcționalități principale
- **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
---
## Arhitectură
Modulul este integrat în monolitul unificat:
```
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)
```
### Flux date — Bonuri fiscale
```
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"
```
### Flux date — Comenzi financiare
```
User → Comandă Telegram → handlers.py → API client → Backend API → Oracle DB → Formater → User
```
---
## Setup
### Configurare `.env`
```bash
# backend/.env sau backend/.env.test
MODULE_TELEGRAM_ENABLED=true
TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather
```
### Pornire
```bash
./start.sh prod # Pornește tot (backend + frontend + bot)
./start.sh test # Mod test (conexiune Oracle directă, fără SSH tunnel)
```
Botul pornește automat ca background task când `MODULE_TELEGRAM_ENABLED=true`.
> **Important:** Backend-ul trebuie rulat cu `--workers 1`. Vezi `docs/telegram/DEPLOYMENT.md`.
---
## Comenzi disponibile
| 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 |
### Bonuri fiscale (fără comandă explicită)
Trimite direct un **fișier PDF** sau o **fotografie** a bonului fiscal → botul pornește automat fluxul OCR.
---
## Autentificare
### Metoda 1: Deep Link (recomandat)
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
### Metoda 2: QR Code (cross-device)
1. Login pe desktop → `/telegram` → "Generează Cod"
2. Scanează QR Code-ul afișat cu Telegram pe mobil
3. Gata
### Metoda 3: Manual
1. Login → `/telegram` → "Generează Cod" → copiază codul
2. Trimite codul la bot (ex: `ABC123XY`)
**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
---
## Bonuri fiscale — detalii tehnice
### OCR Pipeline
- **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)
### Scriere Oracle
- 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)
### Câmpuri extrase de OCR → preview Telegram
| 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 |
---
## Teste
```bash
# 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
```
**Stare teste (la merge):** 48 pass + 2 skipped (real DB, rulează cu env vars).
---
## Troubleshooting
### Botul nu răspunde
- Verifică log: `tail -f /tmp/unified_backend_test.log`
- Verifică `MODULE_TELEGRAM_ENABLED=true` în `.env`
- Backend rulează cu `--workers 1`?
### OCR eșuat / timeout
- 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
### Oracle write eșuat
- `ORA-01017`: credențiale incorecte — verifică `backend/secrets/<server_id>.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
### SSH Tunnel warnings (inofensive în test)
```
[SSH-MONITOR] [vending] FAIL — Restart failed (code 1)
```
Normal în modul test dacă `sshpass` nu e instalat. Nu afectează funcționalitatea.