master-zapier-plan-draft/docs/developer/debugging.md
George Lambert b4150c8250 Milestone 0: import zappier billing, Verae middleware, and Zapier research
Compose-ready workspace: packages/zappier (rate card, portal, Stripe),
packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier
(CLI app), vendor/zapier-platform, and research/zapier vendor corpus.

Gate 0 structure checks pass. Product code and research are not yet wired.
2026-09-09 02:37:36 -04:00

147 lines
3.7 KiB
Markdown

# Runtime Debugging and Failure Tracing
## Goals
- Trace failures across **HTTP → NATS → Verae → Zapier webhook** without redeploying.
- Keep secrets out of logs even when debug is enabled.
- Allow selective namespaces so production noise stays low.
## Enabling debug (runtime)
Debug is **off** when `DEBUG_VERAE` is unset or empty.
```bash
# Everything
export DEBUG_VERAE=1
# or
export DEBUG_VERAE=*
# Selected namespaces (comma-separated)
export DEBUG_VERAE=auth,nats,jobs,webhooks,http,billing,trace
# Minimum level: debug | info | warn | error
export DEBUG_VERAE_LEVEL=debug
# Optional: write to file as well as stderr
export DEBUG_VERAE_FILE=/var/log/verae-zapier-debug.log
```
Restart is **not** required if the process reads env only at boot — current implementation reads env at process start. To change flags:
```bash
# systemd / docker: update env and restart one replica
# or send future SIGHUP support (Phase 15)
```
### Docker example
```yaml
environment:
DEBUG_VERAE: "auth,jobs,nats,webhooks"
DEBUG_VERAE_LEVEL: "debug"
```
## Namespaces
| Namespace | What it traces |
|-----------|----------------|
| `auth` | API key resolve, session parse, login outcomes (no passwords) |
| `billing` | Entitlement checks, quota decisions, plan limits |
| `http` | Outbound Verae requests: method, path, status, duration |
| `nats` | Connect, publish, consume, ack/nak, stream ensure |
| `jobs` | Watch enqueue, poll attempts, terminal transitions |
| `webhooks` | Subscribe, deliver attempts, HTTP status to Zapier |
| `trace` | Correlation id enter/exit spans |
| `app` | Boot, config summary (redacted), shutdown |
`DEBUG_VERAE=1` or `*` enables **all** namespaces.
## Correlation IDs
Every inbound HTTP request should get a `traceId` (generated or from `X-Trace-Id` header).
That id is:
- returned optionally as `X-Trace-Id` on responses,
- attached to NATS payloads as `traceId`,
- included in every debug line for that flow.
Example log line:
```text
2026-08-11T16:00:00.000Z DEBUG jobs [trace=a1b2c3d4] poll attempt=3 jobId=550e… status=pending
```
## Redaction rules
Always redacted (replaced with `[REDACTED]`):
- Headers: `authorization`, `x-api-key`, `cookie`
- Fields named: `password`, `veraePassword`, `token`, `veraeToken`, `accessToken`, `apiKey`, `api_key`, `secret`
- String values matching: `Bearer …`, `zmw_…`, `zmt_…`, long JWTs (`eyJ…`)
`targetUrl` host is kept; query string may be stripped if it contains tokens.
## Using debug for common failures
### 401 from middleware
```bash
DEBUG_VERAE=auth,trace npm start
# reproduce Zapier connection test
# look for resolveAuthContext failures
```
### Job never completes / trigger never fires
```bash
DEBUG_VERAE=jobs,nats,webhooks,http
# confirm: watch published → poll status → event emitted → deliver POST status
```
### 402 quota
```bash
DEBUG_VERAE=billing
# confirm plan limits vs usage counters
```
### Verae upstream errors
```bash
DEBUG_VERAE=http,jobs
# status codes and paths only; body may be summarized
```
## Programmatic API
See [modules/debug.md](modules/debug.md) and source under `verae-zapier-middleware/src/debug/`.
```js
import { createDebugger } from '../debug/logger.js';
import { withTrace, getTraceId } from '../debug/trace.js';
const log = createDebugger('jobs');
log.debug('poll start', { jobId });
log.error('poll failed', { jobId, err: err.message });
```
## Tests
Phase 1 gate verifies:
- silence when disabled,
- namespace filtering,
- redaction,
- trace id propagation.
```bash
npm run gate:1
```
## Production caution
- Prefer staging with narrowed namespaces.
- Never commit files containing live debug output with customer data.
- CI should run with debug off except dedicated debug unit tests that assert redaction.