from fastapi import APIRouter, Header, HTTPException, Query from sqlalchemy.orm import Session from app.core.config import settings from app.db.models import ( SupportRoleAssignment, SupportUser, Workspace, WorkspaceChannelMapping, ) from app.db.session import get_db from fastapi import Depends router = APIRouter(prefix="/internal", tags=["internal"]) @router.get("/notification-recipients") def list_notification_recipients( project_id: int = Query(gt=0), channel_id: int = Query(gt=0), api_key: str | None = Header(default=None, alias="x-api-key"), db: Session = Depends(get_db), ) -> dict[str, object]: """Return project-scoped notification recipients to ABC API only. Secretary is the source of truth for workspace/project administrators. This endpoint is intentionally protected by the service API key and is not exposed through the public user-facing API contract. """ if not settings.master_api_key or api_key != settings.master_api_key: raise HTTPException(status_code=401, detail="internal service authentication failed") mapping = ( db.query(WorkspaceChannelMapping) .join(Workspace, Workspace.id == WorkspaceChannelMapping.workspace_id) .filter( WorkspaceChannelMapping.abc_project_id == project_id, WorkspaceChannelMapping.abc_channel_id == str(channel_id), WorkspaceChannelMapping.is_active.is_(True), Workspace.is_active.is_(True), Workspace.workspace_type == "SOFTWARE_APP", ) .order_by(WorkspaceChannelMapping.id.desc()) .first() ) if mapping is None: return {"items": []} assignments = ( db.query(SupportRoleAssignment) .join(SupportUser) .filter( SupportRoleAssignment.workspace_id == mapping.workspace_id, SupportRoleAssignment.role_code == "PROJECT_MANAGER", SupportRoleAssignment.support_user_id == SupportUser.id, SupportUser.status == "ACTIVE", SupportUser.email.is_not(None), ) .order_by(SupportRoleAssignment.id.asc()) .all() ) items = [] seen: set[str] = set() for assignment in assignments: email = (assignment.user.email or "").strip() normalized = email.lower() if not normalized or normalized in seen: continue seen.add(normalized) items.append({"email": email, "role": "PROJECT_ADMIN"}) return {"items": items}