Skip to main content
These examples describe the current Bijection CLI and SDK source. Use builds from the same repository revision for these APIs. The public CLI and npm SDK are released independently and may lag this reference.
A constraint is a rule about your data that holds after every transaction. You declare it in the schema; Bijection checks it in the final state of every transaction that changes its inputs, whichever function, import or administrative edit made the change. A write that breaks a constraint is refused whole, with ConstraintViolation. Intermediate states inside one transaction may break it as long as the final state holds.

Rules over a view

The ordinary form is a predicate every row of a local view satisfies:
The schema key is the constraint’s name, in snake_case. Constraints read only tables your deployment owns: an observation synced from another system is never refused by a local rule.

Time intervals

v.timeInterval() stores a half-open period { start, end } in exact epoch microseconds, with start before end. Bijection refuses any other value wherever the interval is stored, passed or returned. Index its start to order rows by it:
q.overlaps(a, b) and q.contains(a, b) compare intervals in views and predicates. Touching intervals, such as 08:00–12:00 and 12:00–16:00, do not overlap.

No-overlap and within rules

Two constraint forms hold scheduling rules directly on start-ordered indexes. The index’s fields before during.start are the partition, here one resource:
A within rule needs a disjoint rule on the same container rows. Adjacent containers cover the boundary they share, so a booking from 11:00 to 13:00 fits two shifts that meet at 12:00. Removing or shortening a shift that still holds a booking is refused. Each changed booking is checked against its neighbours in the index, not the whole table, and two transactions that try to place overlapping bookings at the same moment cannot both succeed. A check that cannot decide within its bounds refuses with ConstraintUndetermined instead of letting the write through.

Suggesting slots and rescheduling

scheduleWeights declares soft rules as exact integer weights: lateness per started hour past a job’s due time, moving a booking, changing its resource. scheduling.slots(ctx, ...) in a query returns free, scored slots for a job within at most 31 days and 64 resources, and updates as bookings commit. It reports is_complete: false when it stops at a bound. A slot reserves nothing; book it with your ordinary mutation and the constraints decide. For larger changes, jobShop gives the interval-shaped problem and candidate validators for a customer solver, and verifySchedule rechecks a candidate’s hard rules and recomputes its objective from the same weights before you apply it. partitionJobShop(problem) splits a problem into groups of jobs that can share a resource. Solve, verify and apply each group on its own: the groups share no resource, so their objectives add up, and a booking that changed since capture refuses only its own group. The scheduling example adds skill, release-time, duration and precedence rules as view predicates and expands recurring shift patterns from IANA time zones on a daily cron.