Conversation
- docs/SETUP.md: correct RESUME_PARSE_MODE default (queue, not queue-and-inline) and document JOB_RUNNER=inline behavior without workers - sign-in.test.ts: regression test proving lookalike/subdomain emails are rejected by the AUTH_ALLOWED_EMAIL_DOMAIN gate (endsWith(@ + domain) anchors on the @ separator, so no bypass exists) - dispatch.test.ts: test documenting that inline admin fan-out is fire-and-forget — send failures land in EmailLog, not the returned result
The dev credentials provider (any email -> ADMIN) was registered whenever Google OAuth credentials were missing, which left admin sign-in wide open on deployments without AUTH_GOOGLE_* set. It is now restricted to NODE_ENV=development, with an explicit ALLOW_DEV_LOGIN=1 escape hatch for local production-build smoke tests. Also on the signin page: - hide the Google button when OAuth is not configured (clicking it previously bounced through /api/auth/signin back to /signin with no feedback - the reported refresh loop) - surface NextAuth ?error= codes as a visible alert - show a clear notice when no sign-in method is available And accept .txt resumes end-to-end (upload guard, schema message, file input accept list); text extraction and inline preview already support plain text. Co-Authored-By: Claude <noreply@anthropic.com>
- Add loading.tsx fallbacks for every admin segment (shared AdminPageSkeleton), the public careers job page, and the root job board, so navigation shows immediate skeleton/branded loading states instead of a frozen screen while server components stream. - Add a shadcn-style Skeleton primitive. - RescoreButton: surface success/error via toast (failures were silently swallowed); RetryParsingButton: toast on success/failure in addition to the inline error text. Co-Authored-By: Claude <noreply@anthropic.com>
…tions fix(auth): never enable dev login on production deployments
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR integrates loading UI skeletons across admin and public routes, hardens dev login with explicit configuration, improves sign-in error handling and auth gating, expands resume uploads to support TXT files, adds toast feedback for async operations, and includes test coverage and documentation updates. ChangesLoading UI, Auth, Features, and UX Improvements
🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly Related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/(admin)/admin/jobs/[id]/applicants/[applicantId]/_components/RetryParsingButton.tsx (1)
22-35:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHandle thrown fetch errors and stop refreshing after failed retries.
Line 24 can throw (network/offline), but this path is uncaught, so users may get no failure feedback. Also, after the non-OK branch, Line 34 still refreshes and can immediately clear the inline error set at Line 29.
Suggested patch
function handleRetry() { startTransition(async () => { setError(null); - const response = await fetch(`/api/admin/jobs/parse-retry/${applicantId}?mode=inline`, { - method: "POST", - }); - const body = (await response.json().catch(() => null)) as { error?: string } | null; - if (!response.ok) { - setError(body?.error ?? "Resume parsing failed."); - toast.error(body?.error ?? "Resume parsing failed."); - } else { - toast.success("Resume parsed. Refreshing applicant data…"); - } - router.refresh(); + try { + const response = await fetch(`/api/admin/jobs/parse-retry/${applicantId}?mode=inline`, { + method: "POST", + }); + const body = (await response.json().catch(() => null)) as { error?: string } | null; + if (!response.ok) { + const message = body?.error ?? "Resume parsing failed."; + setError(message); + toast.error(message); + return; + } + toast.success("Resume parsed. Refreshing applicant data…"); + router.refresh(); + } catch { + const message = "Resume parsing failed. Check your connection and try again."; + setError(message); + toast.error(message); + } }); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/`(admin)/admin/jobs/[id]/applicants/[applicantId]/_components/RetryParsingButton.tsx around lines 22 - 35, Wrap the network call in startTransition with a try/catch around the fetch/response parsing so thrown fetch errors are caught and handled by setError and toast.error (e.g., catch network/offline exceptions from the fetch and JSON parsing), and move the router.refresh call so it only runs on successful parsing (inside the response.ok branch) to avoid clearing inline error state after failures; update the logic in RetryParsingButton's startTransition handler (references: startTransition, setError, fetch(`/api/admin/jobs/parse-retry/${applicantId}?mode=inline`), toast.error, toast.success, router.refresh) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@src/app/`(admin)/admin/jobs/[id]/applicants/[applicantId]/_components/RetryParsingButton.tsx:
- Around line 22-35: Wrap the network call in startTransition with a try/catch
around the fetch/response parsing so thrown fetch errors are caught and handled
by setError and toast.error (e.g., catch network/offline exceptions from the
fetch and JSON parsing), and move the router.refresh call so it only runs on
successful parsing (inside the response.ok branch) to avoid clearing inline
error state after failures; update the logic in RetryParsingButton's
startTransition handler (references: startTransition, setError,
fetch(`/api/admin/jobs/parse-retry/${applicantId}?mode=inline`), toast.error,
toast.success, router.refresh) accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 03d92666-32f0-4f3b-8a8a-3e6423e8f49f
📒 Files selected for processing (29)
.env.exampledocs/SETUP.mddocs/session-reports/2026-06-11-resume-pipeline-oauth-emails.mdsrc/app/(admin)/_components/AdminPageSkeleton.tsxsrc/app/(admin)/admin/applicants/loading.tsxsrc/app/(admin)/admin/email-templates/loading.tsxsrc/app/(admin)/admin/integrations/loading.tsxsrc/app/(admin)/admin/jobs/[id]/applicants/[applicantId]/_components/RescoreButton.tsxsrc/app/(admin)/admin/jobs/[id]/applicants/[applicantId]/_components/RetryParsingButton.tsxsrc/app/(admin)/admin/jobs/[id]/applicants/[applicantId]/loading.tsxsrc/app/(admin)/admin/jobs/[id]/applicants/loading.tsxsrc/app/(admin)/admin/jobs/[id]/loading.tsxsrc/app/(admin)/admin/jobs/loading.tsxsrc/app/(admin)/admin/loading.tsxsrc/app/(admin)/admin/notifications/loading.tsxsrc/app/(admin)/admin/settings/loading.tsxsrc/app/(admin)/admin/templates/loading.tsxsrc/app/(public)/careers/[slug]/loading.tsxsrc/app/loading.tsxsrc/app/signin/_components/SignInForm.tsxsrc/app/signin/page.tsxsrc/components/public/ApplicationForm.tsxsrc/components/ui/skeleton.tsxsrc/lib/auth/auth.config.test.tssrc/lib/auth/auth.config.tssrc/lib/auth/sign-in.test.tssrc/lib/storage/upload-limits.tssrc/schemas/application.tssrc/server/jobs/dispatch.test.ts
Promotes the following to production:
Production env vars (AUTH_GOOGLE_*, RESEND_API_KEY, EMAIL_FROM, OPENROUTER_MODEL) have been set in Vercel.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation