feat(profile): event-driven invalidation (#81 phase B.2)
Features now declare invalidatedBy subjects in the registry; the new profile/subscriber.ts subscribes to each unique subject and drops matching stored rows for the userId in the payload. Next getProfile call recomputes from current data instead of waiting up to ttlSec. Wiring: completion_rate_30d, dismiss_rate_30d, mean_dwell_ms_30d, preferred_hour ← signals.tip.feedback tip_volume_30d ← signals.tip.served TTL stays as a safety net for clock drift and dropped events. Registration validates each declared subject against KNOWN_SUBJECTS (mirror of EventMap) so typos throw at startup, not silently. ADR-0011 updated. Refs #81. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,8 @@ import { requireAdmin } from './middleware/admin.js';
|
||||
import type { Request, Response } from 'express';
|
||||
import { connectNats } from './events/nats.js';
|
||||
import { startTodoistSyncScheduler } from './signals/scheduler.js';
|
||||
import { bus } from './events/bus.js';
|
||||
import { registerProfileSubscriptions } from './profile/subscriber.js';
|
||||
|
||||
await mkdir(dirname(config.DATABASE_PATH), { recursive: true });
|
||||
runMigrations();
|
||||
@@ -96,3 +98,7 @@ if (config.NATS_URL) {
|
||||
}
|
||||
|
||||
startTodoistSyncScheduler(config.TODOIST_SYNC_INTERVAL_MS);
|
||||
|
||||
// Profile features are invalidated on relevant signals (#81 phase B.2);
|
||||
// TTL stays as a safety net for clock drift / dropped events.
|
||||
registerProfileSubscriptions(bus);
|
||||
|
||||
Reference in New Issue
Block a user