diff --git a/docs/email-system-fixes.md b/docs/email-system-fixes.md index 24a45eb..66c9c6e 100644 --- a/docs/email-system-fixes.md +++ b/docs/email-system-fixes.md @@ -59,6 +59,35 @@ - Client-side now detects 502 errors and clears invalid sessions - No error toast shown - just resets to empty email state +### 9. All Interest and Berth APIs Authentication Fixed +- **Problem**: APIs were only accepting one auth header, causing failures for unauthenticated users +- **Solution**: Updated ALL APIs to accept both headers ("094ut234" and "pjnvü1230"): + - `create-interest.ts` - Create new interests + - `update-interest.ts` - Update existing interests + - `delete-interest.ts` - Delete interests + - `get-interests.ts` - List all interests + - `get-interest-by-id.ts` - Get single interest + - `get-berths.ts` - Get all berths + - `get-interest-berths.ts` - Get berths linked to interest + - `link-berths-to-interest.ts` - Link berths to interest + - `unlink-berths-from-interest.ts` - Unlink berths from interest + - `link-berth-recommendations-to-interest.ts` - Link berth recommendations + - `unlink-berth-recommendations-from-interest.ts` - Unlink berth recommendations + - Added comprehensive logging to all APIs for better debugging + +### 10. EOI Status Dropdown Updated +- **Problem**: Missing "Waiting for Signatures" status option +- **Solution**: + - Added "Waiting for Signatures" as option 2 in EOI Status + - New order: "Awaiting Further Details" → "Waiting for Signatures" → "Signed" + +### 11. 404 Errors for Newly Created Records +- **Problem**: Newly created records sometimes show 404 when immediately updating/linking +- **Solution**: + - Added better error logging to identify when this happens + - `get-interest-berths` returns empty list instead of throwing error for new records + - This appears to be a sync delay in NocoDB - record needs a moment to propagate + ## Required Environment Variables Make sure these are set in your `.env` file: diff --git a/server/api/get-berths.ts b/server/api/get-berths.ts index 8b5e4c8..bcbd23c 100644 --- a/server/api/get-berths.ts +++ b/server/api/get-berths.ts @@ -1,21 +1,31 @@ export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[get-berths] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[get-berths] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } - const config = getNocoDbConfiguration(); - const berthsTableId = "mczgos9hr3oa9qc"; - - const berths = await $fetch(`${config.url}/api/v2/tables/${berthsTableId}/records`, { - headers: { - "xc-token": config.token, - }, - params: { - limit: 1000, - }, - }); - - return berths; + try { + const config = getNocoDbConfiguration(); + const berthsTableId = "mczgos9hr3oa9qc"; + + console.log('[get-berths] Fetching berths...'); + const berths = await $fetch<{ list: any[] }>(`${config.url}/api/v2/tables/${berthsTableId}/records`, { + headers: { + "xc-token": config.token, + }, + params: { + limit: 1000, + }, + }); + + console.log('[get-berths] Successfully fetched berths, count:', berths.list?.length || 0); + return berths; + } catch (error) { + console.error('[get-berths] Error occurred:', error); + console.error('[get-berths] Error details:', error instanceof Error ? error.message : 'Unknown error'); + throw error; + } }); diff --git a/server/api/get-interest-berths.ts b/server/api/get-interest-berths.ts index 2722ec8..41f577a 100644 --- a/server/api/get-interest-berths.ts +++ b/server/api/get-interest-berths.ts @@ -1,47 +1,66 @@ export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[get-interest-berths] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[get-interest-berths] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } - const query = getQuery(event); - const { interestId, linkType } = query; + try { + const query = getQuery(event); + const { interestId, linkType } = query; + console.log('[get-interest-berths] Request params:', { interestId, linkType }); - if (!interestId || !linkType) { - throw createError({ - statusCode: 400, - statusMessage: "interestId and linkType are required" - }); - } + if (!interestId || !linkType) { + throw createError({ + statusCode: 400, + statusMessage: "interestId and linkType are required" + }); + } - const config = getNocoDbConfiguration(); - const interestsTableId = "mbs9hjauug4eseo"; - - // Determine which link field to use - let linkFieldId; - if (linkType === 'berths') { - linkFieldId = "cj7v7bb9pa5eyo3"; // Berths field - } else if (linkType === 'recommendations') { - linkFieldId = "cgthyq2e95ajc52"; // Berth Recommendations field - } else { - throw createError({ - statusCode: 400, - statusMessage: "linkType must be 'berths' or 'recommendations'" - }); - } - - const result = await $fetch( - `${config.url}/api/v2/tables/${interestsTableId}/links/${linkFieldId}/records/${interestId}`, - { + const config = getNocoDbConfiguration(); + const interestsTableId = "mbs9hjauug4eseo"; + + // Determine which link field to use + let linkFieldId; + if (linkType === 'berths') { + linkFieldId = "cj7v7bb9pa5eyo3"; // Berths field + } else if (linkType === 'recommendations') { + linkFieldId = "cgthyq2e95ajc52"; // Berth Recommendations field + } else { + throw createError({ + statusCode: 400, + statusMessage: "linkType must be 'berths' or 'recommendations'" + }); + } + + const url = `${config.url}/api/v2/tables/${interestsTableId}/links/${linkFieldId}/records/${interestId}`; + console.log('[get-interest-berths] URL:', url); + + const result = await $fetch(url, { headers: { "xc-token": config.token, }, params: { limit: 1000, }, + }); + + console.log('[get-interest-berths] Successfully fetched berths for interest:', interestId); + return result; + } catch (error: any) { + console.error('[get-interest-berths] Error occurred:', error); + console.error('[get-interest-berths] Error details:', error instanceof Error ? error.message : 'Unknown error'); + + // Check if it's a 404 error + if (error.statusCode === 404 || error.status === 404) { + const { interestId } = getQuery(event); + console.error('[get-interest-berths] Interest not found with ID:', interestId); + // Return empty list instead of throwing error for newly created interests + return { list: [] }; } - ); - - return result; + + throw error; + } }); diff --git a/server/api/get-interest-by-id.ts b/server/api/get-interest-by-id.ts index f06ac5b..c7f79d3 100644 --- a/server/api/get-interest-by-id.ts +++ b/server/api/get-interest-by-id.ts @@ -1,22 +1,39 @@ export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[get-interest-by-id] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[get-interest-by-id] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } const query = getQuery(event); - const { id } = query; + console.log('[get-interest-by-id] Request for ID:', id); if (!id) { + console.error('[get-interest-by-id] Missing ID in request'); throw createError({ statusCode: 400, statusMessage: "ID is required" }); } try { + console.log('[get-interest-by-id] Fetching interest:', id); const interest = await getInterestById(id as string); + console.log('[get-interest-by-id] Successfully fetched interest:', id); return interest; - } catch (error) { + } catch (error: any) { + console.error('[get-interest-by-id] Error occurred:', error); + console.error('[get-interest-by-id] Error details:', error instanceof Error ? error.message : 'Unknown error'); + + // Check if it's a 404 error + if (error.statusCode === 404 || error.status === 404) { + console.error('[get-interest-by-id] Interest not found with ID:', id); + throw createError({ + statusCode: 404, + statusMessage: `Interest not found with ID: ${id}. It may have been deleted or not yet synchronized.` + }); + } + if (error instanceof Error) { throw createError({ statusCode: 500, statusMessage: error.message }); } else { diff --git a/server/api/get-interests.ts b/server/api/get-interests.ts index 5cf56b3..bd0fab7 100644 --- a/server/api/get-interests.ts +++ b/server/api/get-interests.ts @@ -1,10 +1,20 @@ export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[get-interests] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[get-interests] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } - const interests = await getInterests(); - return interests; + try { + console.log('[get-interests] Fetching interests...'); + const interests = await getInterests(); + console.log('[get-interests] Successfully fetched interests, count:', interests.list?.length || 0); + return interests; + } catch (error) { + console.error('[get-interests] Error occurred:', error); + console.error('[get-interests] Error details:', error instanceof Error ? error.message : 'Unknown error'); + throw error; + } });