Repository navigation
feat(club): share a card set with the club - #128
Merged
Merged
Conversation
An admin or editor presses "Share with my club" on one of their own custom card sets in Card Images. The images go to R2 under club-card/<clubId>/ and the set to club-cards:<clubId>, and the club's ver moves, so every club device downloads it into IndexedDB and lists it in the picker. A device that never chose cards of its own opens on the club's set; one that did keeps its own, with the club's one tap away (toastmaster_card_source). A lapsed or left club drops the set and the device's own choice shows again. Admins can remove the set from /club/admin. The images are private: they live outside club/<clubId>/, which /api/club-assets serves to anyone. Uploads are checked against their SHA-256, sniffed as JPEG/PNG/WebP, capped at 2 MB each and 20 MB per club. Publishing prunes images no set names, sparing uploads under 15 minutes old. Phase 1 of docs/plans/10-pro-is-the-club-plan.md (local plan, not tracked). New Zoom-client spec: e2e/zoom-client/club-card-sets.md (draft, not yet run).
Conflicts kept both sides: LiveTab.jsx imports (dev's getZoomParticipants plus this branch's card-sync helpers) and the 'Not covered' lists in timer-core.md and timer-sounds.md.
Share with my club sent the row's own label, "Custom 1", as the club set's label. Every other club device has its own "Custom 1", and the publisher's picker showed two rows with the same name. Sending no label lets the set read "<club> cards" in the picker and in the console.
CC-01 to CC-07 ran in the real Zoom client (B = the web app). Nothing failed. CC-07 now says the set leaves B on its next club refresh, which is at most daily, and B shows its own choice rather than Classic. New CC-09 covers a republish pruning the old image. CC-02 expects the '<club> cards' label from the label fix and is marked stale until it is rerun; CC-08 (club lapse) is not run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Custom card images followed a person between their own computers (personal settings sync). The timer role rotates every week, so the person who uploaded the club's artwork was rarely the one timing with it. This is Phase 1 of moving Pro to "one Pro account for your whole club": card artwork, the one personal-sync setting that can't be redone in a minute, now travels with the club code instead. Personal sync itself is untouched here; removing it is Phase 2.
What changes
toastmaster_card_source, the same rule as club presets)./club/adminhas a Card set section with the four cards and Remove card set (admin only).worker/club-cards.js):PUT /api/club/cards/<hash>uploads one image (admin or editor, device not revoked, club entitled).PUT /api/club/cardspublishes the set and bumpsver. Every hash must already be uploaded (409missing_imagesotherwise; the client re-uploads once and retries).GET /api/club/cards/<hash>serves an image to any club device, or to an admin's console session. Private cache.DELETE /api/club/cardsremoves the set (admin).club-cards:<clubId>, its own key, because a presets publish rebuildsclub-presets:from scratch.packages/shared/clubCards.jsdownloads missing images into IndexedDB at start-up and on every club change. Both apps re-show the current card when the set arrives or goes away.Security
club-card/<clubId>/<hash>, not underclub/<clubId>/, which/api/club-assets/*serves to anyone. A test checks the public route can't reach them.Production impact
None expected yet. Joining a club goes through the
proflag, which is archived in PostHog, and production has no clubs. The new routes are not flag-gated, the same as presets. Their Worker route is reachable, but every write needs an admin or editor of an existing club.Testing
npm test: 2234 passed. New:worker/club-cards.test.js(25),packages/shared/__tests__/clubCards.test.js(18), 7 in the ZoomCardImagesModal.test.jsx.npm run test:e2e: 41 passed.npm run build:weband the Zoom app build succeed.npm run test:specs: new spece2e/zoom-client/club-card-sets.md(draft, not run in a real Zoom client).timer-core.mdandtimer-sounds.mdwere reviewed against theLiveTab.jsxchange, and only their "Not covered" lists changed.FLAGS_FORCEback at"1"(it is"0"since 4a526d0).