Backend QA Hardening: Admin, Mail, Document & Vendor Bug-Fix Cluster
Executive summary
A backend-only QA pass that clears a large bug backlog from the DSM issue sheet across the Admin, Mail, Document, Tenant, and Vendor areas, and adds a one-call XLSX export for selected mails. It makes bulk and select-all actions safer and image/non-PDF uploads no longer crash, improving reliability of day-to-day operations ahead of release.
Why this was needed
The QA bug sheet had accumulated dozens of backend defects: image uploads were forced through PDF parsing and could fail, password-reset links could degrade to a bare token when an env var was unset, role updates/deletes left orphaned records when the identity service was out of sync, and a select-all 'move to Processing' could push unassigned mail into an invalid state. Bulk payment-sync was also capped at 100 items and rejected select-all selections. These needed clearing to stabilize the build for promotion.
Client / user impact
- Image and other non-PDF documents upload cleanly without erroneous PDF page-count parsing.
- Select-all 'move to Processing' on mail now blocks up front with a clear list of unassigned items (HTTP 422) instead of failing mid-batch.
- Bulk payment-sync supports select-all with filters and removes the 100-item cap (de-duplicated, background-queued for large sets).
- New one-click XLSX export of selected mail using the same columns/permissions as the mail grid.
- Vendors can clear completed/failed upload tasks, and file details now expose the parent ZIP's mail id for navigation.
- Document-type counts and pagination flags restored; password-reset links are reliably built.
Technical scope
Grounded in the diff (23 files, +655/-107), notable changes:
- Documents (
document_service.py,documents.py): page-count only computed for true PDFs (by content-type/extension); S3 content-type defaults toapplication/octet-stream; dropped forcedapplication/pdfon presigned URLs. - Mail (
mails.py): select-all -> Processing preflight rejects unassigned mail withASSIGNMENT_REQUIRED(422) and a detailed list.mail_admin_actions_service.pyauto-creates the missing global Archived folder.mail_schemas.pyfixes decorator order on validators.mail_tasks.pynormalizes async failure detail. - Bulk/Sync (
documents_sync.py,bulk_selection_service.py,bulk_operations_schemas.py): typedBulkPaymentsSyncRequest, select-all +exclude_completedsupport, newSYNCoperation, 100-item cap removed with de-dup. - Downloads (
download_files.py): newPOST /api/v1/downloads/mails/bulk/xlsx; ZIP endpoints honorX-Workspace-Tenant-IDs. - Admin/Tenant (
admin_roles.py,admin_shared.py,tenant_management.py): role update/delete cleanup when IAM 404s, Subclientparent_id/tenant_type validation, department/contact delete error mapping. - Vendor (
vendor_files_*):clear-completedupload-tasks endpoint,parent_zip_mail_idfield. - Auth (
auth_service.py,iam_password_reset.py): reset link built from env template orFRONTEND_BASE_URL/BASE_URL, raising if unconfigured. Plus comment module-key normalization and contacts active-filter fix. Closes ~40 sheet issues; adds 13 unit regressions.
Risk & mitigation
Broad surface area (Admin, Mail, Document, Tenant, Vendor, Auth) raises regression risk, but changes are localized fixes with 13 added unit regressions plus QA scenario tests passing. Two behavioral changes warrant attention: the password-reset builder now raises if no URL template/base URL is configured (must verify env vars per environment), and the bulk-sync 100-item cap is removed (relies on the background-job threshold for large sets). Role delete is now a hard delete of related mappings.
QA validation focus
- Upload an image (PNG/JPG) and a non-PDF file as documents; confirm success and sensible page count.
- Select-all mail -> move to Processing with unassigned items; expect a 422 listing them, and success once assigned.
- Bulk payment-sync via select-all + filters, including >100 items; confirm de-dup and background job.
- Export selected mail to XLSX (
/downloads/mails/bulk/xlsx); verify columns/permissions match the grid. - Trigger a password reset across environments; confirm a valid link (and check env vars are set).
- Create a Subclient without parent_id (expect validation error); update/delete a role; delete departments/contacts.
- Vendor: clear completed/failed upload tasks; open file details and confirm parent ZIP mail navigation.