EVERBOOK
The Journal

The event that builds itself

engineeringfor wedding professionalsAugust 24, 20262 minute read

The moment a couple accepts a proposal, an event has to exist. It needs an event record, a banquet event order attached to it, and every number the proposal agreed to, already in place. Nobody should have to create it. Nobody should be able to forget to.

There are two places to build that guarantee. You can put it in application code: after the acceptance endpoint runs, call a function that creates the event, then another that creates the BEO, then copy the line items across. Or you can put it in the database itself, so that inserting an event is what creates its BEO, on the same transaction, every time.

We chose the database. The mechanism is a trigger, and it is deliberately boring:

create trigger create_beo_after_event
  after insert on events
  for each row
  execute function create_beo_for_event();

Why not application code

Application code only runs when the application is the one doing the work. Events do not only arrive through the accept button. They arrive through migrations from an operator’s old system. They arrive through imports, support fixes, and API calls that did not exist when the endpoint was written. Each of those paths would need to remember the same steps, in the same order, forever. One of them eventually would not.

A trigger does not care who did the insert. The invariant lives next to the data it protects. If an event exists, its BEO exists. There is no code path that produces the broken state, so there is no code review that has to catch it.

The rule that keeps triggers safe

Triggers earn their bad reputation when they hide business logic. Ours follow one rule: a trigger enforces existence, never behavior. It creates the record that must exist. It does not price anything, notify anyone, or branch on the kind of event. Those decisions belong in code you can read, test, and change without a migration.

The same idea runs through the whole platform. One event record, many readers. The caterer’s prep sheet, the invoice, and the timeline all read the same row, so a changed guest count is one write, not a chase across copies. The trigger is just the smallest version of that promise: the record you depend on is already there.

Elsewhere in the Journal

See the event record build itself from a booked proposal.