# Doctor

> Audits an existing PagoKit integration in the current project against the generated per-provider checklist, so it covers every provider in the catalog rather than a hardcoded few. Checks .gitignore covers .env, that env vars are present and use test-key prefixes, that the webhook secret looks valid, that the webhook handler verifies signatures, that the minimum events for the integrated provider are routed, and that PAGOKIT_INTEGRATION.md exists. Used by /pagokit:doctor. Read-only — never writes files.

- Skill: `hainrixz/doctor` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add hainrixz/doctor`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hainrixz/doctor/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: Hainrixz (https://skillmd.com/u/hainrixz)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hainrixz/doctor

---


# doctor

You audit an existing PagoKit-generated integration. Read-only. Never write files.

## Source of truth

The first thing you read is `PAGOKIT_INTEGRATION.md` in the project root. It was written by integration-specialist when the integration was generated and contains:

- The provider id (any entry in the catalog — see `PROVIDER_CHECKS.md` for the full list)
- The list of files created
- The list of events handled vs TODO
- The deploy target
- The detected stack/ORM
- The `last_generated_at` timestamp
- The pinned SDK version

If `PAGOKIT_INTEGRATION.md` does not exist, this is NOT necessarily an error — the user may have an integration that predates PagoKit. In that case, ask the user "I don't see `PAGOKIT_INTEGRATION.md`. Was this integration generated by PagoKit? If not, I can still audit a known provider — which one are you using?"

## Audit checklist

Run each check and report a list of `[OK] / [WARN] / [FAIL]` lines. Group by category. At the end, summarize: "N OK, M warnings, K failures."

### Category 1 — Environment hygiene

| Check | How | Severity |
|---|---|---|
| `.gitignore` exists and includes `.env` (or `.env*` minus `.env.example`) | Read `.gitignore` from project root; walk up to repo root if necessary | FAIL if not covered |
| `.env` not committed to git | If `.git/` exists, check `git ls-files .env` would be empty | FAIL if committed |
| `.env.example` exists | Glob `.env.example` | WARN if missing |
| `.env.example` contains only test-mode values (compare each credential's `live_prefix` from `PROVIDER_CHECKS.md`) | Read it, grep for live prefixes | FAIL if live keys present |

### Category 2 — Required env vars per provider

Read **`skills/doctor/PROVIDER_CHECKS.md`** and find the section for the integrated provider.
It lists every credential that provider needs, its expected format, its scope and the severity
of a miss — generated from the catalog, so it covers every provider PagoKit knows about rather
than a handful frozen into this file.

Then read the user's `.env` (read it, never echo it) and compare.

For each required variable:
- `[OK]` — present and matches pattern
- `[FAIL]` — missing
- `[FAIL]` — present but doesn't match pattern
- `[WARN]` — uses `_live_` / `_prod_` prefix (production key during audit; the user should know)

### Category 3 — Webhook handler quality

For each webhook file declared in `PAGOKIT_INTEGRATION.md` (or detected via `expected_filenames` in the catalog), check it against the provider's section in `PROVIDER_CHECKS.md` — which already states the verification family, the correct secret env var, whether the payload is authoritative, and the replay strategy:

- `[OK/FAIL]` — the file imports or calls the provider's canonical verifier (or carries the `// @pagokit:signature-verified` tag).
- `[OK/FAIL]` — the route uses raw body capture appropriate for the stack (per Rule 5 / SECURITY_RULES.md).
- `[OK/FAIL]` — the handler's switch covers every event in `providers.json.webhook.required_events_minimum`. Unhandled events should at least be logged with a `TODO` comment.
- `[WARN]` — if the file contains `console.log(event)` or similar (Rule 6).
- `[OK/FAIL]` — replay protection: if `replay_mitigation_strategy` requires `event-id-dedup`, look for a query against `webhook_events_processed` (or equivalent).

### Category 4 — Idempotency

- `[OK/FAIL]` — the checkout endpoint generates an idempotency key with `crypto.randomUUID()` / `uuid.uuid4()` / `SecureRandom.uuid` (Rule 4).
- `[OK/FAIL]` — the DB has an `idempotency_keys` table (or equivalent file declared in `PAGOKIT_INTEGRATION.md`).

### Category 5 — DB schema

If the integration declares an ORM (Prisma / Drizzle / SQLAlchemy / Active Record), verify these tables exist in the schema file:

- `payments` (or provider-named, e.g. `stripe_payments`)
- `subscriptions` (if `billing_mode == subscription`)
- `customers`
- `idempotency_keys`
- `webhook_events_processed`

### Category 6 — Production readiness pointer

Last check: does `PAGOKIT_PRODUCTION_CHECKLIST.md` exist in the project root?
- `[OK]` — exists; remind user to read it before flipping to live keys.
- `[WARN]` — missing; suggest re-running `/pagokit:start` to regenerate it.

## Output format

```
PagoKit Doctor — <provider> integration audit
Generated <last_generated_at> · stack: <stack> · deploy: <deploy_target>

Environment hygiene
  [OK]   .gitignore covers .env
  [OK]   .env not tracked in git
  [OK]   .env.example uses test prefixes
  ...

Webhook handler
  [OK]   app/api/webhook/stripe/route.ts verifies signature
  [OK]   raw body captured correctly (Next.js App Router pattern)
  [FAIL] customer.subscription.updated not routed (expected per Rule providers.json)
  ...

(continue per category)

Summary: 17 OK · 2 warnings · 1 failure

Next steps:
1. Route the missing event customer.subscription.updated (see templates/stripe/subscription.md).
2. Address the warnings before going live.
```

## Anti-patterns

- Do NOT echo secret values back to the user when reporting (read `.env` but report `[OK]`/`[FAIL]`, never the value).
- Do NOT write files, run migrations, or modify anything — strictly read-only.
- Do NOT fail loudly if the project has no PagoKit-generated artifacts. Offer to set up an audit for a known provider instead.
- Do NOT recommend fixes that require live keys (e.g., don't tell the user to "go to dashboard and rotate the webhook secret" as the first step — first verify the test sandbox passes).

