Three bugs fixed:
1. api/jobs.ts: remove manual Content-Type header on FormData upload.
Setting it without the multipart boundary caused Quart to reject the
request body — the root cause of brief upload failures.
2. progress.py: include full job.to_dict() in job.progress / job.completed
/ job.failed WebSocket messages. Frontend checks msg.job to call
updateJob() — without it, job cards never updated in real-time.
3. AppShell: move useWebSocket() here from BriefUploadPage so the WS
connection persists across all pages, not just the upload page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- msal_auth.py: replace verify_signature=False with real JWKS verification
using PyJWKClient; validates RS256 signature, aud=clientId, issuer v2.0
- App.tsx: split DEV bypass from empty-accounts case — in production,
accounts.length === 0 now correctly triggers loginRedirect instead of
calling fetchMe without a token
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>