From 65bdefadc7fdbec56819c5141311fd9bfe46d3fc Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Sivakumar Date: Thu, 30 Jul 2026 21:53:06 +0530 Subject: [PATCH] Fix job seeker submission failing: wrong API prefix and missing auth header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit job-seeker-custom-data.ts hit /api/gateway/jobseeker/profile/me — a prefix that never existed in production (see the comment in lib/api.ts, which every other authenticated call already follows); it 404s against the real ingress, which routes /api/* straight to the gateway. Its local apiFetch also never sent an Authorization header, which AuthUser requires (no cookie fallback), so even the corrected path would 401. This is why RoleWizard's submit flow broke for JOB_SEEKER specifically: handleSubmit() calls savePortfolio() first, which calls updateJobSeekerCustomData() (JOB_SEEKER's portfolioModel is "custom_data"), which threw on the failed fetch and aborted the whole submission before the actual profile PATCH or submit-for-verification call ever ran. Confirmed against production: verifications has 5 rows for COMPANY, 1 for PHOTOGRAPHER, 0 for JOB_SEEKER ever, despite a job seeker having fully filled out the wizard (including an uploaded document) days ago. Same file backs readJobSeekerProfile/updateJobSeekerCustomData used by PortfolioPage, JobSeekerJobsPage, and JobSeekerSavedJobsPage too — all four were broken the same way. Co-Authored-By: Claude Sonnet 5 --- src/lib/job-seeker-custom-data.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/lib/job-seeker-custom-data.ts b/src/lib/job-seeker-custom-data.ts index 0119efa..32d0b32 100644 --- a/src/lib/job-seeker-custom-data.ts +++ b/src/lib/job-seeker-custom-data.ts @@ -1,5 +1,3 @@ -const API = '/api/gateway'; - export type JobSeekerProfile = { id: string; user_id: string; @@ -14,12 +12,26 @@ export type JobSeekerProfile = { custom_data?: Record | null; }; +// The K8s ingress routes any /api/* path directly to the Rust gateway service — +// there is no /api/gateway indirection in production (see ~/lib/api.ts). Hit +// the path as-is, and send the same Authorization bearer token every other +// authenticated call uses — AuthUser on the backend only reads that header, +// there is no cookie-based fallback. +function getAuthHeaders(): Record { + const token = typeof window !== 'undefined' + ? (sessionStorage.getItem('nxtgauge_access_token') || '') + : ''; + return { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }; +} + async function apiFetch(path: string, opts?: RequestInit) { - const cleanPath = path.startsWith('/api/') ? path.slice(4) : path; - return fetch(`${API}${cleanPath}`, { + return fetch(path, { ...opts, credentials: 'include', - headers: { 'Content-Type': 'application/json', ...(opts?.headers ?? {}) }, + headers: { ...getAuthHeaders(), ...(opts?.headers ?? {}) }, }); }