fix(events): Complete field name and query syntax fix based on debug findings
Build And Push Image / docker (push) Successful in 3m34s Details

Root cause identified and fixed:
- Events table uses 'Id' (capital I) not 'id' (lowercase)
- Fixed all field references to use correct NocoDB field names
- Added proper filtering with gte/lte operators (btw didn't work)
- Fixed RSVP lookup to prevent undefined event ID errors
- Updated calendar transformation to use correct field names

 Debug findings showed:
- Basic table access works (mp3wigub1fzdo1b confirmed correct)
- Sample record revealed actual field structure
- Issue was field name mismatch causing undefined IDs in queries

 This should resolve all 422 errors and make events calendar functional
This commit is contained in:
Matt 2025-08-12 13:41:59 +02:00
parent 9c029eb510
commit c4789ec9df
1 changed files with 70 additions and 45 deletions

View File

@ -62,48 +62,63 @@ export function createNocoDBEventsClient() {
if (filters?.limit) queryParams.set('limit', filters.limit.toString());
if (filters?.offset) queryParams.set('offset', filters.offset.toString());
// Build where clause for filtering using correct field names from NocoDB
const whereConditions: string[] = [];
if (filters?.start_date && filters?.end_date) {
// Date range filtering using gte and lte (btw didn't work)
whereConditions.push(`(start_datetime,gte,${filters.start_date})`);
whereConditions.push(`(start_datetime,lte,${filters.end_date})`);
}
if (filters?.event_type) {
whereConditions.push(`(event_type,eq,${filters.event_type})`);
}
if (filters?.visibility) {
whereConditions.push(`(visibility,eq,${filters.visibility})`);
} else if (filters?.user_role) {
// Role-based visibility filtering
if (filters.user_role === 'user') {
whereConditions.push(`(visibility,eq,public)`);
} else if (filters.user_role === 'board') {
// Board members can see public and board-only events
whereConditions.push(`~or((visibility,eq,public),(visibility,eq,board-only))`);
}
// Admin sees all events (no filter)
}
if (filters?.status) {
whereConditions.push(`(status,eq,${filters.status})`);
} else {
// Default to active events only
whereConditions.push(`(status,eq,active)`);
}
if (filters?.search) {
// Search in title or description
whereConditions.push(`~or((title,like,%${filters.search}%),(description,like,%${filters.search}%))`);
}
// Combine conditions with ~and if multiple conditions exist
if (whereConditions.length > 0) {
const whereClause = whereConditions.length === 1
? whereConditions[0]
: `~and(${whereConditions.join(',')})`;
queryParams.set('where', whereClause);
}
// Sort by start date
queryParams.set('sort', 'start_datetime');
const url = `${baseUrl}/api/v2/tables/${eventsTableId}/records?${queryParams.toString()}`;
console.log('[nocodb-events] 🔍 DEBUG: Attempting to fetch events...');
console.log('[nocodb-events] 📋 Table ID:', eventsTableId);
console.log('[nocodb-events] 🌐 Full URL:', url);
console.log('[nocodb-events] 🔑 Token (first 10 chars):', token?.substring(0, 10) + '...');
const response = await $fetch(url, {
method: 'GET',
headers
});
try {
const response = await $fetch(url, {
method: 'GET',
headers
});
console.log('[nocodb-events] ✅ SUCCESS! Got response');
console.log('[nocodb-events] 📊 Response type:', typeof response);
console.log('[nocodb-events] 📝 Response keys:', Object.keys(response || {}));
if (response && typeof response === 'object') {
const responseObj = response as any;
if (responseObj.list && Array.isArray(responseObj.list)) {
console.log('[nocodb-events] 📈 Records found:', responseObj.list.length);
if (responseObj.list.length > 0) {
console.log('[nocodb-events] 🔍 First record keys (FIELD NAMES):', Object.keys(responseObj.list[0]));
console.log('[nocodb-events] 📄 Sample record:', JSON.stringify(responseObj.list[0], null, 2));
}
}
}
return response;
} catch (error: any) {
console.error('[nocodb-events] ❌ FAILED with error:', error);
console.error('[nocodb-events] 🔍 Error details:', {
message: error?.message,
status: error?.status,
statusCode: error?.statusCode,
statusMessage: error?.statusMessage,
data: error?.data
});
// Re-throw the error so the calling code can handle it
throw error;
}
return response;
},
/**
@ -272,7 +287,15 @@ export function createNocoDBEventsClient() {
}
// Get user's RSVPs for these events
const eventIds = events.list.map((e: Event) => e.id);
// Fix: Use 'Id' (capital I) as that's the actual field name from NocoDB
const eventIds = events.list.map((e: any) => e.Id);
// Skip RSVP lookup if no valid event IDs
if (!eventIds.length || eventIds.some(id => !id)) {
console.log('[nocodb-events] ⚠️ No valid event IDs found, skipping RSVP lookup');
return { list: events.list, PageInfo: events.PageInfo };
}
const rsvpQueryParams = new URLSearchParams();
const eventIdConditions = eventIds.map(id => `(event_id,eq,${id})`).join(',');
rsvpQueryParams.set('where', `~and((member_id,eq,${memberId}),~or(${eventIdConditions}))`);
@ -293,9 +316,10 @@ export function createNocoDBEventsClient() {
}
// Add RSVP information to events
const eventsWithRSVP = events.list.map((event: Event) => ({
// Fix: Use 'Id' (capital I) as that's the actual field name from NocoDB
const eventsWithRSVP = events.list.map((event: any) => ({
...event,
user_rsvp: rsvpMap.get(event.id) || null
user_rsvp: rsvpMap.get(event.Id) || null
}));
return {
@ -333,8 +357,9 @@ export function createNocoDBEventsClient() {
/**
* Utility function to transform Event data for FullCalendar
* Updated to use correct field names from NocoDB (Id instead of id)
*/
export function transformEventForCalendar(event: Event): any {
export function transformEventForCalendar(event: any): any {
const eventTypeColors = {
'meeting': { bg: '#2196f3', border: '#1976d2' },
'social': { bg: '#4caf50', border: '#388e3c' },
@ -347,8 +372,8 @@ export function transformEventForCalendar(event: Event): any {
{ bg: '#757575', border: '#424242' };
return {
id: event.id,
title: event.title,
id: event.Id, // Fix: Use 'Id' (capital I) from NocoDB
title: event.title || 'Untitled Event',
start: event.start_datetime,
end: event.end_datetime,
backgroundColor: colors.bg,