docs(quick-261016-nqk): plan and summary for UAT gaps G-18.1-7 and G-18.1-4; D-21 amended, COVERAGE cancel_at row
This commit is contained in:
@@ -66,6 +66,7 @@ Research (`18.1-RESEARCH.md` § Premise Shifts S-1..S-10) found premises that no
|
||||
- **D-20 (S-8, S-9):** The Stripe subscriptions subpackage is its own party plugin, `golem15.pgstripesubscriptions`, at module path `git.golem15.com/golem15/sm-pgstripe-plugin/subscriptions`. It gets its own importable or package-local Stripe fake; P18's root `stripefake_test.go` stays unchanged.
|
||||
- **D-21:** Behaviour defaults: keep PHP's `cancel_at_period_end` mapping (a manual test-mode check decides whether `cancel_at` from the billing portal also needs handling); out-of-order events behave as PHP does; the job reads both pre-basil and basil payload shapes; customer `GET /subscription` returns the latest subscription with `has_access` and `in_grace_period` flags.
|
||||
- **D-21 amendment (2026-10-14, gap closure 18.1-07, user decision on verification human item 1):** out-of-order events no longer behave as PHP; created and updated events apply the subscription Stripe holds, serialised per subscription, and a deletion before its subscription is stored is retried. D-21's other defaults are unchanged.
|
||||
- **D-21 amendment (2026-10-16, quick 261016-nqk, UAT test 7 / gap G-18.1-7):** the test-mode check settled the `cancel_at` question. On API `2026-09-30.endive` a billing-portal cancel reports `cancel_at` (the period end) with `cancel_at_period_end` false; an API cancel reports both. pgstripe now stores `cancel_at_period_end` true when Stripe reports that flag or a `cancel_at` date on an active or trialing subscription; clearing `cancel_at` maps back to false and fires `reactivated`. The row keeps PHP's single flag; `cancel_at` itself is not stored.
|
||||
- **D-22 (plan split, 6 plans):** (1) framework: cabana flat reorder + `taglist`; (2) pgsub core tracer in the new repo (created with `tea repos create --owner golem15`); (3) pgstripe secret columns + import mapping + `subscriptions` plugin (gateway, both webhook routes, River job, host test); (4) pgsub admin screens + customer API; (5) `vue-paymentgateway-layer` pieces (tag `v0.2.0` only on go-ahead); (6) unit tests across all repos + `scripts/check-phase18.1.sh`. Plan 2's repo is committed before plan 3's `go.mod` points at it. No push, tag or deploy without the user's go-ahead.
|
||||
|
||||
### Claude's Discretion
|
||||
|
||||
@@ -17,7 +17,7 @@ Scope: the Stripe Billing surface the frozen PHP `SubscriptionGateway` contract
|
||||
| subscriptions.retrieve (syncSubscription / reconcile) | INTEGRATE | also the webhook job's fresh-state read: created/updated apply Stripe's current subscription, 404 falls back to the snapshot (CR-01, 18.1-07); used by Service.SyncSubscription (WR-06) |
|
||||
| subscriptions.update cancel_at_period_end true (cancel at period end) | INTEGRATE | |
|
||||
| subscriptions.cancel (cancel immediately) | INTEGRATE | |
|
||||
| subscriptions.update cancel_at (flexible-billing cancel enums) | OPT-OUT | D-21 keeps PHP's cancel_at_period_end mapping; a manual Stripe test-mode check at UAT decides a follow-up |
|
||||
| subscription cancel_at (read from events and retrieval) | INTEGRATE | a cancel_at date on an active or trialing subscription maps to cancel_at_period_end true; cleared maps back (portal cancels report cancel_at only; D-21 amended 2026-10-16) |
|
||||
| subscriptions.update (resume or un-cancel through the API) | OPT-OUT | not in the frozen PHP contract: reactivation happens in the billing portal and arrives as customer.subscription.updated |
|
||||
| subscriptions.update (plan change, proration) | OPT-OUT | not in the frozen PHP contract: plan changes go through the billing portal |
|
||||
| subscriptions.list / subscriptions.search | OPT-OUT | not in the frozen PHP contract: reconcile walks local rows and retrieves each |
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
quick_id: 261016-nqk
|
||||
slug: close-uat-gaps-g-18-1-7-and-g-18-1-4
|
||||
date: 2026-10-16
|
||||
gap_closure: true
|
||||
gap_ids: [G-18.1-7, G-18.1-4]
|
||||
repos: [summercms.go, sm-paymentgatewaysubscriptions-plugin, sm-pgstripe-plugin]
|
||||
source: .planning/phases/18.1-payment-gateway-subscriptions/18.1-UAT.md (## Gaps)
|
||||
---
|
||||
|
||||
# Quick 261016-nqk: close UAT gaps G-18.1-7 and G-18.1-4
|
||||
|
||||
No push, tag or release. Framework first (pgsub needs its new hooks), then the plugins; planning docs last.
|
||||
|
||||
## Tasks
|
||||
|
||||
1. **G-18.1-7 (pgstripe).** The decoded subscription maps `cancel_at_period_end` true for Stripe's flag or a `cancel_at` date while active or trialing; a cleared `cancel_at` maps back. One choke point (`subscriptionObject.args`) serves the snapshot, the fresh retrieval and `SyncSubscription`. Tests: both payload shapes, un-cancel, `cancel_at` in past_due/canceled; Postgres smoke of portal cancel then un-cancel (reactivated once). README, COVERAGE row, D-21 amendment.
|
||||
2. **G-18.1-4 (preview labels, pgsub).** The label element renders its `value` property (the SPA's plugin-element contract), not only the attribute. Node-run test.
|
||||
3. **G-18.1-4 (framework).** `pact.ListExtendRecords` (once per list page, before columns are read; unstored `gorm:"-"` columns compile unsortable and refuse sortable/searchable) and `pact.FormRecordTitle` (`meta.title` on show/create/update; the SPA heads form and preview with it). Roster fixture tests, SPA tests, docs, OpenAPI, admin dist.
|
||||
4. **G-18.1-4 (pgsub).** Subscriber column (e-mail, else name; `<alias> #<id>` fallback) through `ListExtendRecords` and the optional `contracts.SubscriberBatchResolver` (user resolver implements `ResolveMany`); subscriber type and id become invisible searchable columns; preview title "Subscription #<id> (<plan>)" (en/pl). Tests, README.
|
||||
5. Rebuild the UAT demo app and check the admin API.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
quick_id: 261016-nqk
|
||||
slug: close-uat-gaps-g-18-1-7-and-g-18-1-4
|
||||
status: complete
|
||||
date: 2026-10-16
|
||||
gap_closure: true
|
||||
gap_ids: [G-18.1-7, G-18.1-4]
|
||||
repos:
|
||||
sm-pgstripe-plugin: [a5b3314]
|
||||
sm-paymentgatewaysubscriptions-plugin: [6a3f2c4, d5579cd]
|
||||
summercms.go: [bc5685e, 013890c, 17398fe]
|
||||
---
|
||||
|
||||
# Quick 261016-nqk: UAT gaps G-18.1-7 and G-18.1-4
|
||||
|
||||
Nothing pushed, tagged or released.
|
||||
|
||||
| Gap | Fix | Commit |
|
||||
|-----|-----|--------|
|
||||
| G-18.1-7 | `cancel_at_period_end` = Stripe's flag, or a `cancel_at` date on an active or trialing subscription; un-cancel maps back and fires reactivated. D-21 amended; COVERAGE row now INTEGRATE | pgstripe a5b3314 |
|
||||
| G-18.1-4 (empty Gateway/Status on preview) | the label element renders its `value` property (the SPA sets the property, the element read only the attribute) | pgsub 6a3f2c4 |
|
||||
| G-18.1-4 (framework) | `pact.ListExtendRecords`, `pact.FormRecordTitle` (`meta.title`), unstored list columns unsortable/unsearchable; SPA uses `meta.title`; docs, OpenAPI, dist | summercms.go bc5685e, 013890c, 17398fe |
|
||||
| G-18.1-4 (subscriber, title) | list column `subscriber` (e-mail, else name, `<alias> #<id>` fallback) via the new optional `contracts.SubscriberBatchResolver`; type/id invisible but searchable; preview title "Subscription #<id> (<plan>)" / "Subskrypcja #<id> (<plan>)" | pgsub d5579cd |
|
||||
|
||||
The screenshot's "Cancel at Period End: No / Canceled At: —" was stale: the preview API for subscription 1 returns `cancel_at_period_end: true` and `canceled_at` (checked on the demo, before and after the rebuild).
|
||||
|
||||
## Verification
|
||||
|
||||
- summercms.go: `go vet ./...`, `go test ./...` (Docker), `summer docs:build --check`, `TestDocsTree`, admin vitest 1431/1431 and typecheck, `check-admin-openapi.sh`, `check-admin-dist.sh`.
|
||||
- pgsub and pgstripe: `go vet ./...`, `go test ./...` (Docker) green; the new subtests ran (not skipped).
|
||||
- Demo app rebuilt without overlays and restarted: list row `subscriber: customer@example.test`, preview `meta.title: "Subscription #1 (Pro)"`, `gateway: Stripe`, `stripe_status: Active`; the new admin bundle is served.
|
||||
|
||||
## Release notes
|
||||
|
||||
- pgsub now needs the framework's `pact.ListExtendRecords` and `pact.FormRecordTitle`: tag the framework (v0.2.2) first, bump pgsub's `require`, tag pgsub, then pgstripe (already needs unreleased pgsub from 261016-myi).
|
||||
- Search by subscriber e-mail is not offered: cabana searches stored columns and relations only, and the subscriber is polymorphic. Type and id stay searchable.
|
||||
- UAT 7 and the site-side cancel still need a live re-run in the demo.
|
||||
Reference in New Issue
Block a user