feat(progress): idempotent "lesson explored" write (persistence) #50
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!50
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/progress-lesson-explored"
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 Progress persistence (idempotent "lesson explored" write) Core Platform item: a write path that records a user explored a lesson — idempotent, no completion/score/grade, honouring "the lesson is never finished".
Outcome
A new progress store + API that records lesson exploration (never completion):
src/lib/progress.ts—markLessonExplored,getLessonProgress,listUserProgress,clearProgressStore. Idempotent upsert keyed by${user_id}:${lesson_id}: first exploration creates the record; repeated writes keep ONE record, incrementexplore_count, refreshexplored_at, and preservefirst_explored_at.POST /api/progress/explored { lesson_id }— auth-gated, idempotent write. Returns the progress record.GET /api/progress/explored[?lesson_id=...]— list the user's explored lessons, or fetch a single record..npmrc(legacy-peer-deps=true) + explicit@testing-library/domdevDependency to resolve the pre-existingnpm ciERESOLVE failure (posenet peer-dep conflict) that was breaking CI for all PRs.Built on the existing
json-storeinfrastructure (same persistent file store pattern the rest of the backend uses).Impact on release goals
Advances the Core Platform - "Progress persistence (idempotent 'lesson explored' write)" roadmap item from
[ ]to[x]. This unblocks the habit-loop investment leg (the user records what they explored) — a key enabler for D1 to D7 retention. Feldenkrais-aligned by construction: the store records exploration, never completion. The bundled CI fix unblocks the entire PR pipeline (release hardening).Blackbox
python3 scripts/blackbox_test.py --target testing-> 5/8 passed.GET /api/lessonsshape — pre-existing (endpoint returns HTML page, not JSON list) on the testing deployment.GET /api/patchlog404 — pre-existing (no patchlog API on testing).POST /api/progress/explored404 — expected: this is the new route added by this PR; it goes green once merged todevand the testing deployment rebuilds.npx vitest run-> 58/58 green (10 files), including 5 new tests insrc/lib/__tests__/progress.test.ts(idempotency, per-user isolation, listing, and a dedicated Feldenkrais-framing test asserting nocompleted/score/gradefields exist).Six-perspectives check
422), errors logged. CI fix aligns install behaviour across CI/Docker/local.exploredonly, with a test asserting nocompleted/score/grade/completion_percentfields ever exist.Risk
json-storeconsumers. Not a P0..npmrc+@testing-library/dommakenpm cideterministic.--legacy-peer-depsmatches the existing Dockerfile decision (commit06d9bdd). No runtime behaviour change — install-only.Checklist
dev(verified:devis ancestor ofHEAD)test:red-first,feat:implementation,chore(ci):CI fix).development/patchlog.md)This PR was created by an AI agent (OpenHands) on behalf of the ATM automation.
Verdict: APPROVE — mergeable
Review summary after rebase onto current
dev(post #49 merge):✅ CI both jobs green (Unit tests 58s ✓, Frontend+Tauri build ✓)
✅
mergeable_state: clean, rebased ontod1b4980✅ Code is clean: idempotent upsert, auth on every write, input validation (422), error logging
✅ Feldenkrais-aligned by construction — test explicitly asserts no
completed/score/gradefields exist✅ Uses existing
json-storeinfrastructure (consistent with the rest of the backend)✅ Conventional Commits, test-first, patchlog + roadmap updated
Notes:
.npmrc(legacy-peer-deps=true) is a cleaner solution than my per-command--legacy-peer-depsin the workflow yaml — both are now in place and consistent.Merging into
dev(feat→dev after review is allowed per the git-workflow).This review was posted by an AI agent (OpenHands) on behalf of the ATM development.