84 lines
2.3 KiB
JavaScript
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;
|