fix(events): Convert NocoDB query syntax from SQL-like to v2 API format
Build And Push Image / docker (push) Successful in 3m20s Details

- Updated all where clauses to use NocoDB v2 syntax: (field,operator,value)
- Changed SQL-like syntax (field >= 'value' AND field = 'value') to v2 format
- Fixed date range queries: (start_datetime,gte,date) and (start_datetime,lte,date)
- Fixed equality queries: (status,eq,active) instead of (status = 'active')
- Fixed AND/OR logic: ~and() and ~or() syntax for complex conditions
- Updated findEventRSVPs, findUserRSVP, and findUserEvents methods
- Fixed RSVP queries to use proper v2 format for member and event matching

This should resolve the 422 Unprocessable Entity errors that were caused by
using deprecated SQL-like syntax with the v2 API endpoints.
This commit is contained in:
Matt 2025-08-12 13:15:06 +02:00
parent 122d6fdd26
commit 0688c23093
1 changed files with 19 additions and 13 deletions

View File

@ -62,42 +62,47 @@ 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
// Build where clause for filtering using NocoDB v2 syntax
const whereConditions: string[] = [];
if (filters?.start_date && filters?.end_date) {
whereConditions.push(`(start_datetime >= '${filters.start_date}' AND start_datetime <= '${filters.end_date}')`);
whereConditions.push(`(start_datetime,gte,${filters.start_date})`);
whereConditions.push(`(start_datetime,lte,${filters.end_date})`);
}
if (filters?.event_type) {
whereConditions.push(`(event_type = '${filters.event_type}')`);
whereConditions.push(`(event_type,eq,${filters.event_type})`);
}
if (filters?.visibility) {
whereConditions.push(`(visibility = '${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 = 'public')`);
whereConditions.push(`(visibility,eq,public)`);
} else if (filters.user_role === 'board') {
whereConditions.push(`(visibility = 'public' OR visibility = 'board-only')`);
// For multiple OR conditions, we'll need to handle this differently
whereConditions.push(`~or(visibility,eq,public)~or(visibility,eq,board-only)`);
}
// Admin sees all events (no filter)
}
if (filters?.status) {
whereConditions.push(`(status = '${filters.status}')`);
whereConditions.push(`(status,eq,${filters.status})`);
} else {
// Default to active events only
whereConditions.push(`(status = 'active')`);
whereConditions.push(`(status,eq,active)`);
}
if (filters?.search) {
whereConditions.push(`(title LIKE '%${filters.search}%' OR description LIKE '%${filters.search}%')`);
whereConditions.push(`~or(title,like,%${filters.search}%)~or(description,like,%${filters.search}%)`);
}
if (whereConditions.length > 0) {
queryParams.set('where', whereConditions.join(' AND '));
const whereClause = whereConditions.length === 1
? whereConditions[0]
: `~and(${whereConditions.join(',')})`;
queryParams.set('where', whereClause);
}
// Sort by start date
@ -202,7 +207,7 @@ export function createNocoDBEventsClient() {
*/
async findEventRSVPs(eventId: string) {
const queryParams = new URLSearchParams();
queryParams.set('where', `(event_id = '${eventId}')`);
queryParams.set('where', `(event_id,eq,${eventId})`);
queryParams.set('sort', 'created_time');
const url = `${baseUrl}/api/v2/tables/${rsvpTableId}/records?${queryParams.toString()}`;
@ -218,7 +223,7 @@ export function createNocoDBEventsClient() {
*/
async findUserRSVP(eventId: string, memberId: string) {
const queryParams = new URLSearchParams();
queryParams.set('where', `(event_id = '${eventId}' AND member_id = '${memberId}')`);
queryParams.set('where', `~and((event_id,eq,${eventId}),(member_id,eq,${memberId}))`);
queryParams.set('limit', '1');
const url = `${baseUrl}/api/v2/tables/${rsvpTableId}/records?${queryParams.toString()}`;
@ -281,7 +286,8 @@ export function createNocoDBEventsClient() {
// Get user's RSVPs for these events
const eventIds = events.list.map((e: Event) => e.id);
const rsvpQueryParams = new URLSearchParams();
rsvpQueryParams.set('where', `(member_id = '${memberId}' AND event_id IN (${eventIds.map((id: string) => `'${id}'`).join(',')}))`);
const eventIdConditions = eventIds.map(id => `(event_id,eq,${id})`).join(',');
rsvpQueryParams.set('where', `~and((member_id,eq,${memberId}),~or(${eventIdConditions}))`);
const rsvpUrl = `${baseUrl}/api/v2/tables/${rsvpTableId}/records?${rsvpQueryParams.toString()}`;