feat(telegram): bot bonuri fiscale — OCR → preview → Oracle write

- US-001: mută queue_client.py în data_entry/services/ocr/
- US-002/003/004: oracle_receipt_writer + oracle_server_id în DB
- US-005: receipt_handlers.py (PDF/photo/callback flow)
- US-006: wire handlers în main.py, per-schema connect, seq_cod.nextval
- US-007: .gitignore secrets/*.oracle_pass
- US-008/009/010: teste unit + integration + E2E
- setup-secrets.sh helper + template
- docs/telegram/README.md actualizat cu arhitectura nouă

Testat E2E pe DB live (MARIUSM_AUTO). COD din seq_cod.nextval.
pypdfium2 fallback pentru PDF decode (fără poppler).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 09:26:58 +00:00
parent 8234103884
commit e257fa5d5f
35 changed files with 4531 additions and 227 deletions

View File

@@ -314,9 +314,38 @@ async def run_telegram_bot():
error_handler
)
from backend.modules.telegram.bot.email_handlers import email_login_handler
# US-006: Receipt OCR flow handlers
from backend.modules.telegram.handlers.receipt_handlers import (
handle_document_message,
handle_photo_message,
handle_receipt_callback,
)
# Create Telegram application
application = Application.builder().token(settings.telegram_bot_token).build()
# US-006: Sweep orphan receipt temp files left over from a previous crash.
# Receipt OCR flow writes /tmp/receipt_*.* and unlinks them after
# confirm/cancel; if the bot died in between, those files remain on disk.
import glob as _glob
try:
orphans = 0
for _path_str in _glob.glob('/tmp/receipt_*.*'):
try:
Path(_path_str).unlink(missing_ok=True)
orphans += 1
except OSError as _e:
logger.warning(f"[TELEGRAM] Failed to unlink orphan {_path_str}: {_e}")
if orphans:
logger.info(f"[TELEGRAM] 🧹 Cleaned up {orphans} orphan receipt temp files")
except Exception as e:
logger.warning(f"[TELEGRAM] ⚠️ Receipt orphan cleanup failed (non-critical): {e}")
# Create Telegram application with concurrent_updates so multiple users
# can use the bot in parallel (e.g. two users uploading receipts at once).
application = (
Application.builder()
.token(settings.telegram_bot_token)
.concurrent_updates(True)
.build()
)
# Register handlers
application.add_handler(email_login_handler)
@@ -339,6 +368,20 @@ async def run_telegram_bot():
application.add_handler(CommandHandler("clearcache", clearcache_command))
application.add_handler(CommandHandler("togglecache", togglecache_command))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text_message))
# US-006: Receipt OCR handlers (PDF/JPG fiscal receipt flow).
# The receipt CallbackQueryHandler MUST be registered BEFORE the catch-all
# button_callback so `receipt:*` callbacks are routed correctly.
application.add_handler(MessageHandler(
filters.Document.PDF | filters.Document.IMAGE,
handle_document_message
))
application.add_handler(MessageHandler(filters.PHOTO, handle_photo_message))
application.add_handler(CallbackQueryHandler(
handle_receipt_callback,
pattern=r'^receipt:'
))
application.add_handler(CallbackQueryHandler(button_callback))
application.add_error_handler(error_handler)