Inspired by the concept of invariant-driven automated testing: instead of only checking payload shape, APOPHIS encodes intended behavior as executable contracts and verifies them with property-based and stateful testing.
Add one behavioral contract next to a route schema. APOPHIS can verify cross-route behavior, such as whether a resource created by one route is retrievable through another.
// Register swagger, auth, plugins, and routes after app creation.
```
**Existing projects:** Register APOPHIS or install route discovery before routes. Run `apophis doctor` to verify routes are discovered with full schema metadata.
**Schema-less fallback:** If APOPHIS is registered after routes, `printRoutes()` can recover paths but not route schemas or behavioral contracts. `apophis doctor` and `apophis verify` will warn when discovery is schema-less.
## Current Limitations
These reflect current implementation behavior. All are actively tracked for improvement.
- **Route discovery requires ordering.** If the APOPHIS plugin or route discovery hook is not installed before routes are registered, behavioral contract annotations (x-ensures, x-requires, x-outbound, x-variants, x-timeout) cannot be recovered. Use `createFastify()` for new projects or register APOPHIS early.
- **Observe has two faces.** The runtime plugin supports non-blocking sink emission via `observe.enabled` + `observe.sinks` when registered programmatically. `apophis observe` CLI validates config readiness; it does not activate a long-running runtime observer. See `docs/observe.md` for the distinction between programmatic runtime observation and CLI config validation.
- **CLI verify samples once per contract by default.** Set `runs` in your preset to increase the number of property-based test samples per route. The programmatic `fastify.apophis.contract()` API supports the same `runs` configuration.
- **Outbound mocks are process-global.** The mock runtime patches `globalThis.fetch`. Only one mock runtime can be installed at a time. Run mock-dependent tests serially or isolate by process. Undici `MockAgent` integration is not yet implemented.
- **Qualify coverage depends on profile configuration.** Qualify runs scenario, stateful, and chaos checks based on profile gates. Chaos route selection uses the configured strategy (one/all/sample/routes).
## Compatibility
- **Fastify v5 only.** Fastify v4 and earlier are not supported.
- **ESM only.** This package is `"type": "module"` and does not provide a CommonJS build. Use `import` syntax.
- **Node.js `>=20.18.1 <21 || >=22 <23`**.
- **`@fastify/swagger` must be registered before routes** (APOPHIS auto-registers it if missing).