{"version":3,"file":"addFormApi-BS1h8DDO.cjs","names":[],"sources":["../src/services/addFormApi.js"],"sourcesContent":["import { ensureToken, fetchJsonWithAuth } from './authApi';\nimport { AUTH_URL, JOBS_URL } from './apiConfig';\nimport { fetchFormGroupsCached, invalidateFormGroupsCache } from './formGroupsCache';\n\n// ── Form Groups ───────────────────────────────────────────────────────────────\n\nfunction extractFormGroups(json) {\n  const payload = json?.data ?? json;\n  if (Array.isArray(payload)) return payload;\n  if (Array.isArray(payload?.groups)) return payload.groups;\n  if (Array.isArray(json?.groups)) return json.groups;\n  return [];\n}\n\n/**\n * formGroupsUrl — the canonical URL for one form-groups query. Built in a fixed\n * parameter order so two callers asking the same question produce the same\n * string, which is what makes them shareable (see formGroupsCache).\n */\nfunction formGroupsUrl({ module, id, action, clientId, region, group, view } = {}) {\n  const params = new URLSearchParams({ module });\n  if (id) params.set('id', id);\n  if (action) params.set('action', action);\n  if (clientId) params.set('clientId', clientId);\n  if (region) params.set('region', region);\n  if (group) params.set('group', group);\n  if (view) params.set('view', view);\n  return `${AUTH_URL}/admin/form-groups?${params.toString()}`;\n}\n\n/**\n * fetchFormGroupsPayload — the RAW payload for one query, shared between every\n * caller that asks for it (see formGroupsCache for why). Returns the whole\n * envelope, so a caller that needs `recordMeta` and one that needs only the\n * groups array still cost ONE request between them.\n */\nexport async function fetchFormGroupsPayload(options = {}) {\n  if (!options.module) throw new Error('module is required to fetch form groups');\n  const url = formGroupsUrl(options);\n  return fetchFormGroupsCached(url, async () => {\n    const token = await ensureToken();\n    const res = await fetch(url, {\n      method: 'GET',\n      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n    });\n    if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n    return res.json();\n  });\n}\n\nexport async function getFormGroups(options = {}) {\n  return extractFormGroups(await fetchFormGroupsPayload(options));\n}\n\nexport async function getCandidateFormGroups(options = {}) {\n  return getFormGroups({ module: 'candidates', ...options });\n}\n\nexport async function getMentionUsers(search = '') {\n  const { apiGetWithAuth } = await import('./authApi');\n  const params = search ? `?search=${encodeURIComponent(search)}` : '';\n  return apiGetWithAuth(JOBS_URL, `/users/any${params}`);\n}\n\n// ── Create Records ────────────────────────────────────────────────────────────\n// Routes through the Auth gateway which injects tenant context from JWT\n// and proxies to the correct downstream service based on module name.\n\nexport async function createModuleRecord(moduleName, formData) {\n  // ensureToken (not getStoredToken) so a missing/expired session throws a\n  // clear \"Authentication required\" error instead of silently sending the\n  // request with no Authorization header (which the gateway rejects as 401).\n  // NOTE: do NOT set Content-Type here — the browser must add the multipart\n  // boundary itself. Only the Authorization header is set manually.\n  const token = await ensureToken();\n\n  const res = await fetch(\n    `${AUTH_URL}/module/create?module=${encodeURIComponent(moduleName)}`,\n    { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: formData },\n  );\n\n  const { logout } = await import('./authApi');\n  if (res.status === 401) logout();\n\n  // A save is exactly the moment a cached form-groups payload stops describing\n  // the record — invalidate before the caller can navigate and read one back.\n  invalidateFormGroupsCache();\n\n  const contentType = res.headers.get('content-type') || '';\n  const data = contentType.includes('application/json') ? await res.json() : await res.text();\n\n  if (!res.ok) {\n    const error = new Error(data?.error || data?.message || `API ${res.status}: ${res.statusText}`);\n    error.status = res.status;\n    error.data = data;\n    throw error;\n  }\n\n  return data;\n}\n"],"mappings":"0NAMA,SAAS,EAAkB,EAAM,CAC/B,IAAM,EAAU,GAAM,MAAQ,EAI9B,OAHI,MAAM,QAAQ,CAAO,EAAU,EAC/B,MAAM,QAAQ,GAAS,MAAM,EAAU,EAAQ,OAC/C,MAAM,QAAQ,GAAM,MAAM,EAAU,EAAK,OACtC,CAAC,CACV,CAOA,SAAS,EAAc,CAAE,SAAQ,KAAI,SAAQ,WAAU,SAAQ,QAAO,QAAS,CAAC,EAAG,CACjF,IAAM,EAAS,IAAI,gBAAgB,CAAE,QAAO,CAAC,EAO7C,OANI,GAAI,EAAO,IAAI,KAAM,CAAE,EACvB,GAAQ,EAAO,IAAI,SAAU,CAAM,EACnC,GAAU,EAAO,IAAI,WAAY,CAAQ,EACzC,GAAQ,EAAO,IAAI,SAAU,CAAM,EACnC,GAAO,EAAO,IAAI,QAAS,CAAK,EAChC,GAAM,EAAO,IAAI,OAAQ,CAAI,EAC1B,GAAG,EAAA,EAAS,qBAAqB,EAAO,SAAS,GAC1D,CAQA,eAAsB,EAAuB,EAAU,CAAC,EAAG,CACzD,GAAI,CAAC,EAAQ,OAAQ,MAAU,MAAM,yCAAyC,EAC9E,IAAM,EAAM,EAAc,CAAO,EACjC,OAAO,EAAA,EAAsB,EAAK,SAAY,CAC5C,IAAM,EAAQ,MAAM,EAAA,EAAY,EAC1B,EAAM,MAAM,MAAM,EAAK,CAC3B,OAAQ,MACR,QAAS,CAAE,eAAgB,mBAAoB,cAAe,UAAU,GAAQ,CAClF,CAAC,EACD,GAAI,CAAC,EAAI,GAAI,MAAU,MAAM,OAAO,EAAI,OAAO,IAAI,EAAI,YAAY,EACnE,OAAO,EAAI,KAAK,CAClB,CAAC,CACH,CAEA,eAAsB,EAAc,EAAU,CAAC,EAAG,CAChD,OAAO,EAAkB,MAAM,EAAuB,CAAO,CAAC,CAChE,CAgBA,eAAsB,EAAmB,EAAY,EAAU,CAM7D,IAAM,EAAQ,MAAM,EAAA,EAAY,EAE1B,EAAM,MAAM,MAChB,GAAG,EAAA,EAAS,wBAAwB,mBAAmB,CAAU,IACjE,CAAE,OAAQ,OAAQ,QAAS,CAAE,cAAe,UAAU,GAAQ,EAAG,KAAM,CAAS,CAClF,EAEM,CAAE,UAAW,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,KAAA,GAAA,EAAA,CAAA,EACrB,EAAI,SAAW,KAAK,EAAO,EAI/B,EAAA,EAA0B,EAG1B,IAAM,GADc,EAAI,QAAQ,IAAI,cAAc,GAAK,GAAA,CAC9B,SAAS,kBAAkB,EAAI,MAAM,EAAI,KAAK,EAAI,MAAM,EAAI,KAAK,EAE1F,GAAI,CAAC,EAAI,GAAI,CACX,IAAM,EAAY,MAAM,GAAM,OAAS,GAAM,SAAW,OAAO,EAAI,OAAO,IAAI,EAAI,YAAY,EAG9F,KAFA,GAAM,OAAS,EAAI,OACnB,EAAM,KAAO,EACP,CACR,CAEA,OAAO,CACT"}