How factos_pog Works
Storage
factos.factos_events is an append-only, globally ordered event log. Each row
stores the event id, type, version, tags, metadata, and JSON payload.
factos.factos_event_tags stores one row per event tag. Decision-context reads
can combine the event-type and tag indexes without parsing payloads.
Dispatch transaction
A dispatch runs one PostgreSQL SERIALIZABLE transaction:
- select and decode the decision context;
- fold matching events from the model’s initial state;
- apply the model’s decision function;
- insert the accepted batch if the context is still current;
- run subscriptions on the transaction connection;
- commit and return the recorded events.
The append uses one statement for the entire accepted event batch. A failed subscription rolls back all event, tag, and subscription writes.
Retries
Serialization failures (40001) and deadlocks (40P01) retry the complete
transaction up to the configured attempt count. Decision functions, codecs,
event-id allocation, and subscription planning must therefore be retry-safe.
Domain, codec, and subscription errors are returned without retrying.
Decision contexts
NoContextskips history and appends unconditionally.AllEventsprotects the complete event log.Matching(items:)builds an OR of type-and-tag predicates.
The transaction’s serializable predicate locks protect the same facts used by the decision.
Recovery
read_after reads globally ordered pages without running a command. Recovery
state, checkpoints, and replay policy remain application-owned.
Migrations
priv/migrations.sql is the current schema. priv/dbmate/ contains the ordered
migration history, including the v1-to-v2 cutover. Applications should apply
these migrations before their own projection or job schemas.