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

+9 -4
View File
@@ -2,17 +2,22 @@ import PQueue from 'p-queue';
import type { Config } from '../config/index.js';
import type { Logger } from './logger.js';
const DEFAULT_HOUR_WINDOW_MS = 3600000;
export class RateLimiter {
private queue: PQueue;
private lastMessageTime: number = 0;
private messagesThisHour: number = 0;
private hourStartTime: number = Date.now();
private readonly hourWindowMs: number;
constructor(
private config: Config,
private logger: Logger
private logger: Logger,
hourWindowMs: number = DEFAULT_HOUR_WINDOW_MS,
) {
this.queue = new PQueue({ concurrency: 1 });
this.hourWindowMs = hourWindowMs;
}
async throttle<T>(fn: () => Promise<T>, shouldCount: (result: T) => boolean = () => true): Promise<T> {
@@ -20,7 +25,7 @@ export class RateLimiter {
const now = Date.now();
// Reset hourly counter if needed
if (now - this.hourStartTime > 3600000) {
if (now - this.hourStartTime > this.hourWindowMs) {
this.messagesThisHour = 0;
this.hourStartTime = now;
this.logger.debug('Hourly rate limit counter reset');
@@ -28,7 +33,7 @@ export class RateLimiter {
// Check hourly limit
if (this.messagesThisHour >= this.config.rateLimit.maxMessagesPerHour) {
const waitTime = 3600000 - (now - this.hourStartTime);
const waitTime = this.hourWindowMs - (now - this.hourStartTime);
this.logger.info(`Hourly limit reached, waiting ${Math.round(waitTime / 60000)} minutes`);
await this.sleep(waitTime);
this.messagesThisHour = 0;
@@ -94,7 +99,7 @@ export class RateLimiter {
}
// Calculate when the hourly counter resets
const hourlyResetAt = this.hourStartTime + 3600000;
const hourlyResetAt = this.hourStartTime + this.hourWindowMs;
// Check if hourly limit is reached
const isHourlyLimitReached = this.messagesThisHour >= maxMessages;