mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 17:41:09 +02:00
feat(cards-server): Phase δ.1 — subscriptions + version reads + smart-merge diff
Server-side plumbing for Phase δ. Frontend hookup follows in δ.2.
- services/subscriptions.ts: subscribe/unsubscribe (idempotent
upsert on (user, deck), stamps the latest_version_id at
subscribe-time so the client knows what it pulled). listForUser
returns each sub with `updateAvailable: currentVersion !== latest`
so the client can render an update indicator without a second
round-trip. Refuses paid decks with 403 — that path comes back
in Phase ζ once the credits Marketplace lands.
- versionWithCards: deterministic ord-ordered card payload for a
specific version. Read-public so anonymous browsers can preview
a deck's content.
- diffSince: smart-merge payload between any two versions. Splits
the latest cards into added/changed/unchanged + lists removed
by content_hash. The 'changed' bucket is heuristic (ord-position
pair where one was removed and one was added) — solid enough
until Phase ε's pull-request pipeline gives us real card
lineage.
- routes/subscriptions.ts mounts: GET /v1/me/subscriptions,
POST/DELETE /v1/decks/:slug/subscribe (auth required),
GET /v1/decks/:slug/versions/:semver (public),
GET /v1/decks/:slug/diff?from=<semver> (public).
cards-web layout fix:
- Marketplace surface (/explore, /u/, /d/) was previously gated
behind the AuthGate — anonymous browsers got pushed to /login
via client-side navigate. PUBLIC_PATHS extended so those routes
SSR + render unauthed.
Validated: tsc clean on cards-server, svelte-check 0/0 on cards-web.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e77134bd8b
commit
86a01426e8
4 changed files with 317 additions and 1 deletions
|
|
@ -14,7 +14,10 @@
|
|||
|
||||
// Auth/marketing pages render outside the gate so first-time visitors
|
||||
// can actually reach them. Everything else is gated.
|
||||
const PUBLIC_PATHS = ['/login', '/register', '/forgot-password'];
|
||||
// Public marketplace surface — anyone can browse decks/profiles/explore
|
||||
// without signing in. AuthGate kicks in once the user opens their own
|
||||
// decks/learn pages.
|
||||
const PUBLIC_PATHS = ['/login', '/register', '/forgot-password', '/explore', '/u/', '/d/'];
|
||||
const isPublic = $derived(PUBLIC_PATHS.some((p) => page.url.pathname.startsWith(p)));
|
||||
|
||||
function handleAuthReady() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue