docs(loyalty): record 2026-05-24 Test 4 + storefront auth body-schema fix
Some checks failed
Some checks failed
End-of-day update. - Test 4 (cross-store redemption) verified: card #5's transaction history now spans store_id=4 (FASHIONHUB, all the earnings) and store_id=5 (FASHIONOUTLET, today's -100 redemption). Cross-location flow confirmed. - Bug found + fixed (478c3a9c) on the storefront auth API. Both POST /api/v1/storefront/auth/forgot-password and .../reset-password declared bare `email: str` / `reset_token: str, new_password: str` params, which FastAPI treats as query strings. The frontend sends JSON body, so the call 422'd with "missing query parameter email". Added PasswordResetRequest + PasswordResetConfirm Pydantic body schemas; switched both endpoints to body: <Schema>. Surfaced trying to test Test 5's customer login flow. - /loyalty-wrap skill committed (d03b96da) — mechanises the end-of-day routine. First invokable as /loyalty-wrap tomorrow (skills load at session start). Carries Test 5 into next session (now unblocked by the auth fix), plus a new TODO from the user: transaction categories should be creatable by merchants and store owners, not admin-only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -267,6 +267,68 @@ User suggested enhancing `/admin/platform-debug` to test redirects. My scope: ad
|
||||
- **Routing pass** (after Test 8 finishes so we don't churn mid-walkthrough): fix the 4 routing bugs in one focused commit, add the RedirectTrace admin tool + the corresponding integration test, update hetzner doc + user-journeys doc Case 3 to match the canonical platform-debug pattern.
|
||||
- Existing follow-ups still queued: Hetzner doc check, B1-F unit tests, prospecting `tasks/__init__.py` missing import, other-module email audit.
|
||||
|
||||
## 2026-05-24 update — Test 4 done + storefront auth body-schema fix
|
||||
|
||||
### Test 4 (cross-store redemption) — verified
|
||||
|
||||
Card #5 has its full earning history at FASHIONHUB (`store_id=4`): welcome
|
||||
bonus 50 + three `points_earned` totalling 218 = 268 total earned. Today's
|
||||
`points_redeemed -100 @ store_id=5` (FASHIONOUTLET) succeeded cleanly,
|
||||
producing the mixed-store transaction history the cross-location flow is
|
||||
supposed to deliver. Balance = 168 pts.
|
||||
|
||||
### Storefront forgot/reset password endpoints now accept JSON body (`478c3a9c`)
|
||||
|
||||
Both `POST /api/v1/storefront/auth/forgot-password` and `.../reset-password`
|
||||
were declared with bare `email: str` / `reset_token: str, new_password: str`
|
||||
parameters. FastAPI treats unannotated str params as query parameters, so
|
||||
the storefront's JSON request body was ignored and the endpoint 422'd
|
||||
with `{"loc":["query","email"],"msg":"Field required"}`. The endpoint
|
||||
docstrings even said "Request Body: email" — intent was clear, the
|
||||
implementation drifted.
|
||||
|
||||
Added two body schemas in `app/modules/tenancy/schemas/auth.py`
|
||||
(`PasswordResetRequest`, `PasswordResetConfirm`), re-exported via
|
||||
`__init__.py`, and switched both endpoint signatures to `body: <Schema>`.
|
||||
|
||||
Surfaced when the user tried to test Test 5 (customer storefront login)
|
||||
and needed to set a password on the customer that self-enrolled with just
|
||||
email + name + birthday.
|
||||
|
||||
### Skill created: `/loyalty-wrap` (`d03b96da`)
|
||||
|
||||
Mechanises the end-of-day routine that's been manual every session. Lives
|
||||
at `.claude/skills/loyalty-wrap/SKILL.md`. Triggers on phrases like "call
|
||||
it a night", "save memory and docs", "wrap up", etc. Skills load at session
|
||||
start, so the first session where the user can actually invoke it as
|
||||
`/loyalty-wrap` is the next one after the one that committed it.
|
||||
|
||||
### Status board delta
|
||||
|
||||
- Step 6 (web user-journey E2E tests) — Tests 1 ✅, 2 ✅, 3 ✅, **4 ✅**
|
||||
done. Test 5 in progress (blocked tonight on password-reset flow; now
|
||||
unblocked by the `478c3a9c` fix, verification pending next session).
|
||||
|
||||
### Carry over for next session
|
||||
|
||||
1. **Test 5 — password-reset end-to-end** (new top priority): with the
|
||||
`478c3a9c` fix deployed, retry the forgot-password flow → confirm an
|
||||
`email_logs` row appears with `template_code='password_reset'`,
|
||||
`status='sent'` → click the link in the email → set a password → login
|
||||
→ continue from step 5.3 (visit `/account/loyalty` dashboard + history).
|
||||
2. **Transaction categories — permissions audit (new item raised by
|
||||
user)**: today only admin can create transaction categories. Merchants
|
||||
and store owners should be able to. Investigate the existing endpoint
|
||||
in `app/modules/loyalty/services/category_service.py` +
|
||||
`app/modules/loyalty/routes/api/admin.py`, decide the right scope
|
||||
(merchant-level? store-level?), wire up the merchant + store UIs, add
|
||||
the appropriate RBAC permissions.
|
||||
3. **Routing pass** still queued (after Test 8): fix the 4 routing bugs
|
||||
+ Redirect Trace admin tool + integration tests + doc updates.
|
||||
4. **Existing follow-ups**: Hetzner doc check, B1-F unit tests,
|
||||
prospecting `tasks/__init__.py` missing import, other-module email
|
||||
audit.
|
||||
|
||||
## Status board
|
||||
|
||||
| # | Pre-launch step | State | Notes |
|
||||
|
||||
Reference in New Issue
Block a user