Sketch aggregates, events, and bounded contexts. In Protean that model is the architecture, and everything else, the API, the docs, the contracts, is derived from it.
@domain.aggregate class Order: customer_id: Identifier(required=True) status: String(max_length=20, default="draft") items = HasMany("OrderItem") @invariant.post def must_have_items_when_placed(self): if self.status != "draft" and not self.items: raise ValidationError(...) # rejected at construction. invalid state cannot exist. Order(customer_id="c-1", status="confirmed") ValidationError: Order must have at least one item
Four capabilities, each one following from a single idea: the model is the source of truth, and it is trustworthy enough to build everything else on.
Protean parses your model into a machine-readable Intermediate Representation. Docs, API specs, and contracts are derived from it, so they cannot drift from the code.
Domain objects are always valid, or they do not exist. Four layers of validation run on every change, and the structure is checked before the first request.
Start with plain domain-driven design. Add CQRS or event sourcing for one aggregate at a time, in the same codebase, with no rewrite.
Your domain knows nothing about databases, brokers, or caches. You swap them in configuration, and the model, the tests, and the rules stay untouched.
A real Protean domain, running on Pyodide in this page. Press check and Protean reads the design back: what each aggregate enforces, what it is missing, why it matters, and how to fix it. The code is editable, and nothing leaves your browser.
Order has no pre/post invariants (own or
inherited); it enforces no business rules and may be an anemic data holder.@invariant.pre or
@invariant.post methods expressing the business rules the aggregate must
always satisfy, or reconsider whether this concept is an aggregate at all.Order has no command handler, no write
path existsFirst check downloads the Python runtime, about 8 MB over the wire, then it is cached by the browser.
Add a field to an Order in most stacks and you touch it in nine places: the model, the migration, the schema, the spec, the client types, the docs, the fixtures, the event, the version.
In Protean you touch the model. Everything that can be derived is derived, so the drift that pulls a real system away from its own drawing has nowhere to enter.
Your domain model does not change. Protean moves the seams, from in-process calls to a message broker, through configuration, so the deployment shape becomes a setting you choose.
The domain model is identical in all three. Only the infrastructure changes.
Every external concern sits behind a port. Choose an adapter, or write one, and Protean wires it into your domain.
Development happens on GitHub in public. Releases ship every couple of weeks, and the whole history is there to read.
One source of truth, an always-valid domain, and why both matter more now that machines write the code.
Built for backend systems whose hard part is the business rules and the states things move through. It is honest about where it stops. Is Protean for you?
About twenty minutes from install to a running, event-driven domain, with no infrastructure decisions required to start.