@fourtheraio/contracts
v0.3.0
Published
Shared Zod schemas for Fourth Era cross-service events. v0.1.0 covers Order and Shipment payloads.
Downloads
433
Readme
@fourtheraio/contracts
Shared Zod schemas for Fourth Era cross-service events. v0.1.0 ships the 11 Order/Shipment payload schemas previously inline in fourth-era-orchestrator/src/events/payload-schemas.ts.
This package follows the @fourtheraio/ naming established by @fourtheraio/observability (2026-04-30 rename precedent). ADR-0001 §D3 references to @fourthera/contracts resolve here.
Install
npm install @fourtheraio/contracts zodzod is a regular dependency, exact-pinned. See "Zod version pinning" below.
What's in v0.1.0
| Domain | Schemas |
| --- | --- |
| Order | OrderConfirmedPayloadV2, OrderCancelledPayloadV2, OrderShippedPayloadV2, OrderDeliveredPayloadV2 |
| Shipment | ShipmentSubmittedPayload, ShipmentAcceptedPayload, ShipmentInTransitPayload, ShipmentDeliveredPayload, ShipmentFailedPayload, ShipmentReturnedPayload, ShipmentDeliveryFailedPayload |
All schemas are exported with their existing names (matching the orchestrator's current usage) to make adoption a one-line import swap.
What's NOT in v0.1.0
- Canonical event envelope schema (planned for a later version)
idempotency_keyformat contract- Membership, commission, invoicing, review, wallet, profile, signup events
Versioning rules
Every PR runs a mechanical shape-diff classifier. See scripts/shape-diff.mjs and tests for the full ruleset. Summary:
| Change | Class |
| --- | --- |
| Added optional field | minor |
| Added required field | major |
| Removed field | major |
| Type narrowed (e.g. string → string.uuid()) | major |
| Type widened | minor |
| Enum narrowed | major |
| Enum widened | minor |
| Object unknown-keys tightened (strip → strict, passthrough → strip/strict) | major |
| Object unknown-keys loosened | minor |
| Schema added | minor |
| Schema removed | major |
Supported Zod features
The shape-diff script in v0.1.0 supports: z.object, z.string (+ .uuid(), .datetime()), z.number (+ .int(), .positive(), .nonnegative()), z.boolean, z.enum, z.array, z.nullable, z.optional.
Not yet supported (presence will fail CI with "extend shape-diff first"):
.refine()/.superRefine()/.transform().default(...)z.lazy()/ recursive schemasz.union/z.discriminatedUnion/z.intersectionz.literalz.record
Extend scripts/shape-diff.mjs (and the test cases) in a separate PR before adding any of the above to a schema.
Zod version pinning
zod is exact-pinned (currently 3.23.8) because the shape-diff script walks Zod's internal _def API. Bumping Zod requires its own PR with diff-script re-baseline review.
Release flow
- Author edits a schema.
- CI runs shape-diff vs
main. Classifies as patch/minor/major. - If major: author adds a
.changeset/*.mdwith migration notes. - CI checks that
package.jsonversion delta ≥ detected class. - Reviewer approves. Merge.
- Locally:
npm run release→ bumps version, generates CHANGELOG, runsnpm publish(gated by Tobias approval).
v0.1.0 init PR exception: no changeset required because there's no prior version to bump from (see Plan ND-1).
Follow-ups
- Orchestrator inline → import migration (separate plan, gated on this package being published successfully to npm — no calendar deadline; see Plan ND-2).
- Envelope + idempotency_key contract (separate spec).
- Per-consumer adoption plans (email-service, commission-engine, invoicing-service, …).
