import { query } from '../db/client.js' export type RealtimeEventRow = { id: number event_type: string entity_id: number scopes: unknown operation: string data: unknown admin_audience: boolean worker_ids: unknown broadcast_workers: boolean occurred_at: string } export async function createRealtimeEvent(input: { eventType: string entityId: number scopes: string[] operation: string data?: unknown adminAudience: boolean workerIds: number[] broadcastWorkers: boolean occurredAt: string }): Promise { const result = await query( ` INSERT INTO realtime_events ( event_type, entity_id, scopes, operation, data, admin_audience, worker_ids, broadcast_workers, occurred_at ) VALUES ($1, $2, $3::jsonb, $4, $5::jsonb, $6, $7::jsonb, $8, $9) RETURNING * `, [ input.eventType, input.entityId, JSON.stringify(input.scopes), input.operation, input.data === undefined ? null : JSON.stringify(input.data), input.adminAudience, JSON.stringify(input.workerIds), input.broadcastWorkers, input.occurredAt, ], ) const row = result.rows[0] if (!row) throw new Error('realtime_event_create_failed') // 事件仅用于短期断线补发;每 100 条清理一次,避免每次业务事件都额外触发 DELETE。 if (Number(row.id) % 100 === 0) { await query( ` DELETE FROM realtime_events WHERE id < GREATEST(0, (SELECT COALESCE(MAX(id), 0) - 500 FROM realtime_events)) `, ) } return row } export async function listRealtimeEventsAfter(eventId: number, limit = 500) { const result = await query( ` SELECT * FROM realtime_events WHERE id > $1 ORDER BY id ASC LIMIT $2 `, [Math.max(0, Number(eventId) || 0), Math.min(500, Math.max(1, Number(limit) || 500))], ) return result.rows }