--- paths: {reports-app,data-entry-app}/backend/**/*.py --- # Backend Patterns ## Router Factory Pattern Use shared router factories instead of custom implementations: ```python from shared.routes.companies import create_companies_router from shared.routes.calendar import create_calendar_router companies_router = create_companies_router(oracle_pool, cache_decorator=cached) app.include_router(companies_router, prefix="/api/companies") ``` ## Database Queries - All queries use parameterized Oracle queries (no SQL injection) - Schema lookup: `SELECT SCHEMA FROM CONTAFIN_ORACLE.V_NOM_FIRME` - Company access: Join V_NOM_FIRME with VDEF_UTIL_FIRME ## Caching (reports-app) - Use `@cached` decorator from `app/cache/decorators` - Place logic in services, not routers - Cache schema lookups (24h TTL) - Cache user data (10-30 min TTL) ## Error Handling ```python try: # Business logic except HTTPException: raise # Re-raise HTTP exceptions except Exception as e: logger.error(...) raise HTTPException(500, "Internal error") ``` ## Oracle Pool Pattern ```python async with oracle_pool.get_connection() as connection: with connection.cursor() as cursor: cursor.execute(query, params) ```