Fix doc gaps: remove qualify --workspace, add plugin options/schema annotations/programmatic API docs
This commit is contained in:
+1
-1
@@ -221,7 +221,7 @@ apophis replay --artifact reports/apophis/failure-*.json
|
|||||||
|
|
||||||
- `--changed` requires a git repository
|
- `--changed` requires a git repository
|
||||||
- `migrate` defaults to `--dry-run` (safe by default)
|
- `migrate` defaults to `--dry-run` (safe by default)
|
||||||
- `--workspace` is only supported by `verify` and `doctor` commands
|
- `--workspace` is fully implemented by `verify` and `doctor`. `observe` and `qualify` accept the flag but run in the current package only.
|
||||||
- Seeds ensure deterministic generation; handler nondeterminism (e.g., `Date.now()`) can still cause replay divergence
|
- Seeds ensure deterministic generation; handler nondeterminism (e.g., `Date.now()`) can still cause replay divergence
|
||||||
|
|
||||||
## Exit Codes
|
## Exit Codes
|
||||||
|
|||||||
@@ -130,6 +130,102 @@ app.get('/users', {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Plugin Options
|
||||||
|
|
||||||
|
When registering the APOPHIS plugin, you can pass these options:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
await fastify.register(apophis, {
|
||||||
|
// Swagger config passthrough (if @fastify/swagger is not already registered)
|
||||||
|
swagger: { openapi: { info: { title: 'API', version: '1.0.0' } } },
|
||||||
|
|
||||||
|
// Runtime contract validation hooks: 'off', 'warn', or 'error'
|
||||||
|
// Only active in non-production environments
|
||||||
|
runtime: 'warn',
|
||||||
|
|
||||||
|
// Automatically clean up tracked resources after tests
|
||||||
|
cleanup: true,
|
||||||
|
|
||||||
|
// Global timeout in milliseconds for all requests
|
||||||
|
timeout: 5000,
|
||||||
|
|
||||||
|
// Tenant isolation scopes
|
||||||
|
scopes: {
|
||||||
|
tenant1: { headers: { 'x-tenant-id': '1' } },
|
||||||
|
tenant2: { headers: { 'x-tenant-id': '2' } },
|
||||||
|
},
|
||||||
|
|
||||||
|
// Auth and protocol extensions
|
||||||
|
extensions: [jwtAuth, apiKeyAuth],
|
||||||
|
|
||||||
|
// Plugin hook-phase contracts
|
||||||
|
pluginContracts: {
|
||||||
|
'rate-limit': { appliesTo: 'POST /users', ensures: ['status != 429'] },
|
||||||
|
},
|
||||||
|
|
||||||
|
// Outbound dependency contracts
|
||||||
|
outboundContracts: {
|
||||||
|
'payment-api': {
|
||||||
|
target: 'https://payments.example.com',
|
||||||
|
method: 'POST',
|
||||||
|
response: { 200: { type: 'object', properties: { id: { type: 'string' } } } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schema Annotations
|
||||||
|
|
||||||
|
APOPHIS reads these OpenAPI schema extensions:
|
||||||
|
|
||||||
|
| Annotation | Location | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `x-category` | Top-level | Route classification: `constructor`, `mutator`, `observer`, `destructor`, `utility` |
|
||||||
|
| `x-ensures` | Top-level or `response[statusCode]` | Post-condition contracts (APOSTL formulas) |
|
||||||
|
| `x-requires` | Top-level or `response[statusCode]` | Pre-condition contracts (APOSTL formulas) |
|
||||||
|
| `x-variants` | Top-level | Request variants for content-type negotiation or feature flags |
|
||||||
|
| `x-timeout` | Top-level or `response[statusCode]` | Per-route timeout in milliseconds |
|
||||||
|
| `x-outbound` | Top-level | Outbound dependency contracts for this route |
|
||||||
|
| `x-streaming` | Top-level | Mark route as streaming (populates `chunks` and `streamDurationMs` in eval context) |
|
||||||
|
| `x-validate-runtime` | Top-level or `response[statusCode]` | Toggle runtime validation for this route (default: true) |
|
||||||
|
| `x-extension-config` | Top-level | Per-route config for extensions (e.g., `{ jwt: { verify: false } }`) |
|
||||||
|
|
||||||
|
Annotations can be placed on the top-level schema or nested inside `response[statusCode]`. Nested annotations take precedence for that status code.
|
||||||
|
|
||||||
|
## Programmatic API
|
||||||
|
|
||||||
|
After registration, `fastify.apophis` provides:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Run contract tests for all routes
|
||||||
|
const suite = await fastify.apophis.contract({ runs: 50, seed: 42 })
|
||||||
|
|
||||||
|
// Run stateful tests
|
||||||
|
const stateful = await fastify.apophis.stateful({ runs: 50, seed: 42 })
|
||||||
|
|
||||||
|
// Run a single scenario
|
||||||
|
const scenario = await fastify.apophis.scenario({
|
||||||
|
name: 'oauth-basic',
|
||||||
|
steps: [...]
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check a single route
|
||||||
|
const result = await fastify.apophis.check('GET', '/users/:id')
|
||||||
|
|
||||||
|
// Get enriched OpenAPI spec with contract metadata
|
||||||
|
const spec = fastify.apophis.spec()
|
||||||
|
|
||||||
|
// Clean up tracked resources
|
||||||
|
await fastify.apophis.cleanup()
|
||||||
|
|
||||||
|
// Test-only utilities (NODE_ENV=test only)
|
||||||
|
fastify.apophis.test.registerPluginContracts('name', spec)
|
||||||
|
fastify.apophis.test.registerOutboundContracts({ ... })
|
||||||
|
fastify.apophis.test.enableOutboundMocks({ mode: 'example' })
|
||||||
|
fastify.apophis.test.disableOutboundMocks()
|
||||||
|
const calls = fastify.apophis.test.getOutboundCalls('payment-api')
|
||||||
|
```
|
||||||
|
|
||||||
## Config Reference
|
## Config Reference
|
||||||
|
|
||||||
For the full configuration reference, see [CLI Reference](cli.md).
|
For the full configuration reference, see [CLI Reference](cli.md).
|
||||||
|
|||||||
@@ -250,14 +250,6 @@ Human output shows per-gate execution counts (scenario, stateful, chaos, adversi
|
|||||||
|
|
||||||
Qualify exits with code 1 if zero checks executed. This prevents silent passes when all routes are filtered out or gates are disabled.
|
Qualify exits with code 1 if zero checks executed. This prevents silent passes when all routes are filtered out or gates are disabled.
|
||||||
|
|
||||||
## `--workspace` Flag
|
|
||||||
|
|
||||||
Run qualify across all packages in a monorepo workspace:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
apophis qualify --workspace --profile oauth-nightly
|
|
||||||
```
|
|
||||||
|
|
||||||
## Test Budget
|
## Test Budget
|
||||||
|
|
||||||
The `runs` field in your preset controls how many property-based tests execute per route. Default is 50. Lower for faster CI feedback, higher for deeper exploration:
|
The `runs` field in your preset controls how many property-based tests execute per route. Default is 50. Lower for faster CI feedback, higher for deeper exploration:
|
||||||
|
|||||||
Reference in New Issue
Block a user