()
| 64 | // ── Main sync function ── |
| 65 | |
| 66 | export async function runResolutionSync(): Promise<{ monitors: number; alerts: number }> { |
| 67 | const db = getDb(); |
| 68 | let totalAlerts = 0; |
| 69 | |
| 70 | // 1. Build/refresh monitor list from all active events with resolution_source |
| 71 | const events = db.prepare(` |
| 72 | SELECT id, title, resolution_source, end_date, tags_json, markets_json |
| 73 | FROM events |
| 74 | WHERE is_active = 1 AND is_closed = 0 AND resolution_source IS NOT NULL |
| 75 | `).all() as EventRow[]; |
| 76 | |
| 77 | const upsertMonitor = db.prepare(` |
| 78 | INSERT INTO resolution_monitors (event_id, source_type, feed_url, org_name, monitor_config) |
| 79 | VALUES (?, ?, ?, ?, ?) |
| 80 | ON CONFLICT(event_id) DO UPDATE SET |
| 81 | source_type = excluded.source_type, |
| 82 | feed_url = excluded.feed_url, |
| 83 | org_name = excluded.org_name, |
| 84 | monitor_config = excluded.monitor_config |
| 85 | `); |
| 86 | |
| 87 | const upsertTx = db.transaction(() => { |
| 88 | for (const event of events) { |
| 89 | const target = parseResolutionSource(event.resolution_source); |
| 90 | switch (target.type) { |
| 91 | case "known_feed": |
| 92 | upsertMonitor.run(event.id, target.type, target.feedUrl, target.orgName, null); |
| 93 | break; |
| 94 | case "price_feed": { |
| 95 | const config = JSON.stringify({ provider: target.provider, symbol: target.symbol }); |
| 96 | upsertMonitor.run(event.id, target.type, target.url, target.provider, config); |
| 97 | break; |
| 98 | } |
| 99 | case "sports_feed": |
| 100 | upsertMonitor.run(event.id, target.type, target.feedUrl, target.source, null); |
| 101 | break; |
| 102 | default: |
| 103 | upsertMonitor.run(event.id, "unmonitorable", null, null, null); |
| 104 | } |
| 105 | } |
| 106 | }); |
| 107 | upsertTx(); |
| 108 | |
| 109 | // 2. Get all monitorable types |
| 110 | const allMonitors = db.prepare(` |
| 111 | SELECT rm.*, e.title, e.end_date, e.tags_json, e.markets_json |
| 112 | FROM resolution_monitors rm |
| 113 | JOIN events e ON e.id = rm.event_id |
| 114 | WHERE rm.source_type IN ('known_feed', 'price_feed', 'sports_feed') |
| 115 | AND e.is_active = 1 AND e.is_closed = 0 |
| 116 | `).all() as EnrichedMonitor[]; |
| 117 | |
| 118 | const feedMonitors = allMonitors.filter((m) => m.source_type === "known_feed" || m.source_type === "sports_feed"); |
| 119 | const priceMonitors = allMonitors.filter((m) => m.source_type === "price_feed"); |
| 120 | |
| 121 | // 3a. RSS-based monitoring (known_feed + sports_feed) |
| 122 | totalAlerts += await runRssMonitoring(feedMonitors); |
| 123 |
no test coverage detected