mirror of
https://github.com/marcogll/telegram_expenses_controller.git
synced 2026-01-13 13:25:15 +00:00
This commit introduces the initial implementation of the input handler and Pydantic data models. - Adds `src/modules/input_handler.py` with text normalization and stubs for other input types. - Adds `src/data_models.py` with `RawInput`, `ExtractedExpense`, `ProvisionalExpense`, and `FinalExpense` models. - Integrates the new modules into the `/process-expense` endpoint in `src/main.py`. - Updates `tasks.md` to reflect the completion of these tasks.
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
from pydantic import BaseModel, Field
|
|
from typing import Optional, List
|
|
from datetime import datetime, date
|
|
|
|
class RawInput(BaseModel):
|
|
"""
|
|
Represents the raw data received from the input source (e.g., n8n).
|
|
"""
|
|
user_id: str
|
|
input_type: str = Field(..., alias="type", description="The type of input, e.g., 'text', 'voice', 'image', 'pdf'")
|
|
data: str
|
|
|
|
class ExtractedExpense(BaseModel):
|
|
"""
|
|
Represents an expense after initial data extraction (e.g., from OCR or transcription).
|
|
Fields are mostly optional as extraction may not be perfect.
|
|
"""
|
|
provider_name: Optional[str] = None
|
|
amount: Optional[float] = None
|
|
currency: Optional[str] = "MXN"
|
|
expense_date: Optional[date] = None
|
|
description: Optional[str] = None
|
|
raw_text: str
|
|
|
|
class ProvisionalExpense(BaseModel):
|
|
"""
|
|
Represents a fully processed but unconfirmed expense.
|
|
This is the state before the user validates the data.
|
|
"""
|
|
user_id: str
|
|
extracted_data: ExtractedExpense
|
|
|
|
# Classified fields
|
|
category: Optional[str] = "Por Determinar"
|
|
subcategory: Optional[str] = None
|
|
expense_type: Optional[str] = Field(None, alias="tipo_gasto_default", description="e.g., 'personal' or 'negocio'")
|
|
|
|
# Metadata
|
|
confidence_score: float
|
|
processing_method: str = Field(..., description="How the expense was classified, e.g., 'provider_match', 'keyword_match', 'ai_inference'")
|
|
validation_notes: List[str] = []
|
|
status: str = "AWAITING_CONFIRMATION"
|
|
timestamp: datetime = Field(default_factory=datetime.now)
|
|
|
|
class FinalExpense(BaseModel):
|
|
"""
|
|
Represents a final, user-confirmed expense record.
|
|
This is the data that will be stored permanently.
|
|
"""
|
|
user_id: str
|
|
provider_name: str
|
|
amount: float
|
|
currency: str
|
|
expense_date: date
|
|
description: Optional[str] = None
|
|
|
|
category: str
|
|
subcategory: Optional[str] = None
|
|
expense_type: str
|
|
|
|
# Audit trail
|
|
initial_processing_method: str
|
|
confirmed_by: str
|
|
confirmed_at: datetime = Field(default_factory=datetime.now)
|
|
audit_log: List[str] = []
|
|
|
|
status: str = "CONFIRMED"
|