Features Reference

Developer & QA index for all views shipped in M1–M4. Each entry includes a direct link, golden path to reach the view, confirmed use cases, and known gaps.

M1

Cards / Listings Data Model

Issues: #8, #9, #10, #11, #12

Replaces free-form Products with a TCGPlayer-style model: sellers pick a card from the global catalog and set price, condition, quantity, and language.

Seller Dashboard
M1
Visit /dashboardrequires sign-in

The seller's home base. Create, edit, and delete Pokémon card listings from a paginated data table. Listings tie a card from the global PokemonCards catalog to a price (MXN), condition, quantity, and language.

Golden path

  1. Go to /sign-up and create an account
  2. Navigate to /dashboard
  3. Click "Add listing" to open the create listing dialog
  4. Search for a card by name, fill in condition / price / quantity / language, and submit

Use cases

  • Create a new listing using the card autocomplete search
  • Edit an existing listing's price, condition, or quantity
  • Delete a listing from the table
  • See listing columns: card name, condition, price (MXN), quantity, language

Known gaps

  • No "Deactivate listing" toggle — only hard delete is available
  • No duplicate listing shortcut
  • No standalone /create-listing route — the create form is a dialog on /dashboard only (cannot deep link)

M1 missing use cases

  • Seller cannot browse their tenant storefront directly from the dashboard
  • No listing history or sold-count visible to the seller
  • No bulk-upload or CSV import for listings
M2

Buyer Search & Discovery

Issues: #13, #14, #15, #16

Buyers can browse and find cards on the platform. The core marketplace loop: search → card page → add to cart.

Pokémon Card Catalog
M2

Infinite-scroll grid of all Pokémon cards in the platform catalog. Each card tile shows the card image, set, lowest listing price in MXN, and active seller count. Filter pills let buyers narrow results by rarity, condition, price range, set ID, and sort order — all reflected in the URL.

Golden path

  1. Visit the home page and click "Browse Pokémon Cards", or navigate directly to /search/pokemon
  2. Type a card name in the search bar to filter results (supports any word order, e.g. "charizard base set" or "base set charizard")
  3. Use the Rarity pill to filter by card rarity
  4. Use the Condition pill to filter by one or more card conditions (NM, LP, MP, HP, DMG)
  5. Use the Price pill to set a MXN min/max price range
  6. Use the Set pill to filter by set ID (e.g. base1, sv01)
  7. Use the Sort pill to order by name, price low→high, price high→low, or most sellers
  8. Scroll down to load more cards (infinite scroll)

Use cases

  • Search by card name — partial match, any word order
  • Filter by rarity using the Rarity pill
  • Filter by one or more conditions (NM / LP / MP / HP / DMG)
  • Filter by price range in MXN
  • Filter by set ID
  • Sort results: Name A–Z, Price Low→High, Price High→Low, Most Sellers
  • See lowest price and seller count per card
  • Click any card tile to navigate to its detail page
  • Clear all active filters with one click

Known gaps

  • Set filter requires a set ID (e.g. base1) — no searchable dropdown of set names
  • No empty-state message when no listings exist for a set
Card Detail & Seller Listings
M2

Full card detail page. Shows card image, stats (HP, types, rarity, set, artist), and a table of all active seller listings for that card. Condition tabs (NM / LP / MP / HP / DMG) filter the listings table. Buyers pick a listing and add it to cart.

Golden path

  1. Go to /search/pokemon
  2. Click any card in the catalog grid
  3. Use the condition tabs to filter listings by card condition
  4. Click "Add to Cart" on a specific seller listing

Use cases

  • View full card metadata: HP, types, rarity, set, artist, attacks, abilities
  • See all active seller listings for a card in one place
  • Filter listings by condition using the tab row
  • Compare seller prices and store names side by side
  • Add a specific listing (with its seller and condition) to the cart

Known gaps

  • No "Last Sold" price — planned for M5-3
  • No "Market Price" derived from recent sales — planned for M5-4
  • No out-of-stock indicator when a listing's quantity reaches 0
  • No link from card detail back to the seller's tenant storefront
Multi-Seller Cart
M2

Shopping cart showing all items added from any card detail page. Items are grouped by seller (tenant). Each seller group has its own subtotal and independent checkout button — required because each seller processes payment via their own Stripe Connected Account.

Golden path

  1. Navigate to any card detail page (/product/...)
  2. Click "Add to Cart" on a seller listing
  3. Click the cart icon in the navbar header
  4. Or navigate directly to /cart

