netakhoj-api / services /AppwriteService.js
Rakeshops71
Deploy app with LFS for large files
3eedfc9
Raw
History Blame Contribute Delete
6.05 kB
import * as sdk from 'node-appwrite';
import { createLogger } from '../utils/logger.js';
import dotenv from 'dotenv';
dotenv.config();
const logger = createLogger('AppwriteService');
class AppwriteService {
constructor() {
this.config = {
endpoint: process.env.APPWRITE_ENDPOINT || 'https://cloud.appwrite.io/v1',
projectId: process.env.APPWRITE_PROJECT_ID,
apiKey: process.env.APPWRITE_API_KEY,
functionId: process.env.APPWRITE_FUNCTION_ID_PRS || '68ffcb25003df2ce3663', // Default to PRS function ID
};
this._validateConfig();
this._initializeClient();
}
_validateConfig() {
if (!this.config.projectId || !this.config.apiKey) {
logger.warn('INIT', 'Appwrite credentials missing. Service will be disabled.');
this.enabled = false;
} else {
this.enabled = true;
}
}
_initializeClient() {
if (!this.enabled) return;
try {
this.client = new sdk.Client()
.setEndpoint(this.config.endpoint)
.setProject(this.config.projectId)
.setKey(this.config.apiKey);
this.functions = new sdk.Functions(this.client);
logger.info('INIT', 'Appwrite SDK initialized');
} catch (error) {
logger.error('INIT', 'Failed to initialize Appwrite SDK', error);
this.enabled = false;
}
}
/**
* Execute an Appwrite Cloud Function
* @param {string} functionId - The ID of the function to execute (optional, defaults to config)
* @param {Object} payload - The data to send to the function
* @param {string} requestId - Request ID for logging
* @returns {Promise<Object>} - The parsed JSON response from the function
*/
async executeFunction(payload, requestId = 'default', functionId = null) {
if (!this.enabled) {
throw new Error('Appwrite service is not configured');
}
const targetFunctionId = functionId || this.config.functionId;
const startTime = Date.now();
try {
logger.debug(requestId, 'Executing Appwrite function', { functionId: targetFunctionId });
const execution = await this.functions.createExecution(
targetFunctionId,
JSON.stringify(payload),
false, // async (false = synchronous)
'/', // path
'POST', // method
{} // headers
);
const duration = Date.now() - startTime;
if (execution.status === 'failed') {
logger.error(requestId, 'Appwrite execution failed', {
stderr: execution.stderr,
duration
});
throw new Error(`Appwrite function execution failed: ${execution.stderr}`);
}
let responseData;
try {
responseData = JSON.parse(execution.responseBody);
// DEBUG LOGGING
let logData = { ...responseData };
if (logData.data) {
logData.data = { ...logData.data };
if (logData.data.attendanceTable) logData.data.attendanceTable = `[HIDDEN - ${logData.data.attendanceTable.length} items]`;
if (logData.data.debatesTable) logData.data.debatesTable = `[HIDDEN - ${logData.data.debatesTable.length} items]`;
if (logData.data.questionsTable) logData.data.questionsTable = `[HIDDEN - ${logData.data.questionsTable.length} items]`;
}
console.log('\n======================================================================');
console.log(`🚀 APPWRITE RESPONSE [${requestId}]`);
console.log('======================================================================');
console.log(JSON.stringify(logData, null, 2));
console.log('======================================================================\n');
} catch (parseError) {
logger.error(requestId, 'Failed to parse response body', {
body: execution.responseBody,
error: parseError.message
});
// Log raw body on error
console.log('\n======================================================================');
console.log(`❌ APPWRITE RESPONSE ERROR [${requestId}]`);
console.log('======================================================================');
console.log(execution.responseBody);
console.log('======================================================================\n');
throw new Error('Invalid JSON response from Appwrite function');
}
logger.success(requestId, `Appwrite execution completed in ${duration}ms`, {
status: execution.status,
success: responseData.success
});
return {
success: true,
data: responseData,
execution: {
id: execution.$id,
status: execution.status,
duration: execution.duration,
},
timing: {
total: duration
}
};
} catch (error) {
const duration = Date.now() - startTime;
logger.error(requestId, 'Appwrite execution error', { error: error.message, duration });
throw error;
}
}
getStats() {
return {
enabled: this.enabled,
config: {
endpoint: this.config.endpoint,
projectId: this.config.projectId ? '***' : 'missing',
functionId: this.config.functionId
}
};
}
}
// Export singleton
export default new AppwriteService();