RipRoster — Member Guide
Who this is for: a community member with a box at a RipRoster store. You join a store with an invite code, keep your cards in your box, browse the catalog, propose trades, ship cards in, and see your cards revealed on the live Rip & Ship show.
If you run the store, see the Streamer / Shop guide. If you are a YouTube viewer, see the Viewer guide.
This guide describes what RipRoster does today. Where something is handled by your streamer or only comes alive after the store is deployed, it says so plainly.
Your role: member. Two capabilities are member-only and you will see them throughout this guide:
trade:propose— propose, accept, decline, and cancel trades, announce inbound packages, and bind a package to a mail-in trade. (Box-gated: you need a box at the store.)profile:edit:own— edit your own profile (your YouTube alias) and flip the "available for trade" switch on your own cards.
No store role (owner / streamer / moderator / staff) holds these, and you do not hold any of the store-side capabilities. The authoritative matrix is docs/AUTH-ROLES.md.
1. Joining a store
Your streamer gives you a member invite code. You redeem it to become a member of that store.
- Open the join / redeem screen.
- Enter the invite code your streamer shared.
- Submit to join. Gate:
POST /api/invites/redeem— membership-optional (you do not need to be a member yet; redeeming is how you become one). The code must be valid: not revoked, not expired, not exhausted, and you must not already be a member of that store.
See how the invite flow works in Diagram D4 below (shared with the staff invite lane).
Today's note — your box and handle are set by your streamer. A freshly self-redeemed member starts with an empty box and no handle. There is no in-app screen for you to set your own name, handle, or box id yet. Today your box is stamped when your streamer checks your first inbound package into a location (see §8). Until then your box page reads as empty and you may appear to others as a nameless "@" in trade-partner pickers. This is expected — ask your streamer to get you set up.
Diagram D4 — Invite → redeem / accept
diagram sourceflowchart TD
subgraph A["Member invite code"]
A1["Owner / streamer / moderator generates a code<br/>(invite:manage)"]
A2["Member redeems the code<br/>(POST /api/invites/redeem)"]
A3{"Valid? not revoked /<br/>not expired / not exhausted /<br/>not already a member"}
A4["Joins the store as a member"]
A1 --> A2 --> A3
A3 -- yes --> A4
A3 -- no --> A5["Rejected (409 / expired / exhausted)"]
end
subgraph B["Staff invite"]
B1["Owner generates an invite with a FIXED role<br/>(staff:manage — streamer / moderator / staff)"]
B2["Invitee accepts<br/>(POST /api/staff/accept)"]
B3{"Valid? not revoked /<br/>not consumed"}
B4["Joins with that fixed role (no box)"]
B1 --> B2 --> B3
B3 -- yes --> B4
B3 -- no --> B5["Rejected (409)"]
end
📸 SCREENSHOT: the redeem / join-a-store screen with the invite-code field — no-store / redeem — member (noMembership at the moment of redeeming). Owner: capture from the live site and replace this block with the image.
2. Your box
My box is your home page. It shows your cards and the ways you can act on them.
- Open My box.
- Each card shows its art and a status badge: In box, In trade, or On the way.
- Use the filter tabs — All / Available / In trades / On the way — to narrow the view.
- Two call-to-action buttons live here: Explore the trade floor (browse and propose trades) and Ship my order (buy shipping home — see §12).
Gate: the box page is member-only (it is your own box; store roles do not have one).
📸 SCREENSHOT: My box landing with card tiles + status badges + filter tabs — #/box — member. Owner: capture from the live site and replace this block with the image.
3. Set up your profile + YouTube name
My profile is where you set the name shown when your card is revealed on stream.
- Open My profile.
- Your name, handle, and box are read-only — your streamer sets these (see §1).
- Your YouTube alias is yours to edit. This is the name the audience sees on the on-stream reveal.
- When your alias is unset, a dismissible "set your YouTube name" banner appears (on the box and profile pages). Setting an alias clears it.
Gate: editing your profile / alias is profile:edit:own — member-only.
Why set your alias? On a reveal, the stream shows your YouTube alias if you set one; if you leave it blank it falls back to your app @handle. Setting the alias means the audience sees the name you want. (See §11 and the Viewer guide.)
📸 SCREENSHOT: My profile form (read-only name/handle/box + editable YouTube alias) AND the dismissible "set your YouTube name" banner — #/profile and #/box — member (alias unset). Owner: capture from the live site and replace this block with the image.
4. Browsing the catalog & searching
The card catalog is open to everyone at the store — browse it to find cards to trade for.
- Open the Card catalog. Browsing is set-first: start at the sets index (
#/sets). - Open a set to see its cards (
#/sets/<id>). - Use the sort control on a set — including price high → low and price low → high.
- Open a single card view (
#/card/<id>) for its detail. - Use global search to jump straight to a card by name.
Gate: the catalog is read-only and reachable by any membership (no special capability).
📸 SCREENSHOT: sets index, a set-detail with the sort control (price high→low), and a single card view — #/sets, #/sets/<id>, #/card/<id> — member. Owner: capture from the live site and replace this block with the image.
5. Marking cards available for trade
Other members can only pick your card in a trade once you mark it available.
- On My box, open one of your own cards that is ready (in your box).
- In the item dialog, flip the "available for trade" switch on.
- The card is now choosable by others as a trade target; flip it off to pull it back.
Gate: PATCH /api/items/:ref/availability = profile:edit:own plus ownership. The switch only renders on your own ready card — you cannot change availability on anyone else's card. This single flag gates both trade kinds (in-hand and mail-in): an unavailable card cannot be requested.
📸 SCREENSHOT: an own ready card's item dialog with the "available for trade" toggle — #/box item dialog — member. Owner: capture from the live site and replace this block with the image.
6. Proposing an in-hand trade
An in-hand trade is a swap where both cards are already in members' boxes at your store.
- Open the trade builder (from "Explore the trade floor" or a partner's card). It opens in In-hand mode.
- Pick card(s) from your box to give.
- Pick card(s) from the partner's available cards to receive.
- Add an optional note.
- Send the proposal.
Gate: trade:propose — member-only (and you need a box). The cards you request must be marked available (§5).
Use Diagram D5 to decide between an in-hand and a mail-in trade.
Diagram D5 — In-hand vs mail-in trade (decision)
diagram sourceflowchart TD
Q{"Do you have the card<br/>in your box right now?"}
Q -- "Yes, it's in my box" --> IH["In-hand trade<br/>(both cards already in boxes)"]
Q -- "No, I'm shipping it in" --> MI["Mail-in trade<br/>(pick from box OR whole catalog;<br/>both parties ship; tracking + arrival<br/>gate completion)"]
IH --> C["Streamer completes → instant ownership swap"]
MI --> C
C --> R["Reveal plays on stream"]
📸 SCREENSHOT: the in-hand trade builder (give/receive columns) — trade builder modal — member. Owner: capture from the live site and replace this block with the image.
7. Proposing a pre-arrival mail-in trade
A mail-in trade is for a card you do not have in your box yet — you (and the counterparty) ship the cards in, and the trade completes once both arrive.
- In the trade builder, switch the mode toggle to Mail-in.
- Pick one card per side. Each side can come from either:
- a card already in your box, or
- a catalog search of the whole database — for a card that is not in any box yet (a typeahead search).
- Choose the counterparty (the member on the other side).
- Send the proposal.
Gate: trade:propose — member-only. The card you want to receive from the counterparty must be marked available by its owner (§5).
The 72-hour tracking window. The builder explains it: once your mail-in trade is accepted, both parties have 72 hours to upload tracking (announce + bind a package — see §8). If fewer than two packages are uploaded in time, the trade expires.
See the mail-in lifecycle in Diagram D1 below, and the in-hand-vs-mail-in decision in Diagram D5 (§6).
Diagram D1 — Mail-in trade lifecycle
diagram sourcestateDiagram-v2
[*] --> proposed: Offer sent (proposed)
proposed --> awaiting_tracking: Accepted — both upload tracking within 72h (awaiting_tracking)
proposed --> declined: Declined (declined)
proposed --> cancelled: Cancelled (cancelled)
awaiting_tracking --> in_transit: Both packages on the way (in_transit)
awaiting_tracking --> expired: 72h window, fewer than 2 uploaded (expired)
awaiting_tracking --> cancelled: Cancelled (cancelled)
in_transit --> arrived: Both cards arrived & checked in (arrived)
in_transit --> voided: 14d / mismatch / cancel-after-ship — cards ship back (voided)
arrived --> completed: Done! Reveal fires, cards swap owners (completed)
arrived --> voided: 14d / mismatch — cards ship back (voided)
completed --> [*]
declined --> [*]
cancelled --> [*]
expired --> [*]
voided --> [*]
Acceptance auto-chains accepted → awaiting_tracking in one step. Ownership only ever swaps on completed; every other terminal (declined, cancelled, expired, voided) leaves the cards with their original owners, and a voided card that already arrived ships back to its sender.
📸 SCREENSHOT: the trade builder with the In-hand ⇄ Mail-in mode toggle on Mail-in — trade builder — member. Owner: capture from the live site and replace this block with the image.
📸 SCREENSHOT: a mail-in side picker showing "your box" cards AND the catalog typeahead results — trade builder — member. Owner: capture from the live site and replace this block with the image.
📸 SCREENSHOT: the chosen-card confirmation chip for a mail-in side — trade builder — member. Owner: capture from the live site and replace this block with the image.
8. Announcing an inbound package & uploading tracking
When you ship a card in — for a mail-in trade or just to add it to your box — you announce the package so your streamer can receive and check it in.
- Open My submissions.
- Click New submission and fill in:
- the tracking number,
- the carrier,
- the list of cards, one card per line.
- Submit to announce the package. It now shows in your submissions list (and your streamer's Inbound queue).
- For a mail-in trade: once the trade is accepted, open Upload tracking to bind an announced package to that trade — within the 72-hour window (§7).
Gate: creating, editing, and cancelling a submission, and binding a package to a trade, all require trade:propose — member-only.
See the inbound flow in Diagram D3 below, and where a mail-in trade sits in Diagram D1 (§7).
Diagram D3 — Inbound package → check-in
diagram sourceflowchart TD
A["Member announces a package<br/>(announced)"] --> B["Streamer marks received<br/>(received)"]
A -. "carrier reports Delivered<br/>(accelerator, once deployed with a key)" .-> B
B --> C{"For each declared card<br/>(declared)"}
C -- "card arrived" --> D["Check in to member's box<br/>(checked_in)"]
C -- "card missing" --> E["Didn't arrive<br/>(not_arrived)"]
D --> F["Package fully processed<br/>(closed)"]
E --> F
📸 SCREENSHOT: the New-submission (announce inbound package) form — inbound form modal — member. Owner: capture from the live site and replace this block with the image.
📸 SCREENSHOT: My submissions list with a package card + its status chip — #/inbound — member. Owner: capture from the live site and replace this block with the image.
📸 SCREENSHOT: the Upload-tracking (bind package) modal listing announced packages — trade detail — member. Owner: capture from the live site and replace this block with the image.
9. Finding your trades across tabs
My trades collects everything you are part of. You only ever see your own trades (the server scopes the list to you).
- Open My trades.
- The Open trades tab includes the live mail-in states —
proposed,accepted,awaiting_tracking,in_transit, andarrived— so an accepted mail-in trade stays visible with its Upload-tracking call to action until it completes or ends. - Terminal trades (
completed,declined,cancelled,expired,voided) move to history. - A mail-in trade shows a "Mail-in" kind badge and its sub-status chip so you can tell it apart from an in-hand trade at a glance.
Gate: the list is server-scoped to you — you see only trades you are a party to.
📸 SCREENSHOT: My trades with an open mail-in trade showing its "Mail-in" kind badge + sub-status chip + Upload-tracking CTA — #/trades — member. Owner: capture from the live site and replace this block with the image.
10. Accepting / declining / cancelling
Respond to trades proposed to you, and manage your own open proposals.
- When someone proposes a trade to you, open the incoming-proposal modal.
- Accept or Decline it. Gate: you must be the recipient to accept or decline.
- Cancel an open trade from either side. Gate:
trade:propose. - Ship-back confirmation: cancelling a mail-in trade after a package has already shipped asks you to confirm — because the cards in transit have to be shipped back to their senders.
Gate: accept / decline require you be the recipient; cancel is available to either party (trade:propose).
📸 SCREENSHOT: an incoming-proposal modal (accept/decline) — #/trades — member (recipient). Owner: capture from the live site and replace this block with the image.
11. Your reveals (the "your card was revealed" notification)
When your card is revealed on stream, it is recorded for you in My Mail Day reveals on your box page.
- Open My box.
- Find the "My Mail Day reveals" section — a persistent list of your cards as they appeared on stream.
- Each entry shows the card art, the counterparty's alias, when it aired, and the play count (×count).
This is the plain in-app notification — there is no toast or pop-up. The list is yours and persists.
Gate: GET /api/me/reveals — member-only.
Where you sit in the reveal sequence is shown in Diagram D2 below: your streamer fires the reveal, the audience sees it on the YouTube stream, and the server best-effort writes the record you see here.
Diagram D2 — Mail Day reveal (sequence)
diagram sourcesequenceDiagram
participant S as Streamer (RipRoster app)
participant Srv as RipRoster server
participant OBS as OBS browser source
participant YT as YouTube audience
participant M as Member's app
S->>Srv: Click "Play on stream" (POST /api/overlay/trigger — trade must be completed)
Srv->>OBS: Publish "event: reveal" over the per-tenant live channel (SSE)
OBS->>OBS: Render the reveal animation
OBS-->>YT: Audience sees the reveal on the YouTube stream
Srv->>M: Best-effort write a reveal record
M->>M: Member later sees it in "My Mail Day reveals"
📸 SCREENSHOT: the "My Mail Day reveals" section with at least one reveal entry (card art, counterparty alias, time, ×count) — #/box — member. Owner: capture from the live site and replace this block with the image.
12. Buying shipping home
When you want your cards mailed to you, you buy shipping through your streamer's Shopify link.
- On My box (or the Shipping page), click Ship my order.
- The handoff opens your streamer's Shopify product link (the "Ship my order" URL the store set).
- If you have open trades, an advisory reminds you to finish or cancel them first — your box can't ship while a card is mid-trade.
Gate: the shipping page is member-reachable; the handoff uses the store's configured Shopify URL.
📸 SCREENSHOT: the "Ship my order" Shopify handoff modal (incl. the open-trades advisory variant) — #/shipping — member. Owner: capture from the live site and replace this block with the image.