# Tasks: add-payment-provider-mollie ## 1. Scaffold package shell - [x] 1.1 Create `packages/universal/payment-provider-mollie/` with `package.json` (name `@suaveplan/payment-provider-mollie`, version `0.1.0`, `sideEffects: false`, type `module`, MIT, author `Suaveplan Team`, deps `@suaveplan/payment` + `@suaveplan/payment-providers` - `@suaveplan/error` + `tslib`, devDeps `@suaveplan/testing` + `@types/node` + `@vitest/coverage-istanbul` + `typescript` + `vite` + `vite-plugin-dts` + `vitest`, all via `workspace:^` / `catalog:` / `catalog:build` / `catalog:testing` — zero bare versions). - [x] 1.2 Add `tsconfig.json` and `tsconfig.lib.json` mirroring the binance sibling. - [x] 1.3 Add `vite.config.ts` with `preserveModules`, `lib.entry = src/index.ts`, externals matching the deps. - [x] 1.4 Add `vitest.config.ts` with `pool: "forks"`, `istanbul` coverage at 100/100/100/100, `testTimeout: 30000`, `setupFiles: ["./tests/setup/polyfills.ts"]`. - [x] 1.5 Add `tests/setup/polyfills.ts` (no-op placeholder mirroring the binance pattern). ## 2. Implement MollieProvider + helpers - [x] 2.1 Create `src/mollie/mollie.ts` exporting: - `MOLLIE_DEFAULT_BASE_URL` constant - `MOLLIE_PROVIDER_NAME` constant - `formatMollieAmount(amount: bigint): string` - `parseMollieAmount(value: string): bigint` - `mapMollieStatus(status: string): PaymentStatus` - `mapMollieRefundStatus(status: string): RefundStatus` - `MollieProvider` class implementing `PaymentProvider` - [x] 2.2 Import all foundation symbols from `@suaveplan/payment-providers` per the contract: `httpRequest`, `composeAbortSignal`, `FetchLike`, `ApiKeyConfig`, `PaymentProviderError`, `PAYMENT_PROVIDER_CODES`, `httpError`, `parseError`. - [x] 2.3 Import payment types from `@suaveplan/payment` (verbatim re-import of the same symbols upstream used). - [x] 2.4 Use `Authorization: Bearer ` header on every call. - [x] 2.5 Marshal Money amounts via `formatMollieAmount` outbound and `parseMollieAmount` inbound; preserve the `{ currency, value }` shape on the wire. - [x] 2.6 Raise ONLY `PaymentProviderError` — every failure path bubbles through `httpRequest` which raises typed errors. - [x] 2.7 Keep `mollie.ts` under 300 lines. ## 3. Tests + docs - [x] 3.1 Create `src/mollie/mollie.test.ts` covering the full plan in `design.md`. All imports go through `@suaveplan/testing/runner`; no `vi.spyOn(globalThis, "fetch")`; recording `FetchLike` closures injected via constructor. Every `it` has `{ timeout: 5000 }`. - [x] 3.2 Cover amount-marshalling edge cases (1 cent, exact major unit, large, over-precision parse, no-decimal parse, single-decimal parse). - [x] 3.3 Cover the full status-map matrix and refund-status-map matrix. - [x] 3.4 Cover the payment-method map (creditcard / ideal / undefined). - [x] 3.5 Cover the HTTP_ERROR surface (rejecting fetch + non-2xx response). - [x] 3.6 Create `src/mollie/mollie.md` with the §4 mandatory sections (Purpose ≥2 sentences, Features, Basic + Advanced usage, API Reference for every export, Implementation Notes), ≥200 words excl. code. - [x] 3.7 Create `src/mollie/index.ts` with explicit named exports (rule 6a). - [x] 3.8 Create `src/index.ts` with explicit named package-root exports (rule 6a). - [x] 3.9 Create root `README.md` with all §5 mandatory sections (H1, description, install, quick-start, Modules linking `src/mollie/mollie.md`). ## 4. Subpath exports - [x] 4.1 Add `./mollie/mollie` subpath export to `package.json#exports` mirroring the binance sibling format. Final exports count: 2 entries (`.` + `./mollie/mollie`) + `./package.json`. ## 5. Verification gates (§13) - [ ] 5.1 Step 0 — spec reconciliation: walk every `### Requirement` in the delta and confirm every named export + every `**Verified by:**` test name exists in source. - [ ] 5.2 Step 1 — `bunx turbo lint typecheck test --filter=@suaveplan/payment-provider-mollie`. - [ ] 5.3 Step 2 — `bunx turbo test:coverage --filter=@suaveplan/payment-provider-mollie` reports 100/100/100/100. - [ ] 5.4 Step 3 — `bunx turbo build --filter=@suaveplan/payment-provider-mollie`. - [ ] 5.5 Step 4 — banned-pattern scan returns zero output. - [ ] 5.6 Step 4a — barrel-shape scan returns zero output (no `export *` in any `/index.ts`). - [ ] 5.7 Step 4b — test-runner import scan returns zero output (no direct `vitest` / `bun:test` imports). - [ ] 5.8 Step 5 — every `.ts` (excl. `.test.ts`, `.types.ts`, `index.ts`) has a sibling `.md`. - [ ] 5.9 Step 6 — `README.md` exists. - [ ] 5.10 Step 7 — no bare versions in `package.json`. - [ ] 5.11 Step 8 — subpath-export count = 2 (`.` + `./mollie/mollie`). - [ ] 5.12 Step 9 — security scan returns zero output. - [ ] 5.13 Step 10 — dependent sweep: `bunx turbo test --filter=...@suaveplan/payment-provider-mollie` green (only the package itself). ## 6. Root-doc refresh (§13b) - [ ] 6.1 Run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`. - [ ] 6.2 Run `bun scripts/generate-missing.ts` to refresh `MISSING.yml`. - [ ] 6.3 Hand-edit `STATUS.md` to add a row for `@suaveplan/payment-provider-mollie` (✅ shipped). - [ ] 6.4 Hand-edit `SUMMARY.md` paragraph for the new package. - [ ] 6.5 `bunx markdownlint-cli2 --fix` across touched docs. ## 7. Fold + archive (§14) - [ ] 7.1 Fold `specs/payment-provider-mollie/spec.md` into `openspec/specs/payment-provider-mollie/spec.md`. - [ ] 7.2 Move `openspec/changes/add-payment-provider-mollie/` → `openspec/archive/2026-05-17-add-payment-provider-mollie/`.