Files
Duriin-API/src/routes/status.js
T

84 lines
2.3 KiB
JavaScript

const db = require('../db');
const { getLastIngestionBySource } = require('../state');
let statusCache = null;
let statusCacheAt = 0;
const STATUS_CACHE_TTL_MS = 30 * 1000;
async function statusRoutes(fastify) {
fastify.get('/status', async (request) => {
const deep = String(request.query?.deep || '').toLowerCase() === 'true';
if (!deep) {
const sequence = db.prepare("SELECT seq FROM sqlite_sequence WHERE name = 'articles'").get();
return {
total: sequence ? sequence.seq : 0,
usable: null,
lastIngestionBySource: getLastIngestionBySource(),
bySource: null,
embeddingModels: null,
mode: 'lightweight',
deep_status_url: '/status?deep=true',
};
}
const now = Date.now();
if (statusCache && now - statusCacheAt < STATUS_CACHE_TTL_MS) {
return statusCache;
}
const bySourceRows = db.prepare(`
SELECT
source,
COUNT(*) AS total,
SUM(CASE
WHEN content IS NOT NULL AND content != ''
AND is_index_page = 0
AND has_embedding = 1
THEN 1 ELSE 0
END) AS usable
FROM articles
GROUP BY source
ORDER BY source
`).all();
const totals = bySourceRows.reduce(
(acc, row) => {
acc.total += row.total;
acc.usable += row.usable;
return acc;
},
{ total: 0, usable: 0 }
);
const embeddingModelRows = db.prepare(`
SELECT
model,
COUNT(*) AS article_count,
(SELECT LENGTH(embedding) FROM article_embedding_store s2 WHERE s2.model = s.model LIMIT 1) AS sample_bytes
FROM article_embedding_store s
GROUP BY model
ORDER BY article_count DESC
`).all();
const result = {
total: totals.total,
usable: totals.usable,
lastIngestionBySource: getLastIngestionBySource(),
bySource: Object.fromEntries(
bySourceRows.map((row) => [row.source, { total: row.total, usable: row.usable }])
),
embeddingModels: embeddingModelRows.map((row) => ({
model: row.model,
articles: row.article_count,
dimensions: row.sample_bytes ? row.sample_bytes / 4 : null,
})),
};
statusCache = result;
statusCacheAt = now;
return result;
});
}
module.exports = statusRoutes;