Skip to content

feat: study cohorts — group enrollment with shared progress & leaderboard - #1040

Open
zeemscript wants to merge 1 commit into
bakeronchain:mainfrom
zeemscript:feat/study-cohorts
Open

feat: study cohorts — group enrollment with shared progress & leaderboard#1040
zeemscript wants to merge 1 commit into
bakeronchain:mainfrom
zeemscript:feat/study-cohorts

Conversation

@zeemscript

Copy link
Copy Markdown

Summary

Implements #1027 — study cohorts (squads): small groups of learners enrolled in the same track who share a group progress view, a private discussion thread, and a group leaderboard. Closes #1027.

What's included

Database

  • Migration 025_study_cohorts.sql (+ .undo.sql): cohorts and cohort_members tables per the issue spec, with indexes on course_slug / learner_addr and a max_members > 0 check.

Backend (createCohortsRouter, mounted under /api)

  • POST /api/cohorts — create (auth + zod validation); validates the course exists; creator auto-joins in a transaction.
  • GET /api/cohorts?course= — list cohorts with live member counts.
  • POST /api/cohorts/:id/join — capacity-checked inside a transaction with a SELECT ... FOR UPDATE row lock so concurrent joins can't oversubscribe; idempotent when already a member.
  • POST /api/cohorts/:id/leave — idempotent no-op when not a member.
  • GET /api/cohorts/:id — members with per-member progress joined against milestone_reports (approved only) plus a group completion %; ordered by milestones completed so the payload doubles as the leaderboard. Falls back to lesson count for courses without milestone rows.

Frontend

  • New Squads tab on the course page (LessonView, alongside Lesson/Forum).
  • SquadsPanel: browse/join cohorts for the course or create one.
  • CohortDetailView: member roster with progress bars, group completion ring, ranked leaderboard (crown for Bump the npm-minor group with 11 updates #1, "You" marker), and an embedded discussion thread reusing CommentSection scoped to thread id cohort-<id> (members only).
  • React Query hooks in src/hooks/useCohorts.ts using the shared apiFetchJson wrapper.

Tests

  • server/src/tests/cohorts-api.test.ts (16 tests): capacity enforcement, join/leave idempotency, group progress aggregation, auth/validation, course-not-found.
  • src/components/cohorts/CohortDetailView.test.tsx (4 tests): ring/roster rendering, leaderboard "You" marker, cohort-scoped discussion, full-squad join disabled.

Repo fix (needed to build)

  • package-lock.json had a corrupted entry (node_modules/esbuild/node_modules/@esbuild/aix-ppc64 with no version field) that made npm install / npm ci fail with npm error Invalid Version:. Removed the stub so npm resolves the proper top-level entry.

Acceptance criteria

  • A learner can create and join a cohort for a course
  • Cohort detail shows real per-member progress (approved milestone_reports)
  • Capacity is enforced; can't join a full cohort (409, race-safe)
  • Discussion thread scoped to the cohort works (reuses CommentSection)

Verification

  • Server: 16 new Jest/supertest tests pass; tsc --noEmit clean.
  • Frontend: 4 new vitest tests pass; vite build succeeds; no new eslint errors.
  • Pre-existing LessonView.test.tsx failures are identical on pristine main (18 failed) — unrelated to this change.

…oard

Implements bakeronchain#1027: small learner squads per course with shared progress,
a private discussion thread, and a group leaderboard.

Backend:
- Migration 025: cohorts + cohort_members tables (with undo)
- POST /api/cohorts (auth, creator auto-joins), GET /api/cohorts?course=
- POST /api/cohorts/:id/join — capacity-checked in a transaction with
  row lock, idempotent; POST /api/cohorts/:id/leave — idempotent
- GET /api/cohorts/:id — members with per-member approved-milestone
  progress (joined against milestone_reports) and group completion %,
  ordered as the squad leaderboard
- Jest/supertest coverage: capacity enforcement, join/leave idempotency,
  group progress aggregation (16 tests)

Frontend:
- "Squads" tab on the course page (LessonView)
- SquadsPanel: browse/join/create cohorts for a course
- CohortDetailView: roster with progress bars, group completion ring,
  leaderboard, and cohort-scoped discussion reusing CommentSection
  (thread id "cohort-<id>", members only)
- React Query hooks in useCohorts.ts; vitest component coverage

Also fixes a corrupted package-lock.json entry
(node_modules/esbuild/node_modules/@esbuild/aix-ppc64 had no version)
that made npm install/ci fail with "Invalid Version".
@Anuoluwapo25

Copy link
Copy Markdown
Contributor

please fix checks

@Anuoluwapo25

Copy link
Copy Markdown
Contributor

Hi @zeemscript, Just want to confirm if you are still working on this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Study cohorts — group enrollment with shared progress & leaderboard

2 participants