Use cases

  • See all cart items grouped by seller in one place
  • Remove an individual item from a seller group
  • See per-seller subtotal and shipping placeholder
  • Click "Checkout with [Seller]" to initiate checkout for that seller's items
  • Empty cart state with link back to /search/pokemon

Known gaps

  • No cart item quantity editor — only add or remove whole items
  • No global checkout across all sellers at once (Stripe architecture requires per-seller sessions)
  • No checkout success / confirmation page — Stripe redirects back with no dedicated success view
  • Cart is stored in Zustand (localStorage) — clears on browser data wipe with no recovery

M2 missing use cases

  • Tenant storefront (/tenants/[slug]) exists but is not linked from M2 features — sellers can share their direct store URL
  • No wishlist or 'save for later' action on card detail
  • No recently viewed cards history
  • MXN currency is display-only — no currency selector
  • Set filter on /search/pokemon requires a set ID — no searchable dropdown of set names
M3

Order Lifecycle & Email

Issues: #29, #30, #31, #32, #33, #34, #35

Orders have a complete lifecycle visible to both buyer and seller. Sellers can mark orders as shipped with a tracking number. Email notifications are sent on order confirmed and order shipped events.

Buyer Order List
M3
Visit /ordersrequires sign-in

Authenticated buyer view of all past orders, sorted newest first. Each row shows the order date, seller, item count, total in MXN, and a color-coded status badge (Pending / Paid / Shipped / Delivered / Cancelled).

Golden path

  1. Complete a checkout with a seller (add to cart → checkout → pay via Stripe)
  2. After the Stripe redirect, navigate to /orders
  3. Or sign in and navigate to /orders at any time

Use cases

  • See all purchases in one place with status and date
  • Track order status across the full lifecycle
  • Click any order row to view full detail

Known gaps

  • No pagination UI — all orders fetched as an infinite list (acceptable for MVP)
  • No order search or filter by status
Buyer Order Detail
M3
Visit /ordersrequires sign-in→ click any order row to open detail

Detailed view of a single order (/orders/[orderId]). Shows each line item with card image and price, order total, current status badge, and — once the seller marks it as shipped — the carrier name and tracking number.

Golden path

  1. Go to /orders
  2. Click any order row

Use cases

  • View itemized order breakdown with card images and prices
  • See the current order status at a glance
  • Get tracking number and carrier once the seller marks the order as shipped
  • Returns 404 if the order ID does not belong to the signed-in user

Known gaps

  • Buyer cannot mark an order as received / delivered (no delivery confirmation action)
  • Buyer cannot cancel an order
  • No order receipt or printable summary
Seller Order Management
M3
Visit /seller/ordersrequires sign-in

Authenticated seller view of all orders placed through their store. Each order row shows card images, quantities, and order totals. Sellers can mark an order as shipped by entering a carrier name and tracking number. Submitting triggers the 'Order Shipped' email to the buyer.

Golden path

  1. Sign in as a seller (an account that has a tenant / store)
  2. Navigate to /seller/orders
  3. Find an order with status 'Paid'
  4. Click "Mark as shipped" to open the shipping form
  5. Select a carrier (Estafeta, DHL, FedEx, Correos de México, J&T Express, Other) and enter the tracking number
  6. Submit — the order transitions to 'Shipped' and the buyer receives an email

Use cases

  • See all buyer orders for the seller's store, newest first
  • Identify orders needing action (status: Paid)
  • Mark an order as shipped with carrier and tracking number
  • Status updates reflected immediately in the table after shipping

Known gaps

  • No email preview UI — email templates exist in code but there is no /emails/preview route
  • Escrow release ('Release funds') is admin-only at /superadmin/orders — no seller-facing UI
  • No bulk-ship action for multiple orders at once
  • Seller cannot cancel or refund an order from this view

M3 missing use cases

  • Escrow hold period (5 days after shippedAt) is implemented but release is manual admin-triggered — no automated release yet (V1 follow-up)
  • Order confirmed email is sent on Stripe webhook; no in-app notification or toast
  • No 'Delivered' transition from the buyer side — status only moves to Delivered when funds are released by admin
M4

Closed Beta Readiness

Issues: #45, #46, #47, #48, #50

Platform is stable enough to invite the first real sellers. Commission logic corrected, dispute flow live, seller onboarding dead ends fixed, and fees are transparent before sign-up.

Commission Logic
M4
Visit /pricingfee logic applied server-side at checkout

