2025-07-10 10:56:52 -06:00

143 lines
4.1 KiB
JavaScript

const axios = require('axios');
const config = require('../config');
const logger = require('../utils/logger');
class NocoDBService {
constructor() {
this.apiUrl = config.nocodb.apiUrl;
this.apiToken = config.nocodb.apiToken;
this.projectId = config.nocodb.projectId;
this.timeout = 10000; // 10 seconds
// Create axios instance with defaults
this.client = axios.create({
baseURL: this.apiUrl,
timeout: this.timeout,
headers: {
'xc-token': this.apiToken,
'Content-Type': 'application/json'
}
});
// Add response interceptor for error handling
this.client.interceptors.response.use(
response => response,
error => {
logger.error('NocoDB API Error:', {
message: error.message,
url: error.config?.url,
method: error.config?.method,
status: error.response?.status,
data: error.response?.data
});
throw error;
}
);
}
// Build table URL
getTableUrl(tableId) {
return `/db/data/v1/${this.projectId}/${tableId}`;
}
// Get all records from a table
async getAll(tableId, params = {}) {
const url = this.getTableUrl(tableId);
const response = await this.client.get(url, { params });
return response.data;
}
// Get single record
async getById(tableId, recordId) {
const url = `${this.getTableUrl(tableId)}/${recordId}`;
const response = await this.client.get(url);
return response.data;
}
// Create record
async create(tableId, data) {
const url = this.getTableUrl(tableId);
const response = await this.client.post(url, data);
return response.data;
}
// Update record
async update(tableId, recordId, data) {
const url = `${this.getTableUrl(tableId)}/${recordId}`;
const response = await this.client.patch(url, data);
return response.data;
}
// Delete record
async delete(tableId, recordId) {
const url = `${this.getTableUrl(tableId)}/${recordId}`;
const response = await this.client.delete(url);
return response.data;
}
// Get locations with proper filtering
async getLocations(params = {}) {
const defaultParams = {
limit: 1000,
offset: 0,
...params
};
return this.getAll(config.nocodb.tableId, defaultParams);
}
// Get user by email
async getUserByEmail(email) {
if (!config.nocodb.loginSheetId) {
throw new Error('Login sheet not configured');
}
const response = await this.getAll(config.nocodb.loginSheetId, {
where: `(Email,eq,${email})`,
limit: 1
});
return response.list?.[0] || null;
}
// Get latest settings
async getLatestSettings() {
if (!config.nocodb.settingsSheetId) {
return null;
}
const response = await this.getAll(config.nocodb.settingsSheetId, {
sort: '-created_at',
limit: 1
});
return response.list?.[0] || null;
}
// Get settings with walk sheet data
async getWalkSheetSettings() {
if (!config.nocodb.settingsSheetId) {
return null;
}
const response = await this.getAll(config.nocodb.settingsSheetId, {
sort: '-created_at',
limit: 20
});
// Find first row with walk sheet data
const settings = response.list?.find(row =>
row.walk_sheet_title ||
row.walk_sheet_subtitle ||
row.walk_sheet_footer ||
row.qr_code_1_url ||
row.qr_code_2_url ||
row.qr_code_3_url
) || response.list?.[0];
return settings || null;
}
}
// Export singleton instance
module.exports = new NocoDBService();