feat(scholars): add multiselect and bulk actions #49

Open
JustinZeus wants to merge 7 commits from feat/scholar-multiselect-bulk-actions into main

7 commits

Author SHA1 Message Date
d1d0abeb11 fix(ci): fix mypy error in bulk_toggle_scholars
Use int(cursor.rowcount) instead of type: ignore comment.
2026-03-07 15:59:31 +01:00
587995a6bc fix(ci): fix ruff format in scholars router
Put each structured_log argument on its own line.
2026-03-07 15:56:40 +01:00
f3e94ec3f5 fix(test): add Pinia setup and admin user to AdminPdfQueueSection tests
The component uses useAuthStore() which requires an active Pinia
instance, and the "Queue all" button is admin-only (v-if="auth.isAdmin").
2026-03-07 15:51:49 +01:00
ef39ab6a41 fix(ci): fix import sorting, API contract, and pdf-queue test
- Add missing blank line after imports in application.py (ruff I001)
- Use full path string instead of template literal for export API call
  to avoid false positive in API contract drift check
- Update pdf-queue test to expect 200 for non-admin listing
2026-03-07 15:40:49 +01:00
7f78dd6353 feat(scholars): add multiselect and bulk actions (delete, toggle, export)
Add Set<number>-based selection state to ScholarsPage with checkboxes
in both table and card views, select-all toggle, and stale-key pruning.

Backend: POST /scholars/bulk-delete, POST /scholars/bulk-toggle, and
GET /scholars/export?ids= filter. Service functions use user-scoped
queries. Structured logging for bulk operations.

Frontend: useScholarBulkActions composable extracts selection and bulk
action logic. AppSelect-based action dropdown with dynamic options.
Delete prompts window.confirm; enable/disable applies immediately.
Export downloads filtered JSON.

Includes integration tests for all bulk endpoints and frontend unit
tests for selection toggle, select-all, and stale pruning.
2026-03-07 14:03:06 +01:00
6fa54db08f feat(settings): hours interval, pdf queue for all users, fix users tab loading
- Convert check interval setting from minutes to hours in the UI
- Show PDF queue tab to all authenticated users (not admin-only); requeue
  actions remain admin-only in both backend and frontend
- Fix users tab not loading on first visit by removing the AsyncStateGate
  wrapper that prevented child component refs from being populated before
  onMounted fired

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 13:53:20 +01:00
17727187fd feat(frontend): show run and cancel buttons to all users
Remove the auth.isAdmin guard from the Start check and Cancel check
buttons in the Activity Monitor. Admin-only route links (check history,
diagnostics) are unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 13:53:20 +01:00