mirror of
https://github.com/marcogll/telegram_expenses_controller.git
synced 2026-01-13 13:25:15 +00:00
feat: translate comments, docstrings, and log messages to Spanish.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Main application router.
|
||||
Enrutador principal de la aplicación.
|
||||
|
||||
Orchestrates the entire expense processing workflow, from input to persistence.
|
||||
Orquesta todo el flujo de trabajo de procesamiento de gastos, desde la entrada hasta la persistencia.
|
||||
"""
|
||||
import logging
|
||||
|
||||
@@ -16,55 +16,55 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
def process_expense_input(db: Session, raw_input: RawInput) -> FinalExpense:
|
||||
"""
|
||||
Full pipeline for processing a raw input.
|
||||
Pipeline completo para procesar una entrada sin procesar.
|
||||
|
||||
1. Ingestion: Convert input (text, image, etc.) to raw text.
|
||||
2. AI Extraction: Parse the raw text into structured data.
|
||||
3. AI Classification/Audit: Validate and categorize the expense.
|
||||
4. Persistence: Save the final, confirmed expense to the database.
|
||||
1. Ingestión: Convertir la entrada (texto, imagen, etc.) en texto sin procesar.
|
||||
2. Extracción por IA: Analizar el texto sin procesar en datos estructurados.
|
||||
3. Clasificación/Auditoría por IA: Validar y categorizar el gasto.
|
||||
4. Persistencia: Guardar el gasto final confirmado en la base de datos.
|
||||
"""
|
||||
logger.info(f"Router processing input for user {raw_input.user_id} of type {raw_input.input_type}")
|
||||
logger.info(f"El enrutador está procesando la entrada para el usuario {raw_input.user_id} de tipo {raw_input.input_type}")
|
||||
|
||||
# 1. Ingestion
|
||||
# 1. Ingestión
|
||||
raw_text = ""
|
||||
if raw_input.input_type == "text":
|
||||
raw_text = text.process_text_input(raw_input.data)
|
||||
elif raw_input.input_type == "image":
|
||||
# In a real app, data would be bytes, not a string path
|
||||
# En una aplicación real, los datos serían bytes, no una ruta de cadena
|
||||
raw_text = image.process_image_input(raw_input.data.encode())
|
||||
elif raw_input.input_type == "audio":
|
||||
raw_text = audio.process_audio_input(raw_input.data.encode())
|
||||
elif raw_input.input_type == "document":
|
||||
raw_text = document.process_document_input(raw_input.data.encode())
|
||||
else:
|
||||
raise ValueError(f"Unsupported input type: {raw_input.input_type}")
|
||||
raise ValueError(f"Tipo de entrada no soportado: {raw_input.input_type}")
|
||||
|
||||
if not raw_text:
|
||||
logger.error("Ingestion phase resulted in empty text. Aborting.")
|
||||
# We might want to return a specific status here
|
||||
logger.error("La fase de ingestión resultó en un texto vacío. Abortando.")
|
||||
# Podríamos querer devolver un estado específico aquí
|
||||
return None
|
||||
|
||||
# 2. AI Extraction
|
||||
# 2. Extracción por IA
|
||||
extracted_data = extractor.extract_expense_data(raw_text)
|
||||
if not extracted_data.amount or not extracted_data.description:
|
||||
logger.error("AI extraction failed to find key details. Aborting.")
|
||||
logger.error("La extracción por IA no pudo encontrar detalles clave. Abortando.")
|
||||
return None
|
||||
|
||||
# 3. AI Classification & Confirmation (simplified)
|
||||
# In a real bot, you would present this to the user for confirmation.
|
||||
# 3. Clasificación y Confirmación por IA (simplificado)
|
||||
# En un bot real, presentarías esto al usuario para su confirmación.
|
||||
provisional_expense = ProvisionalExpense(
|
||||
user_id=raw_input.user_id,
|
||||
extracted_data=extracted_data,
|
||||
confidence_score=0.0 # Will be set by classifier
|
||||
confidence_score=0.0 # Será establecido por el clasificador
|
||||
)
|
||||
|
||||
audited_expense = classifier.classify_and_audit(provisional_expense)
|
||||
|
||||
# 3.5 Deterministic Matching (Phase 3)
|
||||
# Enrich data with categories from providers/keywords if available
|
||||
# 3.5 Coincidencia Determinística (Fase 3)
|
||||
# Enriquecer los datos con categorías de proveedores/palabras clave si están disponibles
|
||||
match_metadata = matcher.get_metadata_from_match(extracted_data.description)
|
||||
|
||||
# For now, we auto-confirm if confidence is high.
|
||||
# Por ahora, auto-confirmamos si la confianza es alta.
|
||||
if audited_expense.confidence_score > 0.7:
|
||||
final_expense = FinalExpense(
|
||||
user_id=audited_expense.user_id,
|
||||
@@ -79,12 +79,12 @@ def process_expense_input(db: Session, raw_input: RawInput) -> FinalExpense:
|
||||
confirmed_by="auto-confirm"
|
||||
)
|
||||
|
||||
# 4. Persistence
|
||||
# 4. Persistencia
|
||||
db_record = repositories.save_final_expense(db, final_expense)
|
||||
logger.info(f"Successfully processed and saved expense ID {db_record.id}")
|
||||
logger.info(f"Gasto procesado y guardado con éxito ID {db_record.id}")
|
||||
return db_record
|
||||
|
||||
else:
|
||||
logger.warning(f"Expense for user {raw_input.user_id} has low confidence. Awaiting manual confirmation.")
|
||||
# Here you would store the provisional expense and notify the user
|
||||
logger.warning(f"El gasto para el usuario {raw_input.user_id} tiene baja confianza. Esperando confirmación manual.")
|
||||
# Aquí guardarías el gasto provisional y notificarías al usuario
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user