diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 68cb43d..5b1c3f5 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -106,7 +106,7 @@ {"id":"fotospiel-app-vel","title":"Localized SEO: update PRP/marketing playbooks for hreflang strategy","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T16:02:42.156443813+01:00","created_by":"soeren","updated_at":"2026-01-01T16:02:42.156443813+01:00"} {"id":"fotospiel-app-vk4","title":"Registration flow fixes: JSON redirect, error clearing, role handling","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:07:01.574904029+01:00","created_by":"soeren","updated_at":"2026-01-01T16:11:18.65499639+01:00","closed_at":"2026-01-01T16:11:18.65499639+01:00","close_reason":"Duplicate of fotospiel-app-l6a"} {"id":"fotospiel-app-w2x","title":"SEC-FE-03 Cookie banner UX + localisation","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T15:55:26.182193434+01:00","created_by":"soeren","updated_at":"2026-01-01T15:55:31.84344419+01:00","closed_at":"2026-01-01T15:55:31.84344419+01:00","close_reason":"Completed in codebase (verified)"} -{"id":"fotospiel-app-w7g","title":"Paddle catalog sync: document failure recovery playbook","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T15:59:26.255623751+01:00","created_by":"soeren","updated_at":"2026-01-01T15:59:26.255623751+01:00"} +{"id":"fotospiel-app-w7g","title":"Paddle catalog sync: document failure recovery playbook","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T15:59:26.255623751+01:00","created_by":"soeren","updated_at":"2026-01-02T21:52:16.074002452+01:00","closed_at":"2026-01-02T21:52:16.074002452+01:00","close_reason":"Completed"} {"id":"fotospiel-app-wde","title":"Tenant lifecycle controls (status, limits, suspend/grace)","description":"Superadmin controls for tenant status, grace periods, and hard limits (uploads/storage/events). Includes UI, policy checks, and audit events.","notes":"Delivered dedicated tenant lifecycle view with limits + audit timeline, added grace_period_ends_at field and tenant_lifecycle_events logging, wired lifecycle actions (activate/suspend/deletion/anonymize) + management actions (limits, grace, subscription expiry), enforced tenant photo/storage limits in PackageLimitEvaluator, added lifecycle/limits tests, ran Pint + targeted tests.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-01T14:18:23.062036821+01:00","updated_at":"2026-01-02T17:33:35.031605632+01:00","closed_at":"2026-01-02T17:33:35.031605632+01:00","close_reason":"Closed"} {"id":"fotospiel-app-wkl","title":"Paddle catalog sync: paddle:sync-packages command (dry-run/pull)","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T16:00:58.753792575+01:00","created_by":"soeren","updated_at":"2026-01-01T16:01:04.39629062+01:00","closed_at":"2026-01-01T16:01:04.39629062+01:00","close_reason":"Completed in codebase (verified)"} {"id":"fotospiel-app-wku","title":"Security review: run dynamic testing harness (identities, DAST, fuzz uploads)","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-01T16:05:37.008239379+01:00","created_by":"soeren","updated_at":"2026-01-01T16:05:37.008239379+01:00"} diff --git a/.beads/last-touched b/.beads/last-touched index d72fbe0..66d4f15 100644 --- a/.beads/last-touched +++ b/.beads/last-touched @@ -1 +1 @@ -fotospiel-app-38f +fotospiel-app-w7g diff --git a/docs/ops/billing-ops.md b/docs/ops/billing-ops.md index b4d536f..f31b267 100644 --- a/docs/ops/billing-ops.md +++ b/docs/ops/billing-ops.md @@ -130,4 +130,26 @@ Diese Sektion ist bewusst generisch gehalten, damit sie auch nach Implementation - Bei Katalog‑Abweichungen `paddle:sync-packages --dry-run` verwenden, um Snapshots zu prüfen, bevor tatsächliche Änderungen gesendet werden. - Fehlgeschlagene Syncs in den Logs (`Paddle package sync failed`, `Paddle discount sync failed`) beobachten. +### 6.5 Recovery-Playbook: Katalog‑Sync fehlgeschlagen + +Wenn der Katalog‑Sync fehlschlägt oder Pakete nicht mehr korrekt verknüpft sind: + +1. **Status im Admin prüfen** + - `PackageResource` → Felder `paddle_sync_status`, `paddle_synced_at` und `Letzter Fehler`. + - Fehlermeldung stammt aus `paddle_snapshot.error.message`. +2. **Trockenlauf ausführen** + - `php artisan paddle:sync-packages --package= --dry-run` + - Prüfe die erzeugten Payload‑Snapshots (in `paddle_snapshot`) auf falsche IDs/Preise. +3. **Mapping prüfen** + - Falls `paddle_product_id` oder `paddle_price_id` fehlt oder falsch ist: im Paket‑Admin korrigieren. + - Bulk‑Sync blockiert unmapped Pakete; gezielte Korrektur vor dem nächsten Lauf ist Pflicht. +4. **Sync erneut anstoßen** + - `php artisan paddle:sync-packages --package= --queue` + - Bei Bedarf: `--allow-unmapped` nur bewusst verwenden (z.B. initiales Mapping). +5. **Pull für Abgleich** + - `php artisan paddle:sync-packages --package= --pull` zum Abgleich mit Paddle. +6. **Logs prüfen** + - Erwartete Logeinträge: `Paddle package sync failed`, `Paddle addon sync failed`, `Paddle discount sync failed`. + - Achte auf wiederkehrende Fehler (z.B. invalid product/price IDs). + Diese Untersektion soll dir als Operator helfen zu verstehen, wie Paddle‑Aktionen im System abgebildet sind und an welchen Stellen du im Fehlerfall ansetzen kannst.