Skip to content

M9-S4a: seller registration + my-listings dashboard#107

Merged
erikshafer merged 1 commit into
mainfrom
m9-s4a-seller-registration-listings-dashboard
Jun 13, 2026
Merged

M9-S4a: seller registration + my-listings dashboard#107
erikshafer merged 1 commit into
mainfrom
m9-s4a-seller-registration-listings-dashboard

Conversation

@erikshafer

Copy link
Copy Markdown
Owner

Summary

  • Seller registration flow: One-click RegisterAsSeller from the session, extending SessionContext with isRegisteredSeller state persisted to sessionStorage. Handles 200 (success) and 409 (already registered) as equivalent success paths.
  • My Listings dashboard: Zod-validated TanStack Query over GET /api/selling/listings?sellerId=, rendering a card grid with seller-lifecycle status badges (Draft/Submitted/Published/Rejected/Withdrawn), empty/error/loading states.
  • S4 split: S4a (this PR) covers the read + register surface; S4b (next) covers create-draft form, edit-draft, and submit — the 10-field form with react-hook-form warrants its own slice.
  • Live smoke finding: Registration body must include participantId — empty body {} yields Guid.Empty before the route {id} fallback activates in Wolverine's [WriteAggregate] identity resolution (same class as M8-S2's empty-body 400).
  • Zero backend changes — frontend only, 19 files changed, seller tests 2→20.

Test plan

  • npm run build -w @critterbids/seller — TypeScript strict, Vite build clean
  • npm run test -w @critterbids/seller — 20 tests pass (schema, listings page, session context, SignalR)
  • npm run test -w @critterbids/bidder -w @critterbids/ops — 25 + 47 tests unchanged
  • HTTP smoke: session → register → 409 idempotency → empty listings → create draft → query shows 1 listing
  • Browser smoke: blocked by Chrome admin-install (per M8-S4 precedent, marked explicitly unchecked)

Wire the seller SPA's two foundational surfaces: one-click seller
registration (narrative 004 Moment 1) and the My Listings dashboard
consuming GET /api/selling/listings?sellerId=.

Registration: SessionContext extended with isRegisteredSeller state,
persisted to sessionStorage; registerAsSeller mutation sends the
participantId in the body (live smoke caught the [WriteAggregate]
identity-binding bug with an empty body — same class as M8-S2).

My Listings: Zod schema for SellerListingSummary, TanStack Query hook,
card-grid page with seller-specific status badge variants, empty/error
states, loading skeleton. Routing extended with /listings route.

S4 split into S4a (this: read + register) and S4b (next: create-draft
form, edit-draft, submit) per handoff guidance — the 10-field form with
react-hook-form warrants its own slice.

Frontend only — zero .cs files touched. Seller tests: 2 → 20 (+18).
Bidder 25 and ops 47 unchanged.
@erikshafer erikshafer self-assigned this Jun 13, 2026
@erikshafer erikshafer merged commit fa1e319 into main Jun 13, 2026
6 checks passed
@erikshafer erikshafer deleted the m9-s4a-seller-registration-listings-dashboard branch June 13, 2026 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant