External systems
An external system is a dependency or participant outside the generated application’s operational boundary. Model the contract the product depends on, not a vendor SDK copied into domain logic.
Define the port
Section titled “Define the port”An external-system definition can capture:
- direction: inbound, outbound, or both;
- kind: payment, identity, tax, messaging, logistics, or generic;
- transport: HTTP, gRPC, AMQP, SQS, Kafka, or custom;
- authentication method;
- synchronous capabilities and typed errors;
- asynchronous callbacks and signature requirements;
- rate limits and provider documentation;
- the environment-variable names used for endpoints and credentials.
This gives the generator enough information to create an adapter boundary while keeping secrets outside the model.
Capabilities
Section titled “Capabilities”A capability is a synchronous operation exposed by the external system. Define typed inputs, output shape, and error codes.
PaymentProvider.authorize(amount, currency, paymentMethodToken) → authorizationId, status errors: declined, timeout, invalid_tokenThe product model decides what each outcome means. The adapter translates vendor-specific responses into the declared contract.
Callbacks
Section titled “Callbacks”A callback is an asynchronous message the provider sends to the application. Declare payload shape and signature method. Bind it to an event or system-initiated action so retries and idempotency have an explicit target.
Treat callbacks as untrusted input: verify signatures, reject replay where required, and record provider identifiers used for deduplication.
Configuration changes are not product changes
Section titled “Configuration changes are not product changes”If a provider changes its endpoint or rotates a credential while the contract remains the same, update the add-on or runtime configuration. No application regeneration is normally required.
If the provider changes behavior or payload shape, update the integration contract or generator adapter, regenerate, test, and deliver a new release.
Failure semantics
Section titled “Failure semantics”Model what the product does when a dependency is slow, unavailable, or returns an uncertain outcome:
- retry with bounded backoff;
- queue work for later;
- open a circuit and degrade gracefully;
- mark the operation pending reconciliation;
- compensate through a separate action;
- require operator review.
Never model “retry forever.” Every async path needs observability and a terminal or inspectable state.
Planned integrations
Section titled “Planned integrations”An integration can be recorded as planned without inventing a fake endpoint or pretending it is wired. Planned ports preserve roadmap intent while keeping the generated release honest.
See Configuration and secrets and Incidents for runtime response.
