Skip to content
Back to skills

Doctor

ASecurity

Audits an existing PagoKit integration in the current project. 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.

  • 37 stars
  • 0 votes
  • 1 copy
  • 8 views
  • Added May 28, 2026
developmentgobashsqlnextjsgitapisecurity

Works with

  • api

Security analysis

A100/100

Scanned May 28, 2026

npx -y skills add Hainrixz/agente-pagokit --skill doctor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Doctor?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Doctor
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hainrixz-doctor/badge)](https://www.skillsdirectory.com/skills/hainrixz-doctor)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: doctor
description: Audits an existing PagoKit integration in the current project. 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.
when_to_use: |
  - The user invokes /pagokit:doctor
  - The user asks "is my payment integration set up correctly?", "did I miss something?", "is this safe to ship?"
  - The integration-specialist subagent wants a sanity check before declaring an integration complete
allowed-tools: Read, Glob, Grep, Bash(ls *), Bash(test *)
---

# 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 (`stripe` | `mercadopago` | `wompi` | `lemonsqueezy`)
- 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-key prefixes (from `providers.json.developer_experience.test_keys_prefix`) | Read it, grep for live prefixes | FAIL if live keys present |

### Category 2 — Required env vars per provider

Load `providers.json`. For the integrated provider, the user's `.env` (read but don't echo!) should contain at minimum:

- Stripe: `STRIPE_SECRET_KEY` starting with `sk_test_` or `sk_live_`; `STRIPE_PUBLISHABLE_KEY` starting with `pk_`; `STRIPE_WEBHOOK_SECRET` starting with `whsec_`.
- Mercado Pago: `MP_ACCESS_TOKEN` matching `secret_key_pattern`; `MP_WEBHOOK_SECRET`.
- Wompi: `WOMPI_PRIVATE_KEY` matching `^prv_(test|prod)_` ; `WOMPI_PUBLIC_KEY` matching `^pub_(test|prod)_` ; `WOMPI_EVENTS_SECRET`.
- Lemon Squeezy: `LEMONSQUEEZY_API_KEY` matching `^lmnsq_(test|live)_`; `LEMONSQUEEZY_WEBHOOK_SECRET`.

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` from `providers.json.webhook`):

- `[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).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.