/** * NocoDB Client for Server * Simple REST API client for NocoDB operations */ class NocoDBClient { constructor() { this.config = { baseUrl: process.env.NOCODB_BASE_URL || '', baseId: process.env.NOCODB_BASE_ID || '', apiKey: process.env.NOCODB_API_KEY || '', ordersTableId: process.env.NOCODB_ORDERS_TABLE_ID || '', }; // Check configuration completeness const missingVars = []; if (!this.config.baseUrl) missingVars.push('NOCODB_BASE_URL'); if (!this.config.baseId) missingVars.push('NOCODB_BASE_ID'); if (!this.config.apiKey) missingVars.push('NOCODB_API_KEY'); if (!this.config.ordersTableId) missingVars.push('NOCODB_ORDERS_TABLE_ID'); if (missingVars.length > 0) { console.warn('⚠️ NocoDB configuration incomplete. Missing variables:', missingVars.join(', ')); console.warn(' Database integration will be disabled.'); } else { console.log('✅ NocoDB client initialized successfully'); console.log(` Base URL: ${this.config.baseUrl}`); console.log(` Table ID: ${this.config.ordersTableId}`); } this.baseUrl = `${this.config.baseUrl}/api/v2/tables/${this.config.ordersTableId}/records`; } /** * Make authenticated request to NocoDB */ async request(endpoint, options = {}) { const url = endpoint.startsWith('http') ? endpoint : `${this.baseUrl}${endpoint}`; const response = await fetch(url, { ...options, headers: { 'xc-token': this.config.apiKey, 'Content-Type': 'application/json', ...options.headers, }, }); if (!response.ok) { const errorText = await response.text(); throw new Error(`NocoDB request failed: ${response.status} - ${errorText}`); } return response.json(); } /** * Create new order record */ async createOrder(orderData) { return this.request('', { method: 'POST', body: JSON.stringify(orderData), }); } /** * Update order fields * NocoDB v2 API requires the ID in the body, not the URL */ async updateOrder(recordId, data) { return this.request('', { method: 'PATCH', body: JSON.stringify({ Id: recordId, ...data, }), }); } /** * Find order by orderId field */ async findOrderByOrderId(orderId) { const params = new URLSearchParams(); params.append('where', `(orderId,eq,${orderId})`); params.append('limit', '1'); const response = await this.request(`?${params.toString()}`); return response.list?.[0] || null; } /** * Update order with Wren fulfillment data */ async updateOrderFulfillment(orderId, fulfillmentData) { // First find the NocoDB record ID const order = await this.findOrderByOrderId(orderId); if (!order) { throw new Error(`Order not found in NocoDB: ${orderId}`); } // Update the record return this.updateOrder(order.Id, fulfillmentData); } /** * Check if NocoDB is configured */ isConfigured() { return !!(this.config.baseUrl && this.config.baseId && this.config.apiKey && this.config.ordersTableId); } } // Export singleton instance export const nocodbClient = new NocoDBClient();