A rule engine that taps the DuckDB events extension on any of three connections and forwards each JSON event the extension emits to your choice of destinations — HTTP webhook, in-app live feed, JSONL audit log, or an arbitrary local command. The ArcGIS Pro / SQL Server trigger→webhook analog for DuckDB, built entirely in-process. Off by default; you decide which events fire on your data.
Author a rule: "when these event types fire AND the query matches this regex, forward to these destinations." Arm it, and the extension pipes every matching event's JSON to a bundled receiver process, which applies the fine-grained filter, token-bucket-throttles the stream, and fans out. No Python, no cloud.
connection_opened/closed, query_begin/end, transaction_begin/commit/rollback, planning_error, finalize_prepare, execute_prepared, rebind_prepared_statement.transaction_commit touching sensitive_data."tmg-event-relay.exe reads stdin JSONL, throttles to MaxEventsPerSec (default 500), fans out, and writes back to the host over a Windows named pipe → host SSE + recent-event ring.projecthub, analytics, or connectors. One receiver process + one named-pipe server per armed rule.// arm a rule on the analytics connection curl -X POST http://localhost:5059/api/events/rules \ -H 'Content-Type: application/json' \ -d '{ "name": "sensitive-write-alert", "connection": "analytics", "eventTypes": ["transaction_commit"], "sqlPattern": "sensitive_data", "destinationIds": ["webhook-prod"] }' → SET events_destination='tmg-event-relay ...' → SET events_types=['transaction_commit'] → SET events_async=true → every matching commit → webhook (throttled)
A rule can fan out to any combination of destinations. Webhook bearer tokens are DPAPI-encrypted at rest and never appear in summary JSON — the same secret envelope the ServiceNow and connector profiles use.
POST each event JSON to your endpoint with a bearer token. Configurable timeout (default 10 s). Fire-and-count-failures in v1.
Live browser feed in the events panel — a recent-event ring (default 100) plus a drop-oldest SSE stream that never blocks the query thread.
Append each event as a line to an audit log on disk — the compliance / after-action record.
Pipe each event to an arbitrary local program's stdin — trigger a script, ring a bell, feed a SIEM forwarder.
| Group | Endpoint | Notes |
|---|---|---|
| Capability | GET /api/events/capabilities | Reports extensionInstalled per connection + active-rule totals |
| Rules | GET / POST /api/events/rules | List / create a rule (event types × SQL pattern × destinations) |
| Rules | POST /api/events/rules/{id}/start | Arm — returns 503 + install hint if the events extension is missing |
| Rules | POST /api/events/rules/{id}/stop | Disarm (SET events_types=[]) + stop the relay |
| Destinations | GET / POST /api/events/destinations | CRUD; webhook secret DPAPI-encrypted, "never surface back, only replace" |
| Destinations | POST /api/events/destinations/{id}/test | Send a synthetic event to verify wiring |
| Live | GET /api/events/recent · /api/events/stream | Recent ring + SSE event stream |
Base URL http://localhost:5059. Storage: GPKG at <dataDir>/gpkg/event_rules.gpkg (three tables, cascade-delete junction). Documented in EVENTS_GUIDE.md. The events extension is a DuckDB community extension; availability on Windows x64 is version-dependent — missing extension degrades to 503 + INSTALL events FROM community; LOAD events;, never a crash.
Events:Enabled=false). Arming a rule hooks every query on the chosen connection — opt-in by design. Project switch stops relays armed on the projecthub connection; rules on analytics/connectors survive.Event-driven automation over your geospatial warehouse — without a message broker or a cloud function.