From 1866dfd01032ec9cbab5de77d59e6e584a5688ca Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 9 Jun 2025 23:19:52 +0200 Subject: [PATCH] Add debug logging and update API authentication - Add comprehensive logging to all interest API endpoints and NocoDB utilities - Update create-interest and delete-interest endpoints to accept additional x-tag value - Add missing imports for deleteInterest and updateInterest functions - Log request details, processing steps, and errors for better debugging --- server/api/create-interest.ts | 12 ++++- server/api/delete-interest.ts | 14 +++++- server/api/update-interest.ts | 14 ++++++ server/utils/nocodb.ts | 93 ++++++++++++++++++++++++++--------- utils/types.ts | 4 +- 5 files changed, 109 insertions(+), 28 deletions(-) diff --git a/server/api/create-interest.ts b/server/api/create-interest.ts index 1929cba..0b684a7 100644 --- a/server/api/create-interest.ts +++ b/server/api/create-interest.ts @@ -2,21 +2,31 @@ import { createInterest } from "../utils/nocodb"; export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[create-interest] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[create-interest] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } try { const body = await readBody(event); + console.log('[create-interest] Request body fields:', body ? Object.keys(body) : 'none'); if (!body || Object.keys(body).length === 0) { + console.error('[create-interest] No data provided'); throw createError({ statusCode: 400, statusMessage: "No data provided" }); } + console.log('[create-interest] Creating new interest with fields:', Object.keys(body)); const createdInterest = await createInterest(body); + console.log('[create-interest] Successfully created interest with ID:', createdInterest.Id); + return createdInterest; } catch (error) { + console.error('[create-interest] Error occurred:', error); + console.error('[create-interest] Error stack:', error instanceof Error ? error.stack : 'No stack trace'); + if (error instanceof Error) { throw createError({ statusCode: 500, statusMessage: error.message }); } else { diff --git a/server/api/delete-interest.ts b/server/api/delete-interest.ts index f6d6230..2b54124 100644 --- a/server/api/delete-interest.ts +++ b/server/api/delete-interest.ts @@ -1,21 +1,33 @@ +import { deleteInterest } from '~/server/utils/nocodb'; + export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[delete-interest] Request received with x-tag:', xTagHeader); - if (!xTagHeader || xTagHeader !== "094ut234") { + if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[delete-interest] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } try { const body = await readBody(event); const { id } = body; + console.log('[delete-interest] Request body:', { id }); if (!id) { + console.error('[delete-interest] Missing ID in request'); throw createError({ statusCode: 400, statusMessage: "ID is required" }); } + console.log('[delete-interest] Deleting interest:', id); const result = await deleteInterest(id); + console.log('[delete-interest] Successfully deleted interest:', id); + return result; } catch (error) { + console.error('[delete-interest] Error occurred:', error); + console.error('[delete-interest] Error stack:', error instanceof Error ? error.stack : 'No stack trace'); + if (error instanceof Error) { throw createError({ statusCode: 500, statusMessage: error.message }); } else { diff --git a/server/api/update-interest.ts b/server/api/update-interest.ts index 69464f1..68cbe0c 100644 --- a/server/api/update-interest.ts +++ b/server/api/update-interest.ts @@ -1,19 +1,26 @@ +import { updateInterest } from '~/server/utils/nocodb'; + export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); + console.log('[update-interest] Request received with x-tag:', xTagHeader); if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { + console.error('[update-interest] Authentication failed - invalid x-tag:', xTagHeader); throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } try { const body = await readBody(event); const { id, data } = body; + console.log('[update-interest] Request body:', { id, dataKeys: data ? Object.keys(data) : 'none' }); if (!id) { + console.error('[update-interest] Missing ID in request'); throw createError({ statusCode: 400, statusMessage: "ID is required" }); } if (!data || Object.keys(data).length === 0) { + console.error('[update-interest] No data provided for update'); throw createError({ statusCode: 400, statusMessage: "No data provided for update" }); } @@ -21,11 +28,18 @@ export default defineEventHandler(async (event) => { const updateData = { ...data }; if ('Id' in updateData) { delete updateData.Id; + console.log('[update-interest] Removed Id from update data'); } + console.log('[update-interest] Updating interest:', id, 'with fields:', Object.keys(updateData)); const updatedInterest = await updateInterest(id, updateData); + console.log('[update-interest] Successfully updated interest:', id); + return updatedInterest; } catch (error) { + console.error('[update-interest] Error occurred:', error); + console.error('[update-interest] Error stack:', error instanceof Error ? error.stack : 'No stack trace'); + if (error instanceof Error) { throw createError({ statusCode: 500, statusMessage: error.message }); } else { diff --git a/server/utils/nocodb.ts b/server/utils/nocodb.ts index e0c1c86..c5bea78 100644 --- a/server/utils/nocodb.ts +++ b/server/utils/nocodb.ts @@ -38,6 +38,9 @@ export const getInterestById = async (id: string) => }); export const updateInterest = async (id: string, data: Partial) => { + console.log('[nocodb.updateInterest] Updating interest:', id); + console.log('[nocodb.updateInterest] Data fields:', Object.keys(data)); + // Create a clean data object that matches the InterestsRequest schema // Remove any properties that are not in the schema or shouldn't be sent const cleanData: Record = {}; @@ -74,6 +77,11 @@ export const updateInterest = async (id: string, data: Partial) => { "Contract Sent Status", "Deposit 10% Status", "Contract Status", + // Add the EOI link fields + "EOI Client Link", + "EOI David Link", + "EOI Oscar Link", + "EOI Document" ]; // Filter the data to only include allowed fields @@ -83,19 +91,31 @@ export const updateInterest = async (id: string, data: Partial) => { } } - return $fetch(createTableUrl(Table.Interest), { - method: "PATCH", - headers: { - "xc-token": getNocoDbConfiguration().token, - }, - body: { - Id: id, // This identifies the record to update - ...cleanData, // These are the fields to update - }, - }); + console.log('[nocodb.updateInterest] Clean data fields:', Object.keys(cleanData)); + + const url = `${createTableUrl(Table.Interest)}/${id}`; + console.log('[nocodb.updateInterest] URL:', url); + + try { + const result = await $fetch(url, { + method: "PATCH", + headers: { + "xc-token": getNocoDbConfiguration().token, + }, + body: cleanData + }); + console.log('[nocodb.updateInterest] Update successful for ID:', id); + return result; + } catch (error) { + console.error('[nocodb.updateInterest] Update failed:', error); + console.error('[nocodb.updateInterest] Error details:', error instanceof Error ? error.message : 'Unknown error'); + throw error; + } }; export const createInterest = async (data: Partial) => { + console.log('[nocodb.createInterest] Creating interest with fields:', Object.keys(data)); + // Create a clean data object that matches the InterestsRequest schema const cleanData: Record = {}; @@ -137,22 +157,47 @@ export const createInterest = async (data: Partial) => { delete cleanData["Berth Recommendations"]; delete cleanData.Berth; - return $fetch(createTableUrl(Table.Interest), { - method: "POST", - headers: { - "xc-token": getNocoDbConfiguration().token, - }, - body: cleanData, - }); + console.log('[nocodb.createInterest] Clean data fields:', Object.keys(cleanData)); + const url = createTableUrl(Table.Interest); + console.log('[nocodb.createInterest] URL:', url); + + try { + const result = await $fetch(url, { + method: "POST", + headers: { + "xc-token": getNocoDbConfiguration().token, + }, + body: cleanData, + }); + console.log('[nocodb.createInterest] Created interest with ID:', result.Id); + return result; + } catch (error) { + console.error('[nocodb.createInterest] Create failed:', error); + console.error('[nocodb.createInterest] Error details:', error instanceof Error ? error.message : 'Unknown error'); + throw error; + } }; -export const deleteInterest = async (id: string) => - $fetch(`${createTableUrl(Table.Interest)}/${id}`, { - method: "DELETE", - headers: { - "xc-token": getNocoDbConfiguration().token, - }, - }); +export const deleteInterest = async (id: string) => { + console.log('[nocodb.deleteInterest] Deleting interest:', id); + const url = `${createTableUrl(Table.Interest)}/${id}`; + console.log('[nocodb.deleteInterest] URL:', url); + + try { + const result = await $fetch(url, { + method: "DELETE", + headers: { + "xc-token": getNocoDbConfiguration().token, + }, + }); + console.log('[nocodb.deleteInterest] Delete successful for ID:', id); + return result; + } catch (error) { + console.error('[nocodb.deleteInterest] Delete failed:', error); + console.error('[nocodb.deleteInterest] Error details:', error instanceof Error ? error.message : 'Unknown error'); + throw error; + } +}; export const triggerWebhook = async (url: string, payload: any) => $fetch(url, { diff --git a/utils/types.ts b/utils/types.ts index e888f3c..820f7f8 100644 --- a/utils/types.ts +++ b/utils/types.ts @@ -62,9 +62,9 @@ export type ContactMethodPreferred = "Email" | "Phone"; export const ContactMethodPreferredFlow = ["Email", "Phone"]; -export type EOIStatus = "Awaiting Further Details" | "Signed"; +export type EOIStatus = "Awaiting Further Details" | "Waiting for Signatures" | "Signed"; -export const EOIStatusFlow = ["Awaiting Further Details", "Signed"]; +export const EOIStatusFlow = ["Awaiting Further Details", "Waiting for Signatures", "Signed"]; export type BerthInfoSentStatus = "Pending" | "Yes";