211 lines
4.2 KiB
Markdown
211 lines
4.2 KiB
Markdown
# Getting Started with APOPHIS
|
|
|
|
Get from install to your first behavioral bug in 10 minutes.
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 20.x or 22.x
|
|
- A Fastify app with `@fastify/swagger` registered
|
|
|
|
## Step 1: Install
|
|
|
|
```bash
|
|
npm install apophis-fastify fastify @fastify/swagger
|
|
```
|
|
|
|
## Step 2: Scaffold
|
|
|
|
```bash
|
|
apophis init --preset safe-ci
|
|
```
|
|
|
|
This creates:
|
|
|
|
- `apophis.config.js` — config with a `quick` profile
|
|
- `APOPHIS.md` — preset-specific guidance
|
|
- Package script: `npm run apophis:verify`
|
|
|
|
## Step 3: Add One Behavioral Contract
|
|
|
|
Pick one important route. Add an `x-ensures` clause that checks behavior across operations:
|
|
|
|
```javascript
|
|
app.post('/users', {
|
|
schema: {
|
|
'x-category': 'constructor',
|
|
'x-ensures': [
|
|
// BEHAVIORAL: Creating a user must make it retrievable
|
|
'response_code(GET /users/{response_body(this).id}) == 200'
|
|
]
|
|
}
|
|
}, async (request, reply) => {
|
|
const { name } = request.body;
|
|
const id = `usr-${Date.now()}`;
|
|
reply.status(201);
|
|
return { id, name };
|
|
});
|
|
```
|
|
|
|
## Step 4: Run Verify
|
|
|
|
```bash
|
|
apophis verify --profile quick --routes "POST /users"
|
|
```
|
|
|
|
APOPHIS will:
|
|
|
|
1. Discover routes from your Fastify app
|
|
2. Filter to `POST /users`
|
|
3. Generate test data from the schema
|
|
4. Execute the route
|
|
5. Check the behavioral contract
|
|
6. Print pass/fail, seed, and replay command
|
|
|
|
## Example Failure
|
|
|
|
If your `GET /users/:id` handler has a bug (always returns 404), APOPHIS catches it:
|
|
|
|
```text
|
|
Contract violation
|
|
POST /users
|
|
Profile: quick
|
|
Seed: 42
|
|
|
|
Expected
|
|
response_code(GET /users/{response_body(this).id}) == 200
|
|
|
|
Observed
|
|
GET /users/usr-123 returned 404
|
|
|
|
Why this matters
|
|
The resource created by POST /users is not retrievable.
|
|
|
|
Replay
|
|
apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json
|
|
|
|
Next
|
|
Check the create/read consistency for POST /users and GET /users/{id}.
|
|
```
|
|
|
|
## Step 5: Replay and Fix
|
|
|
|
Copy the replay command and run it:
|
|
|
|
```bash
|
|
apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json
|
|
```
|
|
|
|
Fix the bug in your handler. Re-run verify. The failure should now pass.
|
|
|
|
## Next Steps
|
|
|
|
- Add more routes to your profile: `apophis verify --profile quick --routes "POST /users,PUT /users/:id"`
|
|
- Run all routes: `apophis verify --profile quick`
|
|
- Run only changed routes in CI: `apophis verify --profile ci --changed`
|
|
- Add observe mode for runtime drift detection: see [docs/observe.md](docs/observe.md)
|
|
- Add qualify mode for scenario, stateful, and chaos checks: see [docs/qualify.md](docs/qualify.md)
|
|
|
|
## Config Reference
|
|
|
|
```javascript
|
|
// apophis.config.js
|
|
export default {
|
|
mode: 'verify',
|
|
profile: 'quick',
|
|
profiles: {
|
|
quick: {
|
|
name: 'quick',
|
|
mode: 'verify',
|
|
preset: 'safe-ci',
|
|
routes: ['POST /users']
|
|
},
|
|
ci: {
|
|
name: 'ci',
|
|
mode: 'verify',
|
|
preset: 'safe-ci',
|
|
routes: []
|
|
}
|
|
},
|
|
presets: {
|
|
'safe-ci': {
|
|
name: 'safe-ci',
|
|
depth: 'quick',
|
|
timeout: 5000,
|
|
parallel: false,
|
|
chaos: false,
|
|
observe: false
|
|
}
|
|
},
|
|
environments: {
|
|
local: {
|
|
name: 'local',
|
|
allowVerify: true,
|
|
allowObserve: true,
|
|
allowQualify: false,
|
|
allowChaos: false,
|
|
allowBlocking: true,
|
|
requireSink: false
|
|
}
|
|
}
|
|
};
|
|
```
|
|
|
|
## Monorepo Workspaces
|
|
|
|
APOPHIS supports workspace-wide operations with the `--workspace` flag.
|
|
|
|
### Root package.json scripts
|
|
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"apophis:verify": "apophis verify --workspace --profile quick",
|
|
"apophis:doctor": "apophis doctor --workspace",
|
|
"apophis:qualify": "apophis qualify --workspace --profile ci"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Workspace fan-out
|
|
|
|
Run verify across all packages:
|
|
|
|
```bash
|
|
apophis verify --workspace --profile quick --format json
|
|
```
|
|
|
|
Output is package-attributed:
|
|
|
|
```json
|
|
{
|
|
"exitCode": 0,
|
|
"runs": [
|
|
{
|
|
"package": "api",
|
|
"cwd": "/repo/packages/api",
|
|
"artifact": { ... }
|
|
},
|
|
{
|
|
"package": "web",
|
|
"cwd": "/repo/packages/web",
|
|
"artifact": { ... }
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Supported commands
|
|
|
|
- `apophis verify --workspace`
|
|
- `apophis doctor --workspace`
|
|
|
|
## Exit Codes
|
|
|
|
| Code | Meaning |
|
|
|---|---|
|
|
| 0 | Success |
|
|
| 1 | Behavioral / qualification failure |
|
|
| 2 | Usage, config, or environment safety violation |
|
|
| 3 | Internal APOPHIS error |
|
|
| 130 | Interrupted (SIGINT) |
|