feat(share): Share-the-felt-change flow (ATM viral hook) #52
No reviewers
Labels
No labels
backend
bug
completed
documentation
duplicate
enhancement
feature
frontend
good first issue
help wanted
in-progress
invalid
performance
phase-1
Phase1
Phase2
Phase3
planning
question
refactor
security
test
testing
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Kalle/ATM!52
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/share-felt-change"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Plan
Deliver the Core Platform "Share-the-felt-change flow (viral hook)" roadmap item — the ATM share hook built around the felt "Aha-moment": after a lesson the user records what they noticed (open-ended noticing, never a score/rating/grade) and can share that felt change, with factual, anonymized social proof.
Outcome
End-to-end share-the-felt-change flow:
src/lib/share.ts— felt-change store: idempotent upsert by(user, lesson)(immutablecreated_at, refreshesupdated_at), distinct-user count for anonymized social proof, and a locale-stablebuildShareTextcomposer.src/lib/share-client.ts— client-safe boundary (purebuildShareText+FeltChangetype, no Nodefs); server-onlyshare.tsre-exports it. Fixes the Tauri static-export build break.POST/GET /api/share— auth-gated write + read returning the user's note plus the anonymizedcount.src/components/ShareSheet.tsx— open-ended noticing prompt ("Was hast du bei dieser Lektion bemerkt?"), save, Web Share with clipboard fallback.AudioPlayer.tsxvia a "notice/share" button next to Rest;lessonTitlethreaded fromLessonDetailClient.tsx.sharei18n namespace added to all 9 locales (de, en, es, fr, he, pt, pt-BR, ru, zh) + idempotent injection scriptscripts/add_share_i18n.py.Update — 2026-07-04 (OG metadata + blackbox + TSC fix)
This PR was green on functionality but incomplete for release. Three additions:
generateMetadatainlibrary/[id]/page.tsx): og:title/description/type=article/url/siteName + Twitter card. Server-side lesson lookup with graceful fallback. Now any shared lesson URL renders a rich preview card — the viral loop's last mile.blackbox_test.py— share-API POST/GET round-trip, note persistence, non-judgemental social-proof count, auth 401, blank-note 422, OG-metadata assertions. 32/32 green on local.tsc --noEmitwas failing on a?rawimport + untyped callback (P1 build risk). Addedsrc/types/raw.d.tsambient declaration + typed the callback. TSC now clean.Impact on release goals
Core Platform "Share-the-felt-change flow (viral hook)" moves
[ ]→[x]. Core Platform is now 4/5 done (Auth ✅, Progress persistence ✅, Share-the-felt-change ✅, Audio engine [~]). This is the release-defining viral feature: it operationalizes the felt Aha-moment as the share hook and the habit-loop "investment" leg, strengthening D1→D7 retention without strain/judgement.Blackbox
python3 scripts/blackbox_test.py --target local→ 32/32 greenpython3 scripts/blackbox_test.py --target testing→ 22/32 (the 10 share-API + OG failures are expected — they go green once this branch merges to dev and deploys; they test code that only exists on this branch).Six-perspectives check
Risk
Low — additive lib + route + component + i18n keys + a button + OG metadata; no existing behaviour changed. The felt-change store uses the existing json-store pattern. Share text is composed by the locale-stable lib helper. The social-proof count is distinct-user and anonymized; it cannot inflate via re-saves and never becomes a leaderboard/streak. OG metadata is additive (new
generateMetadata, no routing change).Checklist
dev(rebased 2026-08-13: merged dev in, conflicts resolved behaviour-preservingly)tsc --noEmitpasses)Note: The CI/Tauri build can take >15 min. Please review the code; CI status will populate asynchronously. This PR was created/updated by an AI agent (OpenHands) on behalf of the ATM automation.
P0 build break — fixed (client/server boundary)
The failing "Frontend + Tauri build" job was caused by a client/server boundary violation:
ShareSheet.tsx("use client") importedbuildShareTextfrom@/lib/share, which co-locates the fs-backed persistence (json-store). During the Tauri static export the API routes are stripped, but client components are still bundled — so Node'sfsleaked into the client/SSR bundle and the build crashed.Fix — split along the boundary:
src/lib/share-client.ts(NEW): pure, client-safebuildShareText+FeltChangetype. Nofs, nojson-store.src/lib/share.ts(server-only): keeps the fs-backed persistence and re-exportsbuildShareTextso server code keeps one import surface.src/components/ShareSheet.tsx: importsbuildShareTextfrom@/lib/share-client.share-client-boundary.test.tsthat fails if the forbiddenfs/json-storeimport is re-added to the client module.Verified locally (the exact failing CI step):
TAURI_BUILD=1 npm run build(static export) now exits 0 ✅/api/lessonsHTML-vs-JSON gap, unrelated to this change).CI is re-running now. The code is reviewable; CI status will populate asynchronously.
This update was created by an AI agent (OpenHands) on behalf of the ATM automation.