← Zurück zum Vorlagen-Explorer Proof of Concept · Stufe 1

Ratsmonitor OS — Technisches Setup

Wie wir Dokumente aus den kommunalen Ratsinformationssystemen einsammeln, ablegen und automatisch aktuell halten. Bewusst kompakt, für Redaktion und IT.

9 Kommunen · Osnabrück, Melle, GMH, Bersenbrück, SG Artland, Quakenbrück, Badbergen, Menslage, Nortrup 3 RIS-Typen · Allris, SOMACOS Session & SD.NET RIM (5 Hosts) Stack · Python · AWS S3 · Lambda

Was Stufe 1 leistet

Diese erste Stufe ist reines Sourcing: vollständig und verlässlich erfassen, was die Städte veröffentlichen, und es revisionssicher ablegen. Die KI-Analyse (OCR, Entitäten-Erkennung, Relevanz-Scoring) und der Knowledge Graph kommen in den Folgestufen darauf.

535
Vorlagen erfasst (letzte 3 Monate)
9
Kommunen über 3 RIS-Typen
stündlich
automatischer Check, 6–23 Uhr
0
externe Scraping-Dienste

Die drei Bausteine im Überblick

1

Scraping

Je RIS-Typ ein schlanker Adapter holt die Vorlagen-PDFs samt Metadaten direkt von der RIS-Webseite — nur mit requests + BeautifulSoup, kein Headless-Browser, kein Drittanbieter.

2

Speicherung

PDFs + JSON-Metadaten landen in einem privaten S3-Bucket (versioniert, verschlüsselt). Eine SQLite-Tabelle hält den vereinheitlichten Index über alle Städte.

3

Cron-Job

Eine AWS-Lambda prüft stündlich alle neun Kommunen auf Neues. Zustandslos: dedupliziert direkt gegen S3, lädt nur, was noch fehlt.

Architektur: Core + Adapter

Der Kern der Idee: ein Gehirn, viele Sammler. Jede Stadt nutzt ein anderes Ratsinformationssystem mit eigener HTML-Struktur — die kapseln wir in kleinen Adaptern. Alles, was danach kommt (Speicherung, später Analyse), ist für alle Städte identisch.

🧠 Core (kommunenübergreifend)

  • store.py — einheitliche SQLite-Tabelle, PK <slug>:<id>
  • s3util.py — S3-Client & Key-Schema
  • build_explorer.py — generiert die HTML-Ansicht

🔌 Adapter (pro RIS-Typ)

  • scrape_vorlagen.pyAllris Osnabrück
  • adapter_session.pySession Melle, GMH, Bersenbrück
  • adapter_sdnet.pySD.NET RIM SG Artland, Quakenbrück, Badbergen, Menslage, Nortrup
  • Übersetzen alles ins gleiche Schema

3 RIS-Software-Typen über 5 Hosts: Ein einziger Session-Adapter bedient über eine CITIES-Registry drei verschiedene Hosts (session.melle.info, ris.bersenbrueck.de, gmh.ris.itebo.de); der neue SD.NET-Adapter bedient über dieselbe Registry-Mechanik gleich fünf Räte auf einem Host (artland.ratsinfomanagement.net, je Rat ein Pfad-Präfix). Eine Änderung am Core wirkt sofort auf alle Kommunen; eine neue Kommune = nur ein neuer Adapter bzw. ein neuer Registry-Eintrag.

1 · Scraping im Detail

Drei RIS-Typen, eine Logik

Alle drei Adapter normalisieren auf dasselbe Schema: Stadt · ID · Datum · Titel · Vorlagennummer · PDF-Link.

SystemKommunenListing-TrickDedup über
Allris Osnabrück Datums-Bisection: Zeitraum rekursiv halbieren bis ≤ 25 Treffer/Seite (Wicket-AJAX) VOLFDNR
Session Melle, GMH, Bersenbrück (3 eigene Hosts) Ein GET auf do0040.asp?smcadat=<Julian Day> listet alles ab dem Datum kvonr (interne ID)
SD.NET RIM SG Artland, Quakenbrück, Badbergen, Menslage, Nortrup (1 Host, 5 Pfade) Selbsttragende Liste <base>vorlagen, nach Termin sortiert — jede Zeile trägt PDF-Link + Nummer schon mit; blättern bis unters Stichdatum Vorlagennummer

