Files
root 33453ecc55
Deploy staging / deploy (push) Failing after 6s
Initial deployment setup
2026-08-31 16:45:24 +09:00

75 lines
2.5 KiB
Python

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}