Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion docs/ux-overhaul/production-route-migration.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# Production Route Migration

Phase 1 preserves route compatibility and establishes canonical role destinations without deleting deep links.
Phase 1 preserves route compatibility and establishes canonical role destinations without deleting deep links. Phase 2 begins the student `/learn` migration while keeping legacy student deep links available.

| Current route | Canonical route | Role | Redirect behavior | Guard behavior | Migration phase | Removal criteria | Deep-link risk |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `/home` | `/home` for teacher/admin, transitional for other roles | teacher, instructor, admin, super_admin-compatible | No redirect | `HomeSessionGuard`; child guards unchanged | Phase 1 | Only after all role dashboards have route-level replacements and analytics show low usage | High |
| `/learn` | `/learn` | student | Login routes students here after ready bootstrap | `HomeSessionGuard`; learner child routes unchanged | Phase 1 | None planned | Low |
| `/learn/products` | `/learn/products` visible as Courses, with course path links to `/learn/courses/:courseId` | student | No redirect | `HomeSessionGuard`; existing learner-product API still used | Phase 2 | Keep as transitional browse route until learner-product and course catalog surfaces are unified | Low |
| `/learn/courses/:courseId` | `/learn/courses/:courseId` | student | New canonical course overview; no redirect | `HomeSessionGuard`; course access remains enforced by backend endpoints and governed start behavior | Phase 2 | None planned; direct route should remain | Low |
| `/learn/paths` | `/learn/paths` | student | No redirect | `HomeSessionGuard`; existing programs API | Phase 2 partial | None until learning paths are redesigned | Low |
| `/learn/certificates` | `/learn/certificates` visible as Achievements | student | No redirect | `HomeSessionGuard`; existing certification APIs | Phase 2 partial | None until achievements are redesigned | Low |
| `/learn/resources` | `/learn/resources` | student | No redirect | `HomeSessionGuard`; no API | Phase 2 partial | Remove only if a supported resources surface is not planned | Low |
| `/learn/lesson/:id` | `/learn/lesson/:id` | student | No redirect; `:id` remains a student unit progress id | `HomeSessionGuard`; governed segment restore unchanged | Phase 2 | None planned | Low |
| `/workspace` | `/workspace` | content_admin | No redirect | `HomeSessionGuard` plus existing role guards | Phase 1 | None planned | Medium |
| `/workspace/learners` | `/workspace/learners` | org_admin | No redirect | Existing creator-role guard | Phase 1 | Replace only if organization home becomes a dedicated route | Medium |
| `/workspace/commercial` | `/workspace/commercial` with visible label `Community` | admin/content_admin/org_admin/teacher/instructor via existing creator role set | No redirect | Existing creator-role guard | Phase 1 | Add alias and deprecation only after community surface is redesigned | Medium |
Expand All @@ -15,6 +21,8 @@ Phase 1 preserves route compatibility and establishes canonical role destination
| `/home/sections` | `/home/sections` | teacher, instructor, org_admin | No redirect | Existing `RoleGuard` section roles | Phase 1 | Class/cohort IA aliases are implemented and smoke tested | High |
| `/home/courses` | `/home/courses` | teacher, instructor, student transitional | No redirect | Existing child route, no added guard | Phase 1 | Course library split is implemented and tested | Medium |
| `/home/programs` | `/home/programs` | teacher, instructor, student transitional | No redirect | Existing child route, no added guard | Phase 1 | Learning path route aliases are implemented and tested | Medium |
| `/home/certifications` | `/learn/certificates` for student-origin actions | student transitional | No redirect | Existing child route, no added guard | Phase 2 partial | Existing links aliased and achievements page redesigned | Medium |
| `/home/lesson/:id` | `/learn/lesson/:id` for student-origin actions | student transitional, staff preview transitional | No redirect | Existing authenticated guard; governed segment restore unchanged | Phase 2 partial | Remove only after staff lesson preview route is explicit and student bookmarks have an alias | High |
| `/home/me/preferences` | `/home/me/preferences` | all authenticated roles | No redirect | Existing authenticated shell | Phase 1 | Dedicated settings route aliases are implemented | Medium |

