Break the follow-ups into six testable steps
Six tasks, each ending on a green billing folder and its own commit: move the money gate into the class that promises it, four fixes that make the fake behave like Stripe, ask Stripe for its products, recognise an orphaned one, count adopted apart from created, and hand the operator a sweep for the orphans nobody can adopt. Self-review dropped one item the spec had carried over from the last review: the zero guard in PlanPrices::ensure(). Its only purpose was to keep a tiered price unreachable, and the gate move rejects those directly — so it would be a behaviour change with no remaining benefit, and it would make a free plan unsellable. Recorded as deliberately not built, with the reason, rather than quietly dropped. Also corrected: a test that counted every product where the run mints one per family, and a step that named the test it replaces only by description. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>feature/host-bootstrap
parent
3ceec8fe5e
commit
7d66a01a40
File diff suppressed because it is too large
Load Diff
|
|
@ -103,10 +103,23 @@ einen vierteljährlichen oder mengenteilenden Preis überhaupt hinstellen kann.
|
|||
wiederkehrende Preise **mit** ihren preisbestimmenden Eigenschaften; was davon
|
||||
zulässig ist, entscheidet der Aufrufer.
|
||||
|
||||
**Verwandt, hier mit erledigt:** `PlanPrices::ensure()` bekommt die
|
||||
`<= 0`-Schranke, die `AddonPrices::ensure()` schon hat. Sie ist das Einzige, was
|
||||
einen `billing_scheme: tiered`-Preis (bei dem Stripe `unit_amount: null`
|
||||
liefert, hier als 0 gelesen) auf der Paketseite überhaupt erreichbar macht.
|
||||
### Die Null-Schranke in `PlanPrices` wird **nicht** gebaut
|
||||
|
||||
Der Abschluss-Review hatte sie vorgeschlagen, und §14 des Vorgängers hat sie
|
||||
notiert: `AddonPrices::ensure()` hat eine `<= 0`-Schranke, `PlanPrices::ensure()`
|
||||
nicht, und das sei das Einzige, was einen `billing_scheme: tiered`-Preis (bei dem
|
||||
Stripe `unit_amount: null` liefert, hier als 0 gelesen) auf der Paketseite
|
||||
erreichbar macht.
|
||||
|
||||
Das stimmte — **bis zu diesem Umzug**. Sobald `AdoptStripePrice` selbst
|
||||
`billing_scheme !== 'per_unit'` ablehnt, ist ein gestufter Preis unabhängig vom
|
||||
Betrag des Aufrufers ausgeschlossen. Die Schranke hätte dann keinen Zweck mehr,
|
||||
wäre aber eine Verhaltensänderung: ein Paket zu null — ein kostenloser Tarif,
|
||||
heute nicht im Katalog, aber jederzeit anlegbar — bekäme keinen Stripe-Preis
|
||||
mehr und wäre nicht verkäuflich. Eine Schranke ohne Nutzen, die einen künftigen
|
||||
Fall bricht, wird nicht eingebaut.
|
||||
|
||||
Der §14-Eintrag wird entsprechend abgehakt: nicht gebaut, und warum.
|
||||
|
||||
## 4. `stripe:sweep-orphan-prices` — das Aufräum-Kommando
|
||||
|
||||
|
|
@ -171,7 +184,9 @@ Ohne Entwurfsentscheidung — bauen, Test, weiter (R22.5):
|
|||
(`SyncStripeCatalogue` holt `PlanPrices` pro Zeile neu), ein Zähler auf der
|
||||
Instanz käme also nie über eins hinaus. Sie hat sonst keinen Zustand, und
|
||||
der Zähler ist das, was den Bericht wahr macht.
|
||||
6. `PlanPrices::ensure()` bekommt die `<= 0`-Schranke — siehe §3.
|
||||
6. ~~`PlanPrices::ensure()` bekommt die `<= 0`-Schranke~~ — **entfällt**, siehe
|
||||
§3: der Umzug des Geld-Tors nimmt ihr den Zweck, und sie würde einen
|
||||
kostenlosen Tarif unverkäuflich machen.
|
||||
|
||||
## 7. Was nicht dazugehört
|
||||
|
||||
|
|
@ -234,7 +249,8 @@ Und an `StripeIdempotencyKeyTest.php`: Blättern **wirft** bei fehlender `id`
|
|||
Warnung drosseln
|
||||
- `app/Services/Billing/AddonPrices.php` — Produkt-Wiedererkennung in
|
||||
`product()`
|
||||
- `app/Services/Billing/PlanPrices.php` — `<= 0`-Schranke
|
||||
- `app/Providers/AppServiceProvider.php` — beide Adoptions-Klassen als
|
||||
Singleton, damit ihr Lauf-Protokoll (`$duplicates`, `$adoptions`) trägt
|
||||
- `app/Console/Commands/SyncStripeCatalogue.php` — Produkt-Wiedererkennung,
|
||||
getrennte Zählung, Kommentar berichtigt
|
||||
- `tests/Feature/Billing/StripePriceAdoptionTest.php`,
|
||||
|
|
|
|||
Loading…
Reference in New Issue