Platform automatically deducts an 8% commission on every completed sale, with a $8 MXN minimum and $850 MXN cap (~$50 USD). The fee is applied as a Stripe application_fee_amount on the seller's Connected Account checkout session — buyers and sellers never handle the split manually.

Golden path

  1. Navigate to /pricing to see the fee structure and examples
  2. Complete a checkout as a buyer (add to cart → checkout → pay via Stripe)
  3. Stripe automatically deducts the platform fee; the seller receives the remainder on their Connected Account

Use cases

  • Fee calculated at 8% of order total in cents
  • $8 MXN minimum fee for small sales (under $100 MXN)
  • $850 MXN cap for large sales (over ~$10,625 MXN)
  • Fee applied server-side in the purchase mutation — cannot be bypassed by the client

Known gaps

  • Platform fee is not shown to the buyer at the Stripe checkout summary
  • Seller has no fee vs. payout breakdown in the seller dashboard
Dispute / Report Flow
M4
Visit /ordersrequires sign-in→ open any order detail → Report Order

Buyers can report a problem with any completed order directly from the order detail page (/orders/[orderId]). Choose a reason (bad item, not delivered, fraud, or other), add a description, and submit. The report is filed in the Reports collection and visible to admins in the Payload admin panel.

Golden path

  1. Sign in as a buyer and navigate to /orders
  2. Click any order row to open the order detail page
  3. Scroll to the bottom and click "Report Order"
  4. Select a reason from the dropdown and fill in a description
  5. Submit — a confirmation message appears and the report is created

Use cases

  • Report a bad or misrepresented item
  • Report a non-delivered order
  • Report suspected fraud
  • Submit a freeform description of the issue

Known gaps

  • Admin has no custom front-end moderation UI — reports are managed via Payload admin (/admin → Reports)
  • No buyer notification when a report is resolved
  • Buyer cannot withdraw or update a submitted report
Admin Moderation Panel
M4
No cards seeded — run bun run db:sync-cards to generate a live linkPayload admin UI only — navigate to /admin → Tenants or Reports

Admins can suspend sellers and review dispute reports via the Payload admin UI. Suspended sellers are blocked from accepting new orders at checkout. Reports can be filtered by status (open / under-review / resolved) in the built-in list view.

Golden path

  1. Sign in with a super-admin account
  2. Navigate to /admin → Tenants
  3. Find the seller, open their record, and set "Is Suspended" to true
  4. Navigate to /admin → Reports to view and filter dispute reports by status

Use cases

  • Suspend a seller — their checkout throws an error for all buyers until unsuspended
  • Unsuspend a seller by unchecking isSuspended
  • View all reported orders filtered by status (open / under-review / resolved)
  • Mark a report as under-review or resolved

Known gaps

  • No custom moderation dashboard — all actions are via Payload admin
  • No email notification sent to a suspended seller
  • NSFW image detection deferred to V1
  • No bulk-action to suspend multiple sellers at once
Seller Onboarding Polish
M4
Visit /stripe-verifyrequires sign-in

Dead ends in the seller onboarding flow have been removed. After sign-up, sellers are taken directly to /stripe-verify. After completing Stripe onboarding they land on /seller/dashboard (not the Payload admin). The dashboard shows a persistent banner with a CTA to connect Stripe, and the 'New Listing' button is hidden until the seller's Stripe account is connected.

Golden path

  1. Go to /sign-up and create a new account
  2. You are automatically redirected to /stripe-verify
  3. Click "Connect Stripe" and complete the Stripe onboarding form
  4. You are returned to /seller/dashboard — the connection banner disappears
  5. 'New Listing' button is now visible and active

Use cases

  • Clear call to action immediately after sign-up — no dead ends
  • Dashboard shows Stripe connection banner and link to /stripe-verify when not yet connected
  • 'New Listing' button is hidden until Stripe is connected
  • After Stripe onboarding, seller lands on /seller/dashboard instead of Payload admin

Known gaps

  • No multi-step onboarding wizard — seller goes directly to Stripe's hosted form
  • No payout preview or bank account info step before connecting
Fee Transparency Page
M4

Static page explaining the VendeCartas commission structure to prospective sellers before they sign up. Shows a three-tier commission table, concrete MXN examples, and a FAQ about fund release timing. Linked from /stripe-verify so sellers can check fees mid-onboarding.

Golden path

  1. Navigate directly to /pricing
  2. Or visit /stripe-verify and click the 'Ver precios' link

