Files
roa2web-service-auto/backend/config.py
Claude Agent dd4b90f922 feat(financial-indicators): Complete Financial Indicators Dashboard Card
Implementare completă a card-ului Indicatori Financiari în Dashboard Solduri:

Backend:
- Model FinancialIndicators cu 22+ indicatori organizați pe categorii
- Service cu calcule din VBAL (Lichiditate, Eficiență, Risc, Cash Flow, Dinamică)
- Altman Z-Score cu toate componentele (X1-X4) și valori absolute
- Profitabilitate cu ROA, ROE, Cifra Afaceri, Cheltuieli separate (operaționale/financiare)
- Caching inteligent pe company_id, luna, an

Frontend:
- FinancialIndicatorsCard.vue cu 4 indicatori principali collapsed
- Expanded view grupat pe categorii (desktop + mobile BottomSheet)
- Subindicatori pentru verificare manuală în balanță
- Traduceri complete în română
- Dark mode support complet
- Sparklines cu tooltips
- Responsive design (desktop grid + mobile carousel)

Documentație:
- PRD complet cu specificații și formule
- Descrieri cu conturi din planul contabil român (OMFP 1802/2014)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 17:32:48 +00:00

178 lines
6.5 KiB
Python

"""
Unified Configuration for ROA2WEB Backend
Consolidates settings from Reports, Data Entry, and Telegram modules
"""
import os
from pathlib import Path
from typing import List
from pydantic_settings import BaseSettings
from functools import lru_cache
class UnifiedSettings(BaseSettings):
"""Unified application settings for all modules."""
# ============================================================================
# GENERAL APPLICATION SETTINGS
# ============================================================================
app_name: str = "ROA2WEB Unified Backend"
app_version: str = "1.0.0"
debug: bool = False
api_host: str = "0.0.0.0"
api_port: int = 8000
# ============================================================================
# ORACLE DATABASE (Shared by all modules)
# ============================================================================
oracle_user: str = ""
oracle_password: str = ""
oracle_host: str = "localhost"
oracle_port: int = 1526
oracle_sid: str = "ROA"
# ============================================================================
# JWT AUTHENTICATION (Shared by all modules)
# ============================================================================
jwt_secret_key: str = "change-me-in-production"
jwt_algorithm: str = "HS256"
access_token_expire_minutes: int = 30
refresh_token_expire_days: int = 7
# ============================================================================
# SESSION SECURITY - EMAIL 2FA (Telegram module)
# ============================================================================
auth_session_secret: str = "change-me-in-production"
# ============================================================================
# CORS
# ============================================================================
cors_origins: str = "http://localhost:3000,http://localhost:5173"
# ============================================================================
# REPORTS MODULE - CACHE CONFIGURATION
# ============================================================================
reports_cache_enabled: bool = True
reports_cache_type: str = "hybrid"
reports_cache_sqlite_path: str = "./data/cache/roa2web_cache.db"
reports_cache_memory_max_size: int = 1000
reports_cache_default_ttl: int = 900
# Cache TTL per type (seconds)
reports_cache_ttl_schema: int = 86400
reports_cache_ttl_companies: int = 1800
reports_cache_ttl_dashboard_summary: int = 1800
reports_cache_ttl_dashboard_trends: int = 1800
reports_cache_ttl_invoices: int = 600
reports_cache_ttl_invoices_summary: int = 900
reports_cache_ttl_treasury: int = 600
# Cache maintenance
reports_cache_cleanup_interval: int = 3600
reports_cache_auto_invalidate: bool = False
reports_cache_check_interval: int = 300
reports_cache_track_performance: bool = True
reports_cache_benchmark_on_startup: bool = False
# ============================================================================
# DATA ENTRY MODULE - CONFIGURATION
# ============================================================================
data_entry_sqlite_database_path: str = "data/receipts/receipts.db"
data_entry_upload_path: str = "data/receipts/uploads"
data_entry_max_upload_size_mb: int = 10
data_entry_allowed_mime_types: List[str] = [
"image/jpeg",
"image/png",
"image/gif",
"image/webp",
"application/pdf",
]
# ============================================================================
# TELEGRAM MODULE - BOT CONFIGURATION
# ============================================================================
telegram_bot_token: str = ""
telegram_smtp_host: str = ""
telegram_smtp_port: int = 587
telegram_smtp_user: str = ""
telegram_smtp_password: str = ""
telegram_smtp_from_email: str = ""
telegram_smtp_from_name: str = "ROA2WEB"
telegram_smtp_use_tls: bool = True
telegram_email_max_retries: int = 3
telegram_email_retry_delay: float = 2.0
telegram_sqlite_database_path: str = "data/telegram/telegram.db"
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
extra = "ignore"
case_sensitive = False
# ============================================================================
# COMPUTED PROPERTIES
# ============================================================================
@property
def oracle_dsn(self) -> str:
"""Get Oracle DSN string."""
return f"{self.oracle_host}:{self.oracle_port}/{self.oracle_sid}"
@property
def cors_origins_list(self) -> List[str]:
"""Get CORS origins as list."""
return [origin.strip() for origin in self.cors_origins.split(",")]
# Data Entry properties
@property
def data_entry_database_url(self) -> str:
"""Get SQLite database URL for async (Data Entry)."""
# Resolve to absolute path for Windows/IIS compatibility
abs_path = Path(self.data_entry_sqlite_database_path).resolve()
return f"sqlite+aiosqlite:///{abs_path}"
@property
def data_entry_sync_database_url(self) -> str:
"""Get SQLite database URL for sync operations (Alembic)."""
# Resolve to absolute path for Windows/IIS compatibility
abs_path = Path(self.data_entry_sqlite_database_path).resolve()
return f"sqlite:///{abs_path}"
@property
def data_entry_upload_path_resolved(self) -> Path:
"""Get resolved upload path."""
path = Path(self.data_entry_upload_path)
path.mkdir(parents=True, exist_ok=True)
return path
@property
def data_entry_max_upload_size_bytes(self) -> int:
"""Get max upload size in bytes."""
return self.data_entry_max_upload_size_mb * 1024 * 1024
# Reports cache properties
@property
def reports_cache_sqlite_path_resolved(self) -> Path:
"""Get resolved cache SQLite path."""
path = Path(self.reports_cache_sqlite_path)
path.parent.mkdir(parents=True, exist_ok=True)
return path
# Telegram properties
@property
def telegram_sqlite_path_resolved(self) -> Path:
"""Get resolved Telegram SQLite path."""
path = Path(self.telegram_sqlite_database_path)
path.parent.mkdir(parents=True, exist_ok=True)
return path
@lru_cache()
def get_settings() -> UnifiedSettings:
"""Get cached settings instance."""
return UnifiedSettings()
# Convenience instance
settings = get_settings()