"""Resolve storage from authenticated project metadata, never browser input.""" from uuid import UUID from fastapi import HTTPException from psycopg import ProgrammingError from psycopg.conninfo import conninfo_to_dict from sqlalchemy.exc import SQLAlchemyError from app.auth.project_dependencies import ( ProjectContext, resolve_project_business_routing, resolve_project_simulation_routing, ) from app.infra.db.metadb.repositories.metadata_repository import MetadataRepository from app.infra.db.project_routing import ActiveProjectRouting from .auth import Identity from .errors import SampleFailure, ensure async def resolve_store_routing( who: Identity, repository: MetadataRepository, *, timeseries: bool = False, ) -> ActiveProjectRouting: context = ProjectContext( project_id=UUID(who.project_id), project_code=who.project_code, user_id=UUID(who.user_id), project_role="", ) try: resolver = resolve_project_simulation_routing if timeseries else resolve_project_business_routing routing = await resolver(context, repository) dsns = [routing.business_dsn] + ([routing.timescale_dsn] if timeseries else []) ensure(all(dsn and conninfo_to_dict(dsn).get("dbname") for dsn in dsns), "PROJECT_STORAGE_NOT_CONFIGURED", "项目数据库名称尚未配置", 503) return routing except (HTTPException, SQLAlchemyError, ValueError, ProgrammingError) as exc: raise SampleFailure( "PROJECT_STORAGE_NOT_CONFIGURED", "项目数据库路由不可用或尚未配置", 503, ) from exc