Prepare the application for production
Tenchi keeps production infrastructure outside the framework core, but it gives each concern a defined place. Process resources live in lifespan, request resources live in the context scope, external systems sit behind application-owned ports, and operational entrypoints call the same use cases as HTTP.
This guide turns that model into an ordered production checklist for a service that needs to survive retries, concurrent writes, partial failures, and deployment changes.
Prepare the API for deployment
Start with the resources and behavior your API already uses:
- Validate configuration and secrets at startup.
- Give each connection pool and SDK client a lifespan that closes it on shutdown. If requests write to a database, configure transactions that commit on success and roll back on failure.
- For protected operations, authenticate callers and authorize their actions. Keep credentials and identity out of request data.
- Configure body limits, deadlines, health checks, and your ASGI process and proxy using the deployment guide.
- Record outcomes so you can investigate errors and latency without logging request bodies or credentials.
- Run
tenchi checkand review API compatibility against the version callers currently use. Follow the release sequence to verify and deploy the finished application.
Test business behavior with memory adapters, then test real transactions and lifespan behavior through in-process HTTP clients.
Add safeguards for the capabilities you use
An HTTP API can ship without jobs, tools, evaluations, or business quotas. Use the following guides when their conditions apply:
| If your application… | Prepare this before deployment |
|---|---|
| Accepts commands callers may retry | Idempotency with durable storage in the same transaction as protected writes |
| Calls external services | Bounded retries and failure handling, with provider timeouts and explicit retry-safe operations |
| Enforces per-user or per-tenant quotas | Rate limits backed by shared storage; configure edge limits separately for request floods |
| Receives signed provider callbacks | Webhook verification, timestamp checks, and duplicate-delivery handling |
| Enqueues background work | Durable jobs, worker deadlines, acknowledgement, retries, and dead-letter handling |
| Needs maintenance commands | Operational tasks, operator access, and application-defined dry runs |
| Exposes application tools | Tool contracts and, for MCP, authentication, visibility, and approval |
| Uses model-backed behavior | Evaluations with suitable cases, thresholds, deadlines, and usage budgets |
| Depends on external deployment resources | Read-only preflight checks for connectivity, permissions, and schema readiness |
Tenchi provides contracts, validation, and lifecycle integration. You choose database drivers, migrations, identity providers, queues, schedulers, and telemetry exporters, and connect them through application-owned adapters.
Choose a consistency requirement before an adapter
A port should say what its caller needs, not which vendor implements it. A command repository normally needs strong reads and writes in the current transaction. A search port can explicitly permit stale results and use a read replica. A notification port can promise only that work was durably accepted, not that an email was delivered during the request.
Keep those meanings visible in method names and docstrings. Wiring can then change from SQLite to PostgreSQL, an in-process adapter to a service client, or a primary connection to a replica without silently weakening a use case.
Define the failure owner
For every boundary, decide which component owns each outcome:
- A contract owns valid HTTP inputs, outputs, and declared application errors.
- A request context owns commit or rollback.
- A use case owns business rejection through
AppError. - Tenchi job primitives validate producer messages, consumer input, and handler results.
- A worker owns acknowledgement, retry, dead-lettering, and backoff.
- A deployment process owns migrations and compatibility with the previous release.
- An observer reports an outcome but never changes it.
This avoids ambiguous failures such as retrying invalid payloads forever, committing state before its outbox record, or treating a logging outage as an API failure.
Continue with the deployment guide for process configuration, release verification, rollout, and rollback.