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

@ -57,7 +57,7 @@ def _requested_by_value(*, payload, admin_user: User) -> str:
return from_payload or admin_user.email
def _serialize_pdf_queue_item(item) -> dict[str, object]:
def _serialize_pdf_queue_item(item, *, is_admin: bool = False) -> dict[str, object]:
return {
"publication_id": item.publication_id,
"title": item.title,
@ -69,7 +69,7 @@ def _serialize_pdf_queue_item(item) -> dict[str, object]:
"last_failure_detail": item.last_failure_detail,
"last_source": item.last_source,
"requested_by_user_id": item.requested_by_user_id,
"requested_by_email": item.requested_by_email,
"requested_by_email": item.requested_by_email if is_admin else None,
"queued_at": item.queued_at,
"last_attempt_at": item.last_attempt_at,
"resolved_at": item.resolved_at,
@ -215,7 +215,7 @@ async def get_pdf_queue(
return success_payload(
request,
data={
"items": [_serialize_pdf_queue_item(item) for item in queue_page.items],
"items": [_serialize_pdf_queue_item(item, is_admin=current_user.is_admin) for item in queue_page.items],
**_pdf_queue_page_data(
total_count=queue_page.total_count,
page=resolved_page,