fix(backend): harden bulk endpoints and redact pdf-queue email for non-admins

- W1: _parse_ids_param now returns 400 on non-integer input instead of 500
- W2: bulk_delete_scholars wraps commit in IntegrityError guard; router
  catches ScholarServiceError → 409
- W3: Move `from typing import Any` to top-level import in application.py
- W4: Redact requested_by_email in PDF queue response for non-admin users
This commit is contained in:
Justin Visser 2026-03-07 17:57:37 +01:00
parent c85fa08b7b
commit f8e3098fc3
3 changed files with 30 additions and 13 deletions

View file

@ -51,7 +51,14 @@ def _parse_ids_param(ids: str | None) -> list[int] | None:
parts = [p.strip() for p in ids.split(",") if p.strip()]
if not parts:
return None
return [int(p) for p in parts]
try:
return [int(p) for p in parts]
except ValueError:
raise ApiException(
status_code=400,
code="invalid_ids_param",
message="The 'ids' parameter must be a comma-separated list of integers.",
)
@router.get(
@ -104,12 +111,19 @@ async def bulk_delete_scholars(
db_session: AsyncSession = Depends(get_db_session),
current_user: User = Depends(get_api_current_user),
):
deleted_count = await scholar_service.bulk_delete_scholars(
db_session,
user_id=current_user.id,
scholar_profile_ids=payload.scholar_profile_ids,
upload_dir=settings.scholar_image_upload_dir,
)
try:
deleted_count = await scholar_service.bulk_delete_scholars(
db_session,
user_id=current_user.id,
scholar_profile_ids=payload.scholar_profile_ids,
upload_dir=settings.scholar_image_upload_dir,
)
except scholar_service.ScholarServiceError as exc:
raise ApiException(
status_code=409,
code="scholar_bulk_delete_failed",
message=str(exc),
) from exc
structured_log(
logger,
"info",