## Canonical Login Destinations
Expand All @@ -32,3 +40,6 @@ Phase 1 preserves route compatibility and establishes canonical role destination
- Browser bookmarks are preserved; no broad route deletion was performed.
- Unauthorized routes remain protected by existing route guards. Hidden navigation is not treated as authorization.
- `/workspace/commercial` remains the technical path in this phase, but visible navigation now uses `Community`.
- Phase 2 updates student-origin actions from the legacy student dashboard to navigate into `/learn/**` while preserving `/home/**` deep links.
- Phase 2 adds `/learn/courses/:courseId` as the canonical student course overview and keeps `/learn/products` as a transitional browse route.
- No dedicated unit route was added because existing APIs do not expose unit-level student progress or direct-link authorization.
7 changes: 7 additions & 0 deletions docs/ux-overhaul/shared-component-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
| Shell navigation service | `frontend/src/app/services/shell-navigation.service.ts` | Production active | Centralizes role-to-navigation and canonical route logic using existing permissions. |
| Confirmation dialog | `frontend/src/app/components/echo-confirmation-dialog/` | Available, not broadly connected | Supports default, destructive, and publish variants; focus trap and Escape behavior covered by unit tests. |
| Skeleton | `frontend/src/app/components/echo-skeleton/` | Available | Tokenized primitive for later page migrations. |
| Student curriculum | `frontend/src/app/components/student-curriculum/student-curriculum.component.ts` | Production active for student course overview | Renders unit hierarchy, lesson state labels, locked/current/complete states, and mobile layout. |

## Migrated Or Extended

| Component | Path | Status | Notes |
| --- | --- | --- | --- |
| Button | `frontend/src/app/components/echo-button/echo-button.component.ts` | Extended in Phase 2 | Adds `secondary` color support and optional `ariaLabel` for accessible student action labels. |
| Confirmation dialog | `frontend/src/app/components/echo-confirmation-dialog/` | Connected to assessment submission | Used as a neutral consequential confirmation before assessment attempts. |
| Lesson viewer | `frontend/src/app/shared/lesson-viewer.component.*` | Migrated for local activity states | Adds activity instruction, quiz validation alert, and current step state text without adding scoring behavior. |
| Certifications page | `frontend/src/app/pages/certifications/` | Migrated for student achievements | Uses shared loading, empty, and error states and learner-facing certificate language. |
| Authenticated shell | `frontend/src/app/pages/home/` | Production active | Adds skip link, role-aware mobile navigation, overlay, scroll lock, and focus return. |
| Header | `frontend/src/app/components/echo-header/` | Production active | Uses role-aware shell titles and shared state panels for organization states. |
| Sidebar | `frontend/src/app/components/echo-sidebar/` | Production active | Uses role-aware navigation sections and tokenized active/focus states. |
Expand All @@ -24,6 +29,8 @@
- Form controls, tables, filter controls, page-specific buttons, dashboard cards, and internal page layouts are still mixed Tailwind/SCSS implementations.
- Existing Storybook/design-lab artifacts remain references; production consumers were not migrated wholesale.
- Destructive actions still need page-by-page adoption of `EchoConfirmationDialogComponent`.
- Form controls, tables, filter controls, page-specific buttons, dashboard cards, and internal page layouts are still mixed Tailwind/SCSS implementations.
- Activity controls delegated to canvas, map, and storybook components still need full accessibility and responsive QA.

## Required Future Adoption

Expand Down
31 changes: 31 additions & 0 deletions docs/ux-overhaul/student-accessibility-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Student Accessibility Review

Date: 2026-07-11

## Completed

- `/learn` has one `h1`: "Continue your learning".
- Next learning appears first in DOM order after the page hero.
- Course progress bars include `role="progressbar"`, `aria-valuenow`, and text percentages.
- Student course states use text labels such as `Ready`, `In progress`, and `Complete`; status is not color-only.
- Loading, empty, and error states reuse shared `EchoLoadingStateComponent` and `EchoStatePanelComponent`.
- Lesson save state uses `role="status"` and save failure uses `role="alert"`.
- The lesson runtime return button has an accessible name: "Return to the course overview".
- Migrated controls use 44px-friendly button/link sizing and visible focus styles.
- `/learn/courses/:courseId` uses one `h1`, semantic ordered lists for unit and lesson hierarchy, text state labels, disabled lesson controls for locked/unavailable lessons, and accessible progress bars.
- Lesson runtime now exposes course, unit, and lesson-position context when the existing student-course data can resolve it.
- Quiz activity validation uses `role="alert"` and does not rely on color alone.
- Assessment submission uses the shared confirmation dialog with focus trap/Escape behavior supplied by `EchoConfirmationDialogComponent`.
- Certificate loading, empty, and error states use shared status/alert semantics.

## Risks

- Full keyboard walkthrough was not completed against a running seeded backend in this pass.
- Full automated contrast tooling was not run.
- Activity controls that delegate to canvas/map/storybook components still need device and assistive-technology QA in a later pass.

## Deferred Checks