Bei Session filtern wir aus der Liste nur echte Vorlagen heraus (Zeilen mit vo0050.asp?__kvonr) — Sitzungen und Tagesordnungspunkte fliegen raus; die Detailseite liefert dann Vorlagennummer + Original-PDF. SD.NET RIM ist noch genügsamer: die Vorlagen-Liste enthält den direkten PDF-Link bereits, eine Detailseite muss gar nicht erst geladen werden.

Warum kein Headless-Browser?

Reine HTTP-Requests sind schneller, stabiler und billiger als ein gesteuerter Chrome. Die RIS-Seiten liefern die nötigen Daten serverseitig — wir brauchen kein JavaScript-Rendering. Stack: requests + beautifulsoup4 + boto3, fertig.

2 · Speicherung im Detail

S3 — die Quelle der Wahrheit

Bucket ratsmonitor-os-noz-data (eu-central-1)

  • Privat — Public Access komplett geblockt
  • Versioniert — Löschungen sind wiederherstellbar
  • Verschlüsselt — SSE-S3 at rest
# Layout pro Kommune
<slug>/vorlagen/<datei>.pdf       # Original-PDF
<slug>/meta/<source_id>.json      # Metadaten-Sidecar (vom Cron)

SQLite — der Index

Tabelle vorlagen, ein Eintrag je Dokument

  • PK = synthetische ID <slug>:<source_id>
  • Spalten: stadt, quelle, datum, titel, s3_key
  • WAL-Modus + busy_timeout für parallele Stadt-Läufe

Speist die Filter im Vorlagen-Explorer (Stadt, Vorlagenart, Dienststelle, Zeitraum, Volltext).

Öffentliche PDF-Auslieferung via CloudFront

Der Bucket bleibt privat — trotzdem sollen die PDF-Buttons im Explorer auf eine stabile, öffentliche Kopie zeigen (nicht aufs flüchtige RIS-Original).

Block Public Access bleibt voll aktiv — eine OAC-Policy zählt nicht als „public". Sicherheit und öffentliche Auslieferung schließen sich nicht aus.

3 · Cron-Job im Detail

Stündlicher Check, vollständig serverlos

Kein Server, der durchläuft — AWS startet den Job nach Zeitplan und fährt ihn wieder runter. Bezahlt wird nur die Laufzeit.

EventBridge Scheduler  cron(0 6-23 * * ?), Europe/Berlin (DST automatisch)
        │
        ▼  triggert stündlich
Lambda  ratsmonitor-os-noz-incremental  python3.12, 512 MB, 300s Timeout
        │
        ▼  ruft scrape_incremental.main() — prüft ALLE 9 Kommunen
Rollierendes Fenster  Osnabrück: heute −30d … +30d · Session & SD.NET: alles ab heute −30d
        │
        ▼  Dedup gegen S3 (HeadObject) — zustandslos, keine DB nötig
S3  schreibt nur neue PDFs + Meta-JSON

Warum zustandslos?

Die Lambda braucht keine eigene Datenbank. Sie fragt für jedes gefundene Dokument per HeadObject: „Liegt das schon in S3?" — wenn nein, laden. Das macht den Job idempotent und absturzsicher: ein verpasster oder doppelter Lauf schadet nicht.

Berechtigungen

IAM-Rolle mit Least Privilege — die Lambda darf nur List/Get/Put auf genau diesen einen Bucket, plus Logs. Keine Zugangsschlüssel im Code; in der Cloud läuft alles über die IAM-Rolle.

Deploy: ./build_lambda.sh bündelt Core + alle drei Adapter zu lambda.zipaws lambda update-function-code. Env-Variablen steuern Fenstergröße (LOOKBACK_DAYS, FORWARD_DAYS) und Parallelität (WORKERS).

Sicherheit & Betrieb auf einen Blick