/** * 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 || '', }; if (!this.config.baseUrl || !this.config.baseId || !this.config.apiKey || !this.config.ordersTableId) { console.warn('⚠️ NocoDB configuration incomplete. Database integration disabled.'); } 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 */ async updateOrder(recordId, data) { return this.request(`/${recordId}`, { method: 'PATCH', body: JSON.stringify(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();