- Keyboard-only seeded student journey through login, `/learn`, lesson, activity, completion, and return.
- Screen-reader verification for lesson activity controls and assessment result states.
- 200% zoom verification with real seeded lesson content.
31 changes: 31 additions & 0 deletions docs/ux-overhaul/student-activity-type-matrix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Student Activity Type Matrix

Date: 2026-07-11

Activity rendering remains in `frontend/src/app/shared/lesson-viewer.component.*`. Formal scoring remains in assessment routes and APIs.

| Type identifier | Renderer/component | API interaction | Submission model | Feedback model | States implemented | Accessibility risks | Responsive risks |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `video` | Native `video` or YouTube `iframe` | None in viewer | None | Browser media controls | In progress, ready to continue | Captions depend on media source | Wide media at mobile widths |
| `image` | Native `img` | None | None | None | In progress, ready to continue | Alt uses activity title | Large images need viewport checks |
| `coloring` | `ColoringCanvasComponent` | None in viewer | Local canvas interaction | None | In progress, ready to continue | Canvas keyboard alternatives remain a future risk | Canvas controls need mobile QA |
| `interactive_map` | `AfricaMapExplorerComponent` | None in viewer | Local interaction | Component-specific | In progress, ready to continue | Must remain keyboard operable | Map density at 390px needs visual QA |
| `storybook` | `StorybookViewerComponent` | Static storybook assets | None | None | In progress, ready to continue | Image alt/captions depend on pages | Image fit needs visual QA |
| `audio` | Native `audio` | None | None | Browser media controls | In progress, ready to continue | Captions/transcripts depend on content | Native controls vary by browser |
| `story` | Text block | None | None | None | In progress, ready to continue | Long text readability | Good after wrapping |
| `reflection` | Textarea | None | Local draft only | None | In progress, ready to continue | Draft is not authoritative progress | Mobile keyboard overlap needs visual QA |
| `checkpoint` | Text block | None | None | None | In progress, ready to continue | None beyond reading level | Good after wrapping |
| `quiz` | Radio options or fallback text input | None in viewer | Local selection before lesson completion | No correctness shown | In progress, validation-needed, ready to continue | Must not imply scored submission | Long options wrap on mobile |
| fallback | Text block | None | None | None | In progress, ready to continue | Unknown content quality | Needs visual QA per content |

## Implemented Interaction States

- Not started: future lesson steps in the step list.
- In progress: current activity step before required local interaction is satisfied.
- Validation-needed: quiz activity when Next is pressed without a selected answer.
- Ready to continue: current step can move forward.
- Completed: prior steps in the step list.

## Not Implemented Here

Submitted, correct, incorrect, partially correct, retry available, retry unavailable, and awaiting feedback belong to formal assessment behavior because no lesson activity submission endpoint exists.
37 changes: 37 additions & 0 deletions docs/ux-overhaul/student-assessment-behavior.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Student Assessment Behavior

Date: 2026-07-11

## Current API Behavior

- Assessments load through `ProgramsService.getAssessment(id)` -> `GET /api/assessments/{assessment_id}`.
- Assessment attempts submit through `ProgramsService.submitAssessment(id, answers)` -> `POST /api/assessments/{assessment_id}/attempts`.
- Availability is governed by `is_available_for_learner`, `learner_delivery_state`, and `learner_delivery_detail`.
- The frontend requires every question to have an answer before submission.
- Submission returns score, max score, percentage, passed, submitted timestamp, and per-answer correctness/points.
- If an assessment belongs to a program, existing certification evaluation is refreshed with `GET /api/certifications?program_id=...` and `POST /api/certifications/{id}/evaluate`.

## Implemented UX Rules

- Unavailable assessments hide the form and show a shared unavailable/blocked state.
- Learners see answer count before submission.
- Final submission uses `EchoConfirmationDialogComponent`.
- The confirmation explains that answers will be submitted for scoring and that this screen does not expose editing after submission.
- Submission loading uses the shared loading state and sets `aria-busy` on the form.
- Submission failure preserves answers, keeps the confirmation dialog open, and shows the failure message.
- Results use learner-centered language: `Passed`, `Needs more practice`, `Confirmed understanding`, and `Review this idea`.
- The page links to `/learn/paths` and `/learn/certificates`; legacy `/home` links were removed from visible student copy.

## Not Changed

- No grading policy changed.
- No retry policy changed.
- Correct answers are not newly revealed.
- No new assessment sessions or incremental save behavior were introduced.
- No backend endpoints were added.

## Known Gaps

