Skip to content

Latest commit

 

History

History
80 lines (62 loc) · 3.02 KB

File metadata and controls

80 lines (62 loc) · 3.02 KB

Repository Instructions

Product goal

Provide honest, executable evidence for a Stripe-like webhook and entitlement rescue method without client code, real payment data, hosted infrastructure, or production credentials.

Architecture

  • strict TypeScript targeting Node.js 20+
  • injected authoritative-subscription reader boundary
  • in-memory deterministic event, invoice, refund, and dead-letter stores
  • HMAC-style local signature harness using synthetic secrets
  • Node.js native test runner
  • audit, rollback, risk, and run evidence under docs/ and runs/

Commands

npm ci
npm run typecheck
npm run lint
npm run check:project
npm run secret:scan
npm run check
npm test
npm run ci

Environment and secret boundaries

No environment variables are required to run the reference. .env.example contains names and blank values only. Never add Stripe keys, webhook secrets, OAuth tokens, real event payloads, customer/payment data, private URLs, or client code. Keep signature fixtures visibly synthetic.

State and migration rules

  • Event IDs are the idempotency boundary and must remain unique.
  • Lifecycle reconciliation must come from the authoritative reader boundary.
  • A lower lifecycle version must never replace a higher one.
  • Invoice ordering remains per invoice and separate from lifecycle ordering.
  • Refund/charge data must never silently act as a cancellation.
  • Entitlements must be derived server-side from stored state.
  • Processing failures must remain visible until explicit replay resolves them.
  • A rollback must fail closed; never restore unsigned or non-idempotent handling.

Deployment target

None. This is a local and CI reference harness, not a deployed webhook service. Production adaptation requires a durable database, queue, official provider SDK, monitored dead-letter path, authentication, and infrastructure review.

Verification checklist

  • npm ci succeeds from the committed lockfile
  • typecheck, deterministic lint, project/link/YAML checks, and secret scan pass
  • forged and stale signatures cause zero mutation
  • duplicate IDs cannot apply twice
  • stale lifecycle and invoice deliveries cannot roll state backward
  • invoice paid and payment failed transitions affect access explicitly
  • refund data remains separate from lifecycle
  • subscription deletion revokes access
  • a synthetic authoritative failure is visible and replayable
  • public docs disclose synthetic reference work and material residual risk

Definition of done

A change is complete only when the clean install, full npm run ci, public claims, run manifest, rollback posture, and residual-risk statement agree. A passing local harness must never be represented as production or client proof.

High-risk files

  • src/signature.ts: request authenticity and replay-window boundary
  • src/processor.ts: idempotency, event ordering, and dead-letter state
  • src/entitlement.ts: access-grant decision
  • test/webhook-rescue.test.ts: claims must not outpace assertions
  • docs/operations/rollback-runbook.md: recovery must remain fail closed