commit
32a36cceff
444 files changed
+67186
No files matched your search
@@ -0,0 +1,113 @@
|
||||
const { query } = require('../database/db');
|
||||
|
||||
class AiInsight {
|
||||
/**
|
||||
* Get AI insight by cycle and kandang
|
||||
* @param {string} cycleId - Cycle ID
|
||||
* @param {string|null} kandangId - Kandang ID (null for all kandangs)
|
||||
* @returns {Promise<Object|null>} Insight object or null if not found or expired
|
||||
*/
|
||||
static async getByCycleAndKandang(cycleId, kandangId = null) {
|
||||
try {
|
||||
const result = await query(
|
||||
`SELECT * FROM ai_insights
|
||||
WHERE cycle_id = $1
|
||||
AND ($2::text IS NULL AND kandang_id IS NULL OR kandang_id = $2)
|
||||
AND expires_at > NOW()
|
||||
ORDER BY generated_at DESC
|
||||
LIMIT 1`,
|
||||
[cycleId, kandangId]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) return null;
|
||||
|
||||
return this.formatInsight(result.rows[0]);
|
||||
} catch (error) {
|
||||
console.error('Error getting AI insight:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update AI insight
|
||||
* @param {Object} insightData - Insight data
|
||||
* @returns {Promise<Object>} Created/updated insight
|
||||
*/
|
||||
static async upsert(insightData) {
|
||||
try {
|
||||
const { cycleId, kandangId, insightText, version = 'v1' } = insightData;
|
||||
|
||||
// Calculate expiry date (6 hours from now)
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setHours(expiresAt.getHours() + 6);
|
||||
|
||||
// Check if insight already exists
|
||||
const existing = await this.getByCycleAndKandang(cycleId, kandangId);
|
||||
|
||||
if (existing) {
|
||||
// Update existing
|
||||
const result = await query(
|
||||
`UPDATE ai_insights
|
||||
SET insight_text = $1, version = $2, generated_at = NOW(), expires_at = $3, updated_at = NOW()
|
||||
WHERE id = $4
|
||||
RETURNING *`,
|
||||
[insightText, version, expiresAt, existing.id]
|
||||
);
|
||||
|
||||
return this.formatInsight(result.rows[0]);
|
||||
} else {
|
||||
// Create new
|
||||
const result = await query(
|
||||
`INSERT INTO ai_insights (cycle_id, kandang_id, insight_text, version, generated_at, expires_at)
|
||||
VALUES ($1, $2, $3, $4, NOW(), $5)
|
||||
RETURNING *`,
|
||||
[cycleId, kandangId, insightText, version, expiresAt]
|
||||
);
|
||||
|
||||
return this.formatInsight(result.rows[0]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error upserting AI insight:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete expired insights
|
||||
* @returns {Promise<number>} Number of deleted rows
|
||||
*/
|
||||
static async cleanupExpired() {
|
||||
try {
|
||||
const result = await query(
|
||||
'DELETE FROM ai_insights WHERE expires_at < NOW()',
|
||||
[]
|
||||
);
|
||||
|
||||
return result.rowCount;
|
||||
} catch (error) {
|
||||
console.error('Error cleaning up expired insights:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format database row to API response format
|
||||
* @param {Object} row - Database row
|
||||
* @returns {Object} Formatted insight
|
||||
*/
|
||||
static formatInsight(row) {
|
||||
return {
|
||||
id: row.id,
|
||||
cycleId: row.cycle_id,
|
||||
kandangId: row.kandang_id,
|
||||
insightText: row.insight_text,
|
||||
version: row.version,
|
||||
generatedAt: row.generated_at,
|
||||
expiresAt: row.expires_at,
|
||||
createdAt: row.created_at,
|
||||
updatedAt: row.updated_at,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AiInsight;
|
||||
Reference in new issue
Block a user