Use cases

  • Understand the 3-tier commission structure: $8 MXN flat (sales under $100 MXN) / 8% standard / $850 MXN cap (~$50 USD)
  • See concrete fee examples: $60 MXN → $8 fee; $200 MXN → $16 fee; $20,000 MXN → $850 fee
  • Read the FAQ: when funds are released (5-day hold after shipment)
  • Click 'Empieza a vender gratis' to go to /sign-up

Known gaps

  • No interactive fee calculator — examples are static
Admin Fund Release (Escrow Payout)
M4
Visit /superadmin/ordersrequires sign-inrequires super-admin account

Super-admins can view all orders across every seller and release held funds after the 5-day escrow hold. Orders in Shipped status with shippedAt > 5 days ago show an enabled 'Liberar fondos' button. Clicking it calls stripe.payouts.create on the seller's Connected Account and transitions the order to Delivered.

Golden path

  1. Sign in with a super-admin account
  2. Navigate to /superadmin/orders
  3. Find a Shipped order where the 5-day hold from shippedAt has elapsed (button is green and enabled)
  4. Click 'Liberar fondos' — payout is sent to the seller's bank account and the order moves to Delivered

Use cases

  • View all platform orders across all sellers in a single table
  • Identify Shipped orders eligible for fund release (hold period elapsed)
  • See the hold expiry date for orders not yet eligible (button disabled with date tooltip)
  • Release funds with one click — payout goes directly to the seller's Stripe Connected Account
  • Order transitions to Delivered upon successful payout
  • Click 'Ver detalles' on any order to see full detail: items, shipping address, buyer contact info, and seller info in a side sheet
  • Seller receives a confirmation email with payout amount and order details when funds are released

Known gaps

  • Fund release is still manual — automated cron-based release is a V1 follow-up

M4 missing use cases

  • M4-1 (Stripe real-account payout testing, #44) — still open
  • M4-6 (Performance & stability pass, #49) — still open
  • Commission logic (M4-2, #45) is backend-only — no checkout summary shows the platform fee to the buyer
  • Automated escrow release after 5-day hold — V1 follow-up (manual release UI available at /superadmin/orders)
M5

In-App Notifications

Logged-in users see a Bell icon in the navbar with a live notification count. Counts are derived from existing order statuses — no extra database collections required. Email confirmations are also sent to the seller's real email address on every new sale.

Notification Bell
M5
Visit /ordersrequires sign-insign in to see the bell in the navbar

A Bell icon appears in the navbar for logged-in users. A red badge shows the total notification count, updated every 60 seconds. Clicking the bell opens a popover listing active notifications grouped by type: orders awaiting shipment (buyer), orders that have been shipped (buyer), and new sales to fulfill (seller).

Golden path

  1. Sign in to any account
  2. Look for the Bell icon in the top navbar — a red badge appears if there are active notifications
  3. Click the Bell to open the notification popover
  4. Click any notification row to navigate to the relevant orders page

Use cases

  • Buyer: see count of Paid orders waiting for the seller to ship
  • Buyer: see count of Shipped orders (new shipment event to review)
  • Seller: see count of new Paid orders that need to be fulfilled
  • Bell shows '9+' when count exceeds 9
  • Bell shows empty state message when there are no notifications
  • Notification count polls every 60 seconds without a page refresh
  • Seller notification email now goes to the seller's real account email (bug fix)

Known gaps

  • Notifications are not marked as 'read' — count clears naturally as orders progress to Delivered
  • No per-notification dismiss or mark-as-read action
  • No push notifications or WebSocket real-time updates (60s polling only)

Scope Gaps & Known Missing Features (M1–M4)

A QA checklist of flows that cannot be reached or tested through the normal golden paths in the current build.

M1 — Seller Listings

  • Deactivate listing (only delete exists)
  • Duplicate listing shortcut
  • Deep link to create-listing form
  • Bulk CSV listing import

M2 — Buyer Discovery

  • Set filter on /search/pokemon requires a set ID — no searchable dropdown of set names
  • Checkout success / confirmation page
  • Cart quantity editor
  • Wishlist / save for later
  • Market price & price history (M5)

M3 — Order Lifecycle

  • Buyer delivery confirmation
  • Buyer order cancellation
  • Email preview route
  • Admin escrow release UI at /superadmin/orders (seller-facing not planned)
  • Automated escrow release (V1)

M4 — Closed Beta

  • Stripe real-account payout testing (#44)
  • Performance & stability pass (#49)
  • Platform fee not shown to buyer at checkout
  • No custom admin moderation UI (Payload admin only)
  • NSFW image detection (V1)