Commit Graph
5 Commits
Author SHA1 Message Date
ced4568 1b6da0a966 feat(selfpaced): student-facing My Programs dashboard
- ProgramsTab.jsx: Active/Completed programs, real progress, deterministic Continue Learning
  (reuses the same launch/poll pattern MyLearningTab already established), entitlement-blocked
  states shown with a real reason, never a silent dead end.
- StudentDashboard.jsx: new My Programs tab. api.js: programs/program/launchProgram.
2026-08-25 12:08:44 -05:00
ced4568 5c7e49c399 feat(student): live student experience — real login, classroom, profile
- LoginScreen (credentialed, now the default entry point) with links to legacy pilot entry
  and forgot-password; SetPasswordScreen (shared activate/reset UI, driven by
  ?activate=/?reset= query params — no router library, matching this app's existing
  state-machine-per-shell convention); ForgotPasswordScreen (anti-enumeration, dev-only
  reset-token surface).
- ClassroomTab: LIVE NOW banner, join, heartbeat only while joined and the tab is mounted,
  guidance-only current-activity link, own Lab status/launch (reuses the My Learning tab's
  exact API), announcements, Need Help form. No chat, no video, no shell access.
- ProfileTab: identity, cohort, progress, achievements, active-session count,
  change-password (gated on has_credentials).
- PlatformShell rewritten as an explicit view state machine; StudentDashboard gained the new
  tabs; api.js/Platform.module.css extended to match.
2026-08-25 01:19:44 -05:00
ced4568 d4db8f99f5 feat(student): add learning tabs and Lab hint/assessment UX
StudentDashboard is now tabbed: My Learning (the original Phase 2A/2B flow, extracted
unchanged into MyLearningTab and extended with an overall percent-complete bar), Practice,
Assessments (available/active-with-live-countdown/history), Capstone (locked checklist ->
unlocked -> start/resume -> completed), Achievements (a flat dated list, not a leaderboard).

Inside the Lab UI: ProgressiveHints replaces the static hint array render when the Gateway has
stripped hints (detected via scenario.hints being undefined but hint_count present - standalone
dev mode never sees this, so it keeps the original behavior); a new top-level AssessmentBanner
shows a live countdown and completion count whenever a Platform assessment is running,
rendered alongside (not replacing) the pre-existing Lab-local exam-mode UI, which is untouched.
2026-08-18 14:35:59 -05:00
ced4568 ae75bb4cbe feat(auth): add server-controlled student and admin sessions
Replaces the Phase 2A pilot ?sid= query param with an HttpOnly,
SameSite=Lax session cookie. Gateway now derives student identity from
the session (via Platform API's /api/session/whoami) instead of trusting
a client-suppliable id, and checks ownership on every proxied HTTP and
WebSocket Lab request, not just the initial navigation.

Fixes a routing bug found during testing: the fallback route was using
'does this session own a running environment' to decide whether an
unprefixed /api/* call belonged to the Lab UI or the dashboard — true in
both places. Replaced with an explicit LAB_OWNED_PATHS allowlist of the
exact unprefixed paths the existing Lab UI actually calls.

e2e-phase2a.js rewritten to use a cookie jar instead of headers/query
params, with explicit impersonation-rejection tests added. 10/10 passing.
2026-08-18 12:22:58 -05:00
ced4568andClaude Sonnet 5 fb2945069c feat(student): add curriculum dashboard and lab launch/reset/recreate flow
StudentDashboard.jsx — "Up Next" curriculum view + Launch Lab flow, in one
component since they share state (environment status affects what curriculum
actions make sense).

- Renders GET /api/curriculum/path as-is: the existing RootNode path
  (Foundation -> Workloads -> Networking -> Configuration -> Troubleshooting
  -> Real Ops -> Capstone), no new structure invented. Capstone stays the
  locked placeholder from the earlier slice.
- Launch Lab -> POST /api/environment/launch, polls status every 2.5s while
  provisioning/resetting, transitions through none -> provisioning -> running
  -> error with a distinct UI state for each (EnvironmentPanel). On running,
  navigates to launch_path with the student's own id as ?sid= — a
  defense-in-depth ownership check the Gateway verifies on that specific
  navigation (see the gateway commit).
- One "Recreate Lab" control, calling POST /api/environment/reset — no raw
  destroy-without-recreate exposed to students, matching "don't expose raw
  destroy/admin controls beyond what is safe for a student." A visible note
  states progress is saved separately and survives.

Platform.module.css reuses the existing design tokens from index.css
(--green, --surface, --text, etc.) so this reads as the same product as the
Lab UI, not a bolted-on separate app.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-18 11:16:35 -05:00