Files
2026-05-27 23:29:53 +01:00

89 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks — add @suaveplan/payment
> Every checkbox MUST reflect work actually done in this change. Retroactive ticking is forbidden.
## 1. Spec authoring
- [x] 1.1 Read `../suaveplan/enterprise/payment.md` end-to-end.
- [x] 1.2 Read upstream source at `../suaveplan/packages/universal/payment/src/` end-to-end.
- [x] 1.3 Read `openspec/AGENTS.md` §13 + §14.
- [x] 1.4 Draft `proposal.md` from template.
- [x] 1.5 Fill `## Source mapping` table — every requirement cites line range or appears in the "no source line" table with justification.
- [x] 1.6 Draft `specs/payment/spec.md` from template.
- [x] 1.7 Every requirement carries a `**Verified by:**` line at draft time.
## 2. Implementation
- [x] 2.1 `src/types/payment.ts` — `PaymentStatus`, `PaymentMethod{,Type}`, `CardBrand`, `PaymentIntent`, `PaymentProvider`, `PaymentEventMap`, `Refund{,Status,Reason,Input}`, `Dispute{,Evidence}`, `CreatePaymentIntentInput`, `VALID_TRANSITIONS` (frozen).
- [x] 2.2 `src/error-codes/error-codes.ts` — `PAYMENT_CODES` (13 codes) via `defineCodes`; `PaymentError extends SuaveplanError<PaymentErrorCode>` with `intentId`/`currentStatus`/`targetStatus`/`ageMs` discriminants; 12 factory functions.
- [x] 2.3 `src/hooks/hooks.ts` — generic `Hooks<TMap>` + `paymentHooks` singleton + `onPaymentProcessing` shortcut.
- [x] 2.4 `src/engine/engine.ts` — `PaymentEngine` over `EventBus<PaymentEventMap>`, state-machine enforcement, refund-balance guard, hook pipeline, explicit `markFailed`/`openDispute`/`closeDispute` emitters.
- [x] 2.5 `src/webhook/webhook.ts` — `WebhookVerifier` using `@suaveplan/crypto-hash` HMAC + `@suaveplan/crypto-utils` `constantTimeEqual`; injectable `now()`.
- [x] 2.6 `src/receipt/receipt.ts` — `ReceiptGenerator` + `resetReceiptCounter` + plain-text renderer; injectable `now()`/`nextId`.
- [x] 2.7 `src/gateway/types.ts` — `PaymentGateway` + `GatewayChargeStatus` + `GatewayResult` + `GatewayCharge` + `ValidationResult` + `ChargeOptions`.
- [x] 2.8 `src/gateway/test.ts` — `TestGateway` + `resetChargeCounter`; injectable `now()`.
- [x] 2.9 `src/gateway/stripe.ts` — `StripeGateway` over injected `FetchLike`; typed-error wrap; status map.
- [x] 2.10 `src/gateway/paypal.ts` — `PayPalGateway` over injected `FetchLike`/`now`/`btoa`; OAuth token cache.
- [x] 2.11 `src/fraud/fraud.ts` — `FraudDetector`; injectable `now()`.
- [x] 2.12 `src/refund/refund.ts` — `RefundManager` + `resetRefundCounter`; typed `PaymentError`s; injectable `now()`/`nextId`.
- [x] 2.13 `src/retry/retry.ts` — `PaymentRetrier`; injectable `random()`/`sleep()`.
- [x] 2.14 `src/tax/tax.ts` — `TaxCalculator`.
- [x] 2.15 `src/tokenization/tokenization.ts` — `CardTokenizer`; typed `PaymentError(INVALID_CARD)`; injectable `SubtleCrypto`/`now()`.
- [x] 2.16 `src/reconciliation/reconciliation.ts` — `PaymentReconciliation`; injectable `now()`.
- [x] 2.17 `src/index.ts` — explicit named root barrel re-exporting every public symbol.
- [x] 2.18 Per-feature `index.ts` barrels — explicit named re-exports only.
- [x] 2.19 `package.json` at `0.1.0` with `workspace:^` for `@suaveplan/{error,events,money,crypto-hash,crypto-utils}` and `catalog:build` for `tslib`; 16 subpath exports; `sideEffects: false`.
- [x] 2.20 `vite.config.ts` + `tsconfig{,.lib}.json` + `vitest.config.ts` + `tests/setup/polyfills.ts`.
## 3. Tests
- [x] 3.1 `src/error-codes/error-codes.test.ts` — registry shape; every code reachable from a factory; discriminants set / unset; cause passthrough on the three cause-bearing factories.
- [x] 3.2 `src/hooks/hooks.test.ts` — no-op pass-through; priority ordering; async handler support; unsubscribe idempotence; clear / count; singleton + shortcut.
- [x] 3.3 `src/engine/engine.test.ts` — every lifecycle method, every transition guard, every provider-error wrap (Error + non-Error throws), out-of-band emitters, `canTransition` matrix.
- [x] 3.4 `src/webhook/webhook.test.ts` — sign determinism; verify valid + expired + future + bad-sig + bad-length-sig + non-hex-sig + odd-length-sig + tampered-body + invalid-JSON + custom tolerance + SHA-512 + Date.now fallback.
- [x] 3.5 `src/receipt/receipt.test.ts` — structured generate, injected nextId + taxLabel, plain-text full + minimal render.
- [x] 3.6 `src/gateway/test.test.ts` — happy + delay + failure + missing charge + shouldFail mid-stream for capture / refund + validate matrix.
- [x] 3.7 `src/gateway/stripe.test.ts` — success / canceled / unknown / HTTP-error paths + capture (with/without amount) + refund (success + fallback) + get (with/without charges array) + validate matrix + baseUrl normalisation.
- [x] 3.8 `src/gateway/paypal.test.ts` — auth + create + token cache + token refresh + auth failure + order failure + custom baseUrl + capture (with/without amount) + refund (success + no-capture + PENDING) + get (aggregation + empty units + unknown status) + validate matrix + empty body.
- [x] 3.9 `src/fraud/fraud.test.ts` — clean allow, missing-customer flag, high-amount flag, velocity → block, between-thresholds review, score cap, reset, early-return when no customerId.
- [x] 3.10 `src/refund/refund.test.ts` — every typed error reachable, summary balances, fullyRefunded flag, byReason filter, canRefund matrix, injected nextId.
- [x] 3.11 `src/retry/retry.test.ts` — success / retry-success / non-retryable result / non-retryable thrown / exhaustion / non-Error wrap / default sleep / calculateDelay matrix (no-jitter / cap / +jitter / -jitter never-negative).
- [x] 3.12 `src/tax/tax.test.ts` — fallback default, region override, removeRate, exclusive, inclusive, exempt, empty input.
- [x] 3.13 `src/tokenization/tokenization.test.ts` — tokenize + custom prefix + bad Luhn + bad month + expired + Luhn matrix + brand matrix (8 brands + unknown).
- [x] 3.14 `src/reconciliation/reconciliation.test.ts` — matched + discrepancy + unmatched (both sides) + status normalisation + reconciledAt clock.
- [x] 3.15 Every `it(...)` carries `{ timeout: 5000 }`.
## 4. Documentation
- [x] 4.1 Sibling `.md` for every implementation `.ts` (16 modules) — ≥200 words, basic + advanced examples, full API reference.
- [x] 4.2 `README.md` linking every co-located `.md` under `## Modules`.
## 5. Pre-archive verification (the 5-gate triple)
- [ ] 5.1 `bun run check` — Biome 0/0/0 across the monorepo.
- [ ] 5.2 `bunx turbo lint typecheck test --filter=@suaveplan/payment` — green.
- [ ] 5.3 `bunx turbo test:coverage --filter=@suaveplan/payment` — 100/100/100/100.
- [ ] 5.4 `bunx turbo build --filter=@suaveplan/payment` — green.
- [ ] 5.5 Banned-pattern scan (`@deprecated`/`TODO`/`FIXME`/`ts-ignore`/`ts-expect-error`/`.skip`/`.only`) — zero output.
## 6. Pre-archive 9-row checklist (AGENTS.md §13)
- [ ] 6.1 Generics threaded; no `any`.
- [ ] 6.2 Zod schemas wired at every declared boundary — N/A (deferred per `## Out of scope`).
- [ ] 6.3 Every error code in `PAYMENT_CODES` thrown by a production path.
- [ ] 6.4 Strict-mode behaviours tested both on and off — N/A (no strict-mode toggle).
- [ ] 6.5 OTel instruments emitted from production paths — N/A (deferred per `## Out of scope`).
- [ ] 6.6 Lifecycle dedup tested where claimed — N/A (idempotency deferred).
- [ ] 6.7 No retroactive tick.
- [ ] 6.8 No `export *` in any feature-module barrel.
- [ ] 6.9 No direct `vitest` / `bun:test` imports in test files.
## 7. Archive
- [ ] 7.1 Fold spec delta into `openspec/specs/payment/spec.md`.
- [ ] 7.2 Move `openspec/changes/add-payment/` → `openspec/archive/2026-05-17-add-payment/`.
- [ ] 7.3 Refresh `MANIFEST.md` via `bun scripts/folder-reorg/generate-manifest.ts`.
- [ ] 7.4 Update `STATUS.md` to flip `@suaveplan/payment` from `–` → `✅`.
- [ ] 7.5 Update `SUMMARY.md` with the shipped surface.
- [ ] 7.6 `bunx markdownlint-cli2 --fix` across touched markdown.