synops/migrations/030_feed_orchestration.sql
vegard 7fbdc3f5dc Feed-orkestrering: periodisk RSS/Atom-polling per samling (oppgave 29.3)
Ny standard-orkestrering "Overvåk RSS-feed" som bruker synops-feed CLI.
Samlinger konfigurerer feed-abonnementer via metadata.feed_subscriptions[],
med konfigurerbar URL, intervall og mål (inbox/channel).

Komponenter:
- Migration 030: synops-feed cli_tool-seed, orchestration-seed, indeks, prioritetsregel
- feed_poller.rs: Bakgrunnstask som hvert 60s finner forfalne abonnementer
  og enqueuer feed_poll-jobber. Dedupliserer mot kjørende jobber.
- feed_poll job handler: Spawner synops-feed CLI, oppdaterer last_polled_at
- API: configure_feed_subscription + remove_feed_subscription endepunkter

Verifisert: NRK toppsaker.rss → 100 noder opprettet, last_polled_at oppdatert.
2026-03-18 21:32:00 +00:00

82 lines
3.5 KiB
PL/PgSQL

-- 030_feed_orchestration.sql
-- Oppgave 29.3: Feed-orkestrering — standard-orkestrering "Overvåk RSS-feed"
-- som bruker synops-feed. Konfigurerbar per samling via metadata.feed_subscriptions.
--
-- Inneholder:
-- 1. synops-feed cli_tool-node (aliases og args_hints for script_compiler)
-- 2. "Overvåk RSS-feed" seed-orkestrering
-- 3. Indeks for rask oppslag av feed_subscriptions
--
-- Ref: docs/concepts/orkestrering.md, tools/synops-feed/
BEGIN;
-- =============================================================================
-- 1. synops-feed — RSS/Atom-feed abonnement
-- =============================================================================
INSERT INTO nodes (id, node_kind, title, visibility, metadata, created_by)
VALUES (
'f0000000-c100-4000-b000-000000000015',
'cli_tool',
'synops-feed',
'discoverable',
'{
"binary": "synops-feed",
"aliases": ["abonner på feed", "hent feed", "rss-abonnement", "feed-sjekk"],
"description": "Abonner på RSS/Atom-feed og opprett content-noder for nye entries",
"args_hints": {
"feed-url": "--url {arg}",
"for samlingen": "--collection-id {event.collection_id}",
"som bruker": "--created-by {event.created_by}",
"intervall": "--interval {arg}",
"som json": "--payload-json {arg}"
}
}'::jsonb,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'
) ON CONFLICT (id) DO NOTHING;
-- =============================================================================
-- 2. Seed-orkestrering: Overvåk RSS-feed
-- =============================================================================
-- Trigger: scheduled.interval — periodisk polling basert på konfigurasjon.
-- Hvert collection med metadata.feed_subscriptions[] aktiverer dette.
-- Maskinrommet sin feed_poller finner disse samlingene og enqueuer feed_poll-jobber.
INSERT INTO nodes (id, node_kind, title, content, visibility, metadata, created_by)
VALUES (
'e0000000-0ac0-4000-b000-000000000006',
'orchestration',
'Overvåk RSS-feed',
E'NÅR planlagt intervall\nHVIS samling har feed_subscriptions\n\n1. abonner på feed for samlingen\n\nved feil: opprett oppgave "Feed-polling feilet" (bug)',
'discoverable',
'{
"trigger": {
"event": "scheduled.interval",
"conditions": {
"has_metadata": "feed_subscriptions"
}
},
"executor": "script",
"intelligence": 1,
"effort": 1,
"compiled": false
}'::jsonb,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'
) ON CONFLICT (id) DO NOTHING;
-- =============================================================================
-- 3. Indeks for rask oppslag av samlinger med feed_subscriptions
-- =============================================================================
-- Brukes av feed_poller for å finne samlinger som skal polles.
CREATE INDEX IF NOT EXISTS idx_nodes_feed_subscriptions
ON nodes ((metadata->'feed_subscriptions'))
WHERE node_kind = 'collection' AND metadata ? 'feed_subscriptions';
-- =============================================================================
-- 4. Prioritetsregel for feed_poll-jobber
-- =============================================================================
-- Lav prioritet (3) — feed-polling er bakgrunnsarbeid som ikke haster.
INSERT INTO job_priority_rules (job_type, base_priority, cpu_weight, max_concurrent, timeout_seconds)
VALUES ('feed_poll', 3, 1, 2, 120)
ON CONFLICT (job_type) DO NOTHING;
COMMIT;