Restructure chat service, web routes, and add test suite

Split monolithic chat service into modular structure with Matrix client
support, extract web server into per-resource route modules, introduce
bootstrap/main-loop separation, and add comprehensive vitest coverage
across services, repositories, and utilities. Adds project docs and
CLAUDE.md agent instructions.
This commit is contained in:
jjbrunton committed 2026-05-21 01:32:10 +01:00
1 parent dfa0580859
commit 633bb0ec04
84 files changed
+19278 -3888

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
import { Router } from 'express';
import type { WebContext } from '../context.js';
export function createConfigRouter(ctx: WebContext): Router {
const router = Router();
router.get('/config', (_req, res) => {
res.json({
rateLimit: ctx.runtimeConfig.rateLimit,
browser: { dryRun: ctx.runtimeConfig.browser.dryRun },
});
});
router.put('/config', (req, res) => {
try {
const updates = req.body;
if (updates.rateLimit) {
if (typeof updates.rateLimit.minDelayBetweenMessagesMs === 'number') {
ctx.runtimeConfig.rateLimit.minDelayBetweenMessagesMs = Math.max(
0,
updates.rateLimit.minDelayBetweenMessagesMs,
);
}
if (typeof updates.rateLimit.maxMessagesPerHour === 'number') {
ctx.runtimeConfig.rateLimit.maxMessagesPerHour = Math.max(
1,
updates.rateLimit.maxMessagesPerHour,
);
}
if (typeof updates.rateLimit.jitterMs === 'number') {
ctx.runtimeConfig.rateLimit.jitterMs = Math.max(0, updates.rateLimit.jitterMs);
}
}
if (updates.browser) {
if (typeof updates.browser.dryRun === 'boolean') {
ctx.runtimeConfig.browser.dryRun = updates.browser.dryRun;
}
}
// Mirror into the loaded config so getStats reflects new values.
ctx.config.rateLimit.minDelayBetweenMessagesMs = ctx.runtimeConfig.rateLimit.minDelayBetweenMessagesMs;
ctx.config.rateLimit.maxMessagesPerHour = ctx.runtimeConfig.rateLimit.maxMessagesPerHour;
ctx.config.rateLimit.jitterMs = ctx.runtimeConfig.rateLimit.jitterMs;
ctx.config.browser.dryRun = ctx.runtimeConfig.browser.dryRun;
ctx.getOnConfigChange()?.(ctx.runtimeConfig);
ctx.activity.push('info', 'Config updated via dashboard');
ctx.broadcaster.push('info', 'Configuration updated via dashboard', updates);
res.json({ success: true, config: ctx.runtimeConfig });
} catch (error) {
ctx.logger.error('Failed to update config:', error);
res.status(400).json({ error: String(error) });
}
});
return router;
}