Events & jobs

Modules collaborate without knowing each other through two PostgreSQL mechanisms: an event bus (LISTEN/NOTIFY) and a job queue (SKIP LOCKED).

Events #

A module declares in its manifest what it publishes and what it is subscribed to. The core relays via LISTEN/NOTIFY and logs into core.event_log. Real examples (calendar):

publishes  = ["EventCreated", "EventUpdated", "EventDeleted"]
subscribed = ["UserDeleted", "ContactUpdated"]

Typical payload (JSON):

{ "type": "EventCreated",
  "payload": { "event_id": "…", "user_id": "…", "module_id": "calendar" } }
Note

React to UserDeleted, for example, to purge the user's data from your schema — this is how consistency is kept without direct coupling between modules.

Job queue (SKIP LOCKED) #

For asynchronous work (emails, exports, cleanup, webhooks), push a job into core.jobs; workers claim it with safe concurrency:

SELECT id FROM core.jobs
WHERE status = 'pending' AND run_after <= NOW()
FOR UPDATE SKIP LOCKED
LIMIT 10;

Key fields: job_type, payload (JSONB), status (pendingrunningdone/failed), attempts/max_attempts, run_after (scheduling & retry).