- The API does not currently expose whether retry is available after a failed attempt.
- Teacher-review-required state is not clearly surfaced beyond generic availability fields.
- Question-by-question review is limited to the result data currently returned by the backend.
38 changes: 38 additions & 0 deletions docs/ux-overhaul/student-course-data-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Student Course Data Contract

Date: 2026-07-11

## Summary

The completed student Phase 2 course overview composes existing frontend services and backend endpoints. No backend endpoint, database schema, role model, or progress rule was changed.

| Field | Frontend source | Backend endpoint/schema | Returned | Derived | Optional | Safe to display | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Course identifier | `Course.id`, `StudentCourseWithDetails.course_id` | `GET /api/courses/{course_id}` -> `CourseResponse.id`; `GET /api/student-courses` -> `StudentCourseWithDetails.course_id` | Yes | No | No | Yes | Used by canonical `/learn/courses/:courseId`. |
| Course title | `Course.title` | `CourseResponse.title` | Yes | No | No | Yes | Primary page title. |
| Course description | `Course.description` | `CourseResponse.description` | Yes | No | Yes in frontend model | Yes | Hidden if missing; no generated objectives. |
| Course image | `CourseDraft.imageUrl`, legacy card fields | Not included in `CourseResponse` | No | No | Yes | Not used | Existing API gap; overview uses content-first layout. |
| Enrollment/access state | `StudentCourseWithDetails` match by `course_id` | `GET /api/student-courses` | Yes for enrolled courses | No | Yes | Yes | Not enrolled courses are startable only through existing enroll flow. |
| Start state | `startCourse()` response | `POST /api/start-course` -> `SegmentResponse` | Yes | No | Yes | Yes | Backend requires enrollment and governs availability. |
| Completion state | `StudentCourseWithDetails.status` | `StudentCourseWithDetails.status` | Yes | No | Yes | Yes | Completed courses show review-only action. |
| Unit list/order | `course.units[].order` | `CourseResponse.units` / `UnitResponse.order` | Yes | Sorted client-side by returned order | Yes | Yes | No separate unit progress endpoint is used for students. |
| Lesson list/order | `unit.lessons[].order` | `LessonResponse.order` | Yes | Sorted client-side by returned order | Yes | Yes | Frontend `Lesson` model now includes `order?: number`. |
| Locked/unlocked state | Current `SegmentResponse` | `GET /api/progress/segment` | Only current segment state | Partially | Yes | Yes with caveats | Only current governed lesson is openable; other lessons are labeled locked/unavailable without bypassing governance. |
| Current lesson | `SegmentResponse.lesson_id` | `SegmentResponse.lesson_id` | Yes | No | Yes | Yes | Used for current lesson state and course runtime context. |
| Current unit | Course hierarchy containing current `lesson_id` | `CourseResponse.units[].lessons[]` | No direct field | Yes | Yes | Yes | Derived only to display location, not to authorize navigation. |
| Course progress | `CoursesService.getCourseProgress()` | Composes `GET /api/progress/segment` | No direct percentage in backend response | Yes | Yes | Yes | Existing frontend behavior preserved. |
| Unit progress | Current unit marker plus completed-course status | No student unit progress summary endpoint | No | Limited | Yes | Yes with neutral labels | Labels are "Current unit", "Included in course", or completed-course counts. |
| Lesson progress | Current segment only | `SegmentResponse.status`, `delivery_state` | Partial | Limited | Yes | Yes with neutral labels | No per-lesson completion matrix is available. |
| Assignment context | Not currently consumed by student course overview | Assignment APIs exist separately | Not in student course response | No | Yes | Not shown | Avoids fabricated assignment behavior. |
| Program/path context | `ProgramsService` surfaces paths separately | `/api/programs` | Not in course response | No | Yes | Not shown on course overview | Future phase can connect program context if API supports it. |
| Badge outcome | Badge/cert preview on `/learn`; certificates page | Badge and certification APIs | Partial | No | Yes | Yes | Course overview links to Achievements without promising a specific badge. |
| Certification outcome | `ProgramsService.getMyCertifications()` | `/api/students/me/certifications` | Yes for earned certs | No | Yes | Yes | No download/print action is fabricated. |
| Prerequisites | None found in student API | N/A | No | No | Yes | Not shown | Backend gap if future UX requires prerequisite display. |
| Required vs optional lessons | Not returned in course hierarchy | N/A | No | No | Yes | Not shown | Avoided to prevent unsupported claims. |

## Known Gaps

- `CourseResponse` does not return a course image.
- Student APIs do not return a complete per-lesson state matrix for locked, completed, available, retry, or required/optional status.
- Unit progress is not returned as a student-facing summary.
- Program/path context is separate from the course response and is not joined into the overview in this phase.
Loading
Loading