-
Notifications
You must be signed in to change notification settings - Fork 1
Roadmap
RubricMaker is an offline-first rubric creation and grading tool for educators. This roadmap lists completed phases first (newest at the top of that section is the most recently shipped), then planned work.
- ✅ Rubric builder with multiple scoring modes (Total Points, Weighted, Single-Point)
- ✅ Interactive grading interface with score modifiers
- ✅ CEFR framework integration (Can-Do statements)
- ✅ Student self-assessment & peer review
- ✅ Essay assignments with rich text editor
- ✅ Analytics dashboard with class statistics
- ✅ Multi-format export (PDF, DOCX, CSV)
- ✅ Student portal with shareable links
- ✅ Offline-first architecture with localStorage
- ✅ Basic theme customization
Phase 1: Cloud Sync & Collaboration (PR #128)
- ✅ Sync conflict resolution —
src/utils/syncMerge.ts, remote-as-baseline merge with LWW on rubrics, wired into all three hydration sites (startup, reconnect, OTP sign-in) - ✅ Cambridge English framework — CEFR ↔ exam mapping (
src/data/cambridgeExams.ts), opt-in "B2 · FCE" badges, optional Cambridge Dictionary API vocabulary lookups - ✅ Theme bundles — 5 one-click presets (
src/data/themes.ts), tonal accent scale viacolor-mix(), 5 decorative export fonts for PDF/DOCX
Phase 2: Infrastructure Stabilization (PR #131 + wiki updates)
- ✅ 2.1 Multi-device e2e — second-browser-context Supabase fixture, propagation/LWW-race/network-partition specs (
e2e/specs/18-multi-device-sync.spec.ts) - ✅ 2.2 LWW extended to every editable collection (rubrics, grades, peer reviews, classes, students, grade scales, comment snippets/bank, self-assessments, speaking sessions, analysis results); add/delete-only collections (
attachments,exportTemplates,favoriteStandards) intentionally left on pending-queue protection only - ✅ 2.3 Wiki documentation pass — Cambridge + theming guides added to Features.md, conflict-resolution strategy documented in Supabase-Sync.md
- ✅ 3.1 Speaking session recordings — IndexedDB blob store, local-only audio, DB-gated video, optional cloud sync with cascade delete
- ✅ 3.2 Vocabulary profiling dashboard (
/vocabulary) — per-student/class CEFR distribution charts, open CEFR word lists, CSV export - ✅ 3.3 Peer review analytics (
/peer-analytics/:rubricId) — consistency scoring, leniency bias, inter-rater spread, comment heatmap - ✅ 3.4 Full testing environment (
/tests,/test/:code) — MC/short-answer/open questions, auto-scoring, class-average adjustment, live proctoring monitor
Phase 3.5: Hot Text Questions & Standalone Essays Workspace (PR #140)
- ✅ Hot-text question type —
src/utils/clozeParse.tsparses{{cloze}}and[[hot-text]]syntax; scoring intestCalc.ts - ✅ Standalone
/essaysworkspace (parallel to/tests) — prompt editor, rubric connector, per-student share links, submission-code import, reusable assignment templates (PR #143)
- ✅ 4.1 Expanded statistics — multi-class Compare view, trend overlay, rule-based insights, track/year filters
- ✅ 4.2 Activity dashboard (
/activity-dashboard) — rubric/test/essay × class grid, assign-from-view, submission count badges - ✅ 4.3 Admin hardening —
teacher/admin/observer roles + RLS, pg_cron data retention, student soft-delete archive (restore/anonymize), audit log with CSV export - ✅ 4.4 SIS roster sync (partial) — CSV upsert + optional roster-removal sync; native Magister API integration still reserved for community contribution
- ✅ 4.5 Self-hosting ops —
docs/SELF_HOSTING_OPS.md, HestiaCP/Virtualmin guides
- ✅ 5.1 Mobile grading — touch stepper alongside sliders, single-column ComparativeGrading reflow <768px, iPad CSS, mobile e2e
- ✅ 5.2 WCAG 2.1 AAA —
src/utils/contrastCheck.ts+ enforcement test, accessible modals with focus trap/restoration, keyboard drag-and-drop, i18n'd skip link - ✅ 5.3 Help & documentation — page tours (Joyride) on 12 pages total, contextual tooltips (
src/components/ui/HelpPopover.tsx) for score modifiers/LWW sync/proctoring flags - ✅ a11y test coverage — RubricBuilder/GradeStudent/ComparativeGrading added to the jest-axe page suite (PR #152, closing the Phase 5.2 follow-up)
- ✅ Route-shaped skeleton loading for lazy routes and async actions (PR #153)
Phase 6: Strategic Features (PR #157)
Scoped down from the original proposal before implementation — see "Deferred from Phase 6" below for what was cut and why.
- ✅ 6.1 Student Learning Paths — rule-based (no AI/LLM) rubric recommendations from CEFR-skill cohort gaps, consecutive-low-score intervention flagging,
/students/:id/learning-path(src/utils/learningPathAggregator.ts) - ✅ 6.2 Rubric Marketplace (school-scoped) — publish/browse/clone/upvote within a school via the existing
schools/school_memberstables,/marketplace(supabase/migrations/040_rubric_marketplace.sql,src/pages/MarketplacePage.tsx) - ✅ 6.3 Integration Ecosystem (CSV import only) — Clever CSV and OneRoster CSV roster-import auto-detection added to the existing CSV import modal; LTI 1.3 LMS integration deferred (see below)
- ✅ 6.4 Test Summary Export — per-question and per-skill/standard strong/weak breakdown, PDF/DOCX export (single + batch) from the test results page, feature parity with the rubric summary export (
src/utils/testSummaryAggregator.ts) - ✅ 6.5 Report Card Improvement — consolidated PDF/DOCX report card per student combining rubric grades, standards coverage, learning goals, CEFR overview, and test summary, with section toggles and single/batch export from the Export page (
src/utils/reportCardAggregator.ts)
Verification baseline (carried through every phase above): typecheck/lint clean, full unit suite green (1755+ tests), i18n parity across en/nl/fr/de/es, e2e suite green on chromium/firefox/webkit/mobile-chrome (pre-existing/environmental flakes tracked separately, not regressions).
Phase 7: Longitudinal & Historical Insight (PR #159)
- ✅ 7.1 Multi-year student history —
Student.pastClassMembershipsrecorded on every class change (manual move via Edit Student, and CSV sync-mode re-import transfers), with a confirmation summary before sync-mode CSV mutates anything; trail rendered on the student profile - ✅ 7.2 Rubric version diffing — "Compare" button per saved version opens a diff against the current rubric (criteria added/removed/changed, title/weight, level points/labels) (
src/utils/rubricVersionDiff.ts,RubricVersionDiffModal.tsx); version history/snapshot/restore already existed - ✅ 7.3 Standards coverage gap analysis — class-level aggregator cross-references every linked standard against what's been graded, split into Assessed/Not yet assessed, surfaced on the Activity Dashboard (
src/utils/standardsCoverageAggregator.ts,ClassCoverageGapPanel.tsx)
Phase 8: Collaboration & Department Workflow (PR #160)
- ✅ 8.1 Co-grading & moderation — second-marker grade reuses the peer-review data model (
StudentRubricwithisPeerReview: true);src/utils/coGradingModerationQueue.tsflags disputes above a configurable point threshold;/moderationlists disputes with a per-criterion delta and keep/accept resolution - ✅ 8.2 Department rubric/comment-bank libraries —
sharedWithSchoolflag on rubrics and comment-bank items, read-only to every teacher in the same school (041_school_sharing.sql, mirrors the Phase 6 marketplace's school_members join pattern) - ✅ 8.3 Grading task assignment — batch-assign a class's ungraded submissions for a rubric to a colleague from the Activity Dashboard (
GradingTasktype,042_grading_tasks.sql); completion is derived, not a stored flag - ✅ 8.4 Manual reordering — drag-and-drop reordering (
src/utils/displayOrder.ts,@hello-pangea/dnd) on RubricList, TestListPage, EssayListPage, the Activity Dashboard, and the class list on the Students page, per teacher. List containers use flexbox-wrap rather than CSS grid, since@hello-pangea/dndcomputes drag displacement from sibling bounding rects and doesn't support CSS grid track layout — grid caused incorrect cross-row drag animation and made it impossible to drop a card between two others in a different row. - ✅ 8.5 Cohort-based filtering — year/track cohort filter on the Rubrics, Tests, and Essays lists (
src/utils/cohortAggregator.ts,src/components/CohortFilter.tsx); a student counts as in-cohort via their current class or any past class frompastClassMemberships, so an item stays visible to a cohort across a class transfer. Manual reordering is disabled while a cohort filter is active. Not added to the Activity Dashboard, since its existing class-level year/track filter already serves the same need for that per-class matrix view.
Scoped to three of the four originally-proposed items; 9.4 (expanded essay exports) needs a new essay-rubric attachment data model and stayed out of scope — see "Carried forward from Phase 9" below.
- ✅ 9.1 RTL readiness — CSS logical-properties audit (
src/index.css): physicalleft/right/margin-left/padding-left/border-right/text-align: leftrules converted toinset-inline-*/margin-inline-*/padding-inline-*/border-inline-*/text-align: start, a no-op in the 5 existing LTR locales. Newsrc/utils/rtlLanguages.ts+ anAppContexteffect setsdir="rtl"on<html>when an RTL language is active — inert today (no RTL locale shipped yet) but ready for one. The mobile sidebar drawer'stransform: translateX()slide animation has no logical-property equivalent and was deliberately left sliding from the left edge only — tracked below as a known gap, not fixed in this pass. - ✅ 9.2 Installable offline PWA —
vite-plugin-pwa(Workbox) generates the manifest + service worker at build time;registerType: 'prompt'(notautoUpdate) so a new build never silently swaps JS under a mid-session sync — the user gets a native confirm prompt (src/pwa.ts) before reloading. Supabase requests (/rest/,/auth/,/realtime/,/storage/,/functions/+ version segment, matched by path so it covers both hosted and self-hosted Supabase) are explicitlyNetworkOnlyin the Workbox runtime-caching config — the service worker must never make a failed sync request look like it succeeded. Works under the existing relativebase: './'sub-path hosting config. Manifest icons:rubric-icon.svg(sizes: any) plus 192×192/512×512 PNG fallbacks (pwa-192.png/pwa-512.png, rasterized from the same SVG via a one-off Playwright screenshot script — no new dependency) for broader Chrome/Android installability. A dedicatedmaskablepurpose variant is still a follow-up, see Known Issues. - ✅ 9.3 Dyslexia-friendly reading mode — new Settings toggle (
dyslexiaFriendlyMode) sets--line-height: 1.8/--letter-spacing: 0.04emapp-wide via the same CSS-custom-property pattern as the existing theme bundles; no new component, just two new:rootvars insrc/index.csswith theirvar(--x, default)fallback as the single source of truth for the off state.
Carried forward from Phase 9:
- Essays written by students can be exported from HTML-code into Markdown, DOCX, and PDF.
- Essays can be downloaded as separate documents or combined into a batch download (per class, or by selection)
- Essays can be attached to the rubrics, and exported together. This can also include the grammar and vocabulary analysis.
Each phase below groups proposals under one theme so they can be scoped and shipped independently. None of these involve AI/LLM content generation — that remains explicitly out of scope for this project.
Two items from the original Phase 6 proposal were cut from scope before implementation, since neither could be built and verified in the implementation environment:
- LTI 1.3 LMS integration (Canvas, Blackboard, Moodle) — needs a live LMS sandbox to verify OAuth/launch flows; CSV-based roster import (Clever, OneRoster) shipped instead as a same-outcome, locally-testable substitute for the common "get students into the app" need.
-
Public/cross-tenant rubric marketplace — shipped as school-scoped only (reuses
schools/school_members); a public marketplace would need a moderation queue, abuse controls, and report/flag tooling that don't exist yet.
Both remain candidates for a future phase if there's demand.
Phase 9 (Accessibility & Reach Expansion) is now mostly complete — see the "✅ Completed Phases" section above. Its 9.4 item (expanded essay exports) remains unscoped and is listed there as carried forward.
Closes the loop on "data leaves the device" use cases beyond JSON backup.
- Per-SIS CSV export presets (beyond the generic CSV in Phase 0) for common Dutch/EU school administration systems, so a Statistics export drops straight into the receiving gradebook's expected columns
- Export essay/test assignment due dates as a downloadable
.icsfile — no calendar API integration required, keeps the offline-first model intact
- Optional, opt-in HTTP endpoint (Supabase Edge Function) exposing aggregated, anonymized class statistics for school-level reporting dashboards — gated behind the existing admin role, off by default
| Issue | Impact | Owner | Priority |
|---|---|---|---|
| Native Magister SIS API integration (bulk import + live sync) not built — CSV path covers production use today | School IT can't fully automate roster sync | Reserved for community contribution | Low |
Multi-device e2e specs (18-multi-device-sync.spec.ts) require a local Supabase stack to verify outside CI; no Docker daemon in some dev sandboxes |
Slower local iteration on sync code | — | Low |
Mobile sidebar drawer (.sidebar overlay, transform: translateX()) always slides in from the left edge, even under dir="rtl" — translateX has no CSS logical-property equivalent |
Cosmetic-only RTL gap on mobile nav; inert until an RTL locale ships | — | Low |
PWA manifest icons (SVG + 192/512 PNG) have no dedicated maskable purpose variant |
Android adaptive-icon masking may crop/pad the icon awkwardly on some launchers | — | Low |
-
Unit tests: Vitest (coverage thresholds: 50% lines/statements, 37% functions/branches — see
npm run coverage) -
E2E tests: Playwright, including a dedicated
mobile-chromeandsupabaseproject - i18n: Parity tests across EN, NL, FR, DE, ES locales — new locales must pass the same parity check and be checked against existing UI layout for overflow
-
Accessibility: axe-core in CI (WCAG 2.1 AA minimum; AAA contrast enforced via
contrastCheck.ts) - Performance: Offline-first validation; sync latency benchmarks for > 100 rubrics
Last updated: 24 June 2026 — Phase 9 mostly complete (9.1–9.3): RTL CSS logical-properties readiness, installable offline PWA (vite-plugin-pwa, prompt-based update, Supabase requests excluded from SW caching), and a dyslexia-friendly reading mode toggle. 9.4 (expanded essay exports) carried forward, unscoped. Phase 10 remains a themed proposal.