feat: implement notification system with polling and event handling; add device ID middleware and cleanup logic
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { dbAdapter, DBAdapter } from './db';
|
||||
import crypto from 'crypto';
|
||||
|
||||
export type NotificationEvent = {
|
||||
id: string;
|
||||
deviceIdOrigin?: string;
|
||||
eventType: string; // created | updated | deleted | listContentUpdated | listEdited ...
|
||||
entityType: string; // list | field | item | value
|
||||
entityId?: string;
|
||||
listId?: string;
|
||||
createdAt: number; // ms epoch
|
||||
};
|
||||
|
||||
function genId() {
|
||||
try {
|
||||
return crypto.randomUUID();
|
||||
} catch {
|
||||
return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
||||
}
|
||||
}
|
||||
|
||||
export async function enqueueNotification(
|
||||
adapter: DBAdapter,
|
||||
deviceIdOrigin: string | undefined,
|
||||
eventType: string,
|
||||
entityType: string,
|
||||
entityId?: string,
|
||||
listId?: string,
|
||||
createdAt?: number
|
||||
) {
|
||||
const id = genId();
|
||||
const ts = createdAt ?? Date.now();
|
||||
await adapter.execute(
|
||||
'INSERT INTO notifications (id, deviceIdOrigin, eventType, entityType, entityId, listId, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
[id, deviceIdOrigin ?? null, eventType, entityType, entityId ?? null, listId ?? null, ts]
|
||||
);
|
||||
}
|
||||
|
||||
// Retention policy
|
||||
const DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
||||
const CLEAN_INTERVAL_MS = 60 * 60 * 1000; // hourly
|
||||
|
||||
export function startNotificationCleanup() {
|
||||
const retentionMs = Number(process.env.NOTIF_RETENTION_MS || DEFAULT_RETENTION_MS);
|
||||
setInterval(async () => {
|
||||
try {
|
||||
const cutoff = Date.now() - retentionMs;
|
||||
await dbAdapter.execute('DELETE FROM notifications WHERE createdAt < ?', [cutoff]);
|
||||
} catch (e) {
|
||||
console.warn('[NOTIF] Retention cleanup failed:', e);
|
||||
}
|
||||
}, CLEAN_INTERVAL_MS).unref?.();
|
||||
}
|
||||
Reference in New Issue
Block a user