# Tasks: slim-payment-providers ## 1. Remove concrete provider modules - [ ] 1.1 Delete `packages/universal/payment-providers/src/providers/stripe/`. - [ ] 1.2 Delete `packages/universal/payment-providers/src/providers/paypal/`. - [ ] 1.3 Delete `packages/universal/payment-providers/src/providers/square/`. - [ ] 1.4 Delete `packages/universal/payment-providers/src/providers/mollie/`. - [ ] 1.5 Delete `packages/universal/payment-providers/src/providers/adyen/`. - [ ] 1.6 Delete the now-empty `src/providers/` directory. - [ ] 1.7 Drop the `SquareConfig` type from `src/types/provider.ts` (it ships with the sibling Square package). - [ ] 1.8 Remove the 5 `./providers//` entries from `package.json#exports`. ## 2. Extract composeAbortSignal as a public helper - [ ] 2.1 Promote the internal `composeSignals` function in `src/http/http.ts` to an exported `composeAbortSignal(internal, external)`. - [ ] 2.2 Re-export `composeAbortSignal` from `src/http/index.ts` and `src/index.ts`. - [ ] 2.3 Extend `src/http/http.test.ts` to cover `composeAbortSignal` directly (internal abort propagates, external abort propagates, already-aborted external triggers immediately, undefined external returns internal). - [ ] 2.4 Update `src/http/http.md` to document `composeAbortSignal`. ## 3. Add PROVIDER_NOT_REGISTERED + PROVIDER_ALREADY_REGISTERED codes - [ ] 3.1 Extend the `PAYMENT_PROVIDER_CODES` registry in `src/error-codes/error-codes.ts` with `PROVIDER_NOT_REGISTERED` and `PROVIDER_ALREADY_REGISTERED`. - [ ] 3.2 Add `providerNotRegistered(name)` and `providerAlreadyRegistered(name)` factories. - [ ] 3.3 Extend `src/error-codes/error-codes.test.ts` to confirm both new codes are reachable from their factories and carry the `provider` discriminant when the registry surfaces them. - [ ] 3.4 Update `src/error-codes/error-codes.md` to list all 6 codes. ## 4. Build ProviderRegistry - [ ] 4.1 Create `src/registry/registry.ts` exporting a `ProviderRegistry` class with `register`, `unregister`, `get`, `has`, `list`, `size`. - [ ] 4.2 `get(name)` MUST throw `PaymentProviderError(PROVIDER_NOT_REGISTERED)` on miss. - [ ] 4.3 `register(provider)` MUST throw `PaymentProviderError(PROVIDER_ALREADY_REGISTERED)` when the name is already present. - [ ] 4.4 `list()` MUST return a frozen array in insertion order. - [ ] 4.5 Create `src/registry/registry.md` with the §4 mandatory sections (Purpose, Features, Basic + Advanced usage, API Reference, Implementation Notes). - [ ] 4.6 Create `src/registry/registry.test.ts` covering every public method, both error paths, and the insertion-order guarantee. ## 5. Add definePaymentProvider factory - [ ] 5.1 Create `src/registry/define.ts` exporting `definePaymentProvider(spec)`. - [ ] 5.2 Result MUST be frozen and MUST carry the literal `TName`. - [ ] 5.3 Method identities MUST be preserved (the closure passed in IS the closure dispatched at call time). - [ ] 5.4 Create `src/registry/define.md` with the §4 mandatory sections. - [ ] 5.5 Create `src/registry/define.test.ts` covering the literal-type narrowing, frozen-shape guarantee, method-identity preservation, and the round-trip through `ProviderRegistry.register`. ## 6. Update barrels + subpath exports - [ ] 6.1 Create `src/registry/index.ts` re-exporting `ProviderRegistry` and `definePaymentProvider` via explicit named exports (rule 6a). - [ ] 6.2 Rewrite `src/index.ts` to drop the 5 provider class exports and the `SquareConfig` type export, and add `ProviderRegistry`, `definePaymentProvider`, `composeAbortSignal`, `providerNotRegistered`, `providerAlreadyRegistered`. - [ ] 6.3 Add `./registry/registry` to `package.json#exports`. Final count: 5 entries (`.`, `./types/provider`, `./error-codes/error-codes`, `./http/http`, `./registry/registry`). - [ ] 6.4 Update `package.json#description` to describe the slim core. ## 7. Update README.md - [ ] 7.1 Rewrite the one-paragraph description to reflect the slim shape. - [ ] 7.2 Rewrite the Quick Start example to use `ProviderRegistry` + a sibling-imported `StripeProvider`. - [ ] 7.3 Rewrite the Features list to drop the 5-adapter language and describe the foundation surface. - [ ] 7.4 Rewrite the Modules list — only `types/provider`, `error-codes/error-codes`, `http/http`, `registry/registry`. - [ ] 7.5 Add a "Sibling provider packages" section linking the 5 follow-up packages by name (note they are not yet published). ## 8. Verification gates (§13) - [ ] 8.1 Step 0 — spec reconciliation: walk every `### Requirement` in the delta, grep `src/` for the named symbols, confirm every `**Verified by:**` test name appears in the matching test file. - [ ] 8.2 Step 1 — `bunx turbo lint typecheck test --filter=@suaveplan/payment-providers`. - [ ] 8.3 Step 2 — `bunx turbo test:coverage --filter=@suaveplan/payment-providers` reports 100/100/100/100. - [ ] 8.4 Step 3 — `bunx turbo build --filter=@suaveplan/payment-providers`. - [ ] 8.5 Step 4 — banned-pattern scan returns zero output. - [ ] 8.6 Step 4a — barrel-shape scan returns zero output (no `export *` in any `/index.ts`). - [ ] 8.7 Step 4b — test-runner import scan returns zero output (no direct `vitest` / `bun:test` imports). - [ ] 8.8 Step 5 — every `.ts` (excl. `.test.ts`, `.types.ts`, `index.ts`) has a sibling `.md`. - [ ] 8.9 Step 6 — `README.md` exists. - [ ] 8.10 Step 7 — no bare versions in `package.json`. - [ ] 8.11 Step 8 — subpath-export count matches the feature-module count (4 features + root = 5 entries). - [ ] 8.12 Step 9 — security scan returns zero output. - [ ] 8.13 Step 10 — dependent sweep: `bunx turbo test --filter=...@suaveplan/payment-providers` green (currently only the package itself). ## 9. Root-doc refresh (§13b) - [ ] 9.1 Run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`. - [ ] 9.2 Run `bun scripts/generate-missing.ts` to refresh `MISSING.yml`. - [ ] 9.3 Hand-edit `STATUS.md` row for `@suaveplan/payment-providers` to describe the slim shape (no row flip — package stays ✅). - [ ] 9.4 Hand-edit `SUMMARY.md` paragraph for `@suaveplan/payment-providers` to describe the slim shape. - [ ] 9.5 `bunx markdownlint-cli2 --fix` across touched docs. ## 10. Fold + archive (§14) - [ ] 10.1 Fold `specs/payment-providers/spec.md` into `openspec/specs/payment-providers/spec.md` — apply the `## REMOVED` block (delete the 5 provider requirements + drop `SquareConfig` from the http/types requirement) and apply the `## ADDED` block (add the `ProviderRegistry`, `definePaymentProvider`, `composeAbortSignal`, and registry-code requirements). - [ ] 10.2 Move `openspec/changes/slim-payment-providers/` → `openspec/archive/2026-05-17-slim-payment-providers/`.