Skip to content

Roadmap

Wouter Meetsma edited this page Jun 20, 2026 · 49 revisions

Development Roadmap

🎯 Overview

RubricMaker is an offline-first rubric creation and grading tool for educators. This roadmap outlines completed features, current work in progress, and planned development phases.


✅ Completed Phases

Phase 0: MVP & Core Features (Launched)

  • ✅ 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

Status: Stable and feature-complete for core education workflows


Phase 1: Cloud Sync & Collaboration (Completed)

PR #128 — Final Three Roadmap Items

#15 — Sync Conflict Resolution ✅

Supabase-first implementation with intelligent merge strategy

  • src/utils/syncMerge.ts replaces wholesale spread operations at all three hydration sites
    • Startup sync
    • Network reconnect hydration
    • In-page OTP sync
  • Strategy: Remote as baseline (preserves deletions); locally queued edits protected from stale data; pending deletes not resurrected
  • Rubrics only: Last-write-wins (LWW) on updatedAt — other collections carry event timestamps (gradedAt, submittedAt) only
  • Offline-first preservation: Changes queue locally, sync on reconnection
  • Test coverage: 1263/1263 unit tests passing; e2e spec 17-offline-sync-merge.spec.ts (static validation + CI coverage)

#18 — Cambridge English Framework ✅

CEFR ↔ Cambridge Exam mapping + vocabulary API integration

  • Static CEFR-to-exam mapping (src/data/cambridgeExams.ts)
    • A2 Key → C2 Proficiency coverage
    • Function: cambridgeExamForLevel()
  • UI: Opt-in showCambridgeLabels setting renders "B2 · FCE" labels alongside CEFR badges
    • Visible on CEFR overview page
    • Shown on student profile pages
  • API Integration: Previously unused cambridgeApi.lookupWord() now wired to vocabulary editor
    • Admin-configured API key required
    • Enriches vocab items with CEFR level + definition
    • Offline-first: fully hidden without key, fills empty fields only
  • i18n: New cambridge.* namespace added to 5 locales with parity tests

#23 Phase 2 — Full Theme Bundles ✅

One-click theme presets + tonal accent scales + Google Fonts support

  • 5 Theme Bundles (src/data/themes.ts)
    • Academy, Nature, Midnight, Warm, Slate
    • Visual card picker in Settings → General
    • Atomic update: single updateSettings call with new colorPreset field
  • Tonal Scale Generation (src/utils/accentScale.ts)
    • --accent-50..900 scale via CSS color-mix() in oklab
    • Applied globally from AppContext
  • Export Fonts
    • DOCX: headings/body honor rubric format font via document styles
    • PDF: 5 new decorative Google Fonts (Playfair Display, Oswald, Bebas Neue, Special Elite, Courier Prime)
    • Format picker: live preview included
    • Export pathway: fonts injected at generation time
  • i18n: New themes.* namespace added to 5 locales with parity tests

Test Results: 123 new unit tests + 1 new Playwright spec; full suite: 1263/1263 passing, typecheck and lint clean


🚀 In Progress

Phase 2.1 — Multi-Device E2E Testing 🚧 (branch feat/multi-device-e2e)

  • Added secondSupabasePage fixture to e2e/fixtures/supabase.fixture.ts — a second browser context signed in as the SAME test user (shares testUserEmail with supabasePage), enabling true two-device tests
  • New e2e/specs/18-multi-device-sync.spec.ts: basic propagation (device A edits, device B reloads and sees it), simultaneous-edit/LWW race (the device that saves last wins the whole record, per syncMerge.ts), and network-partition resilience (offline edit on A flushes after reconnect without disturbing a concurrent online edit on B)
  • The old test.skip "Multi-device propagation" placeholder in 17-offline-sync-merge.spec.ts is removed
  • typecheck/lint/unit suite (1283/1283) clean
  • Outstanding: new specs are statically reviewed and register correctly with Playwright, but have not yet run against a real local Supabase stack — no Docker daemon was available in the dev sandbox. Run npm run db:start && npm run e2e:supabase once Docker (Desktop/colima/orbstack) is available and iterate as needed before merging.

Phase 2.2 — LWW for all editable collections ✅ (done, PR #129 merged)

  • StudentRubric.updatedAt added; set on every grade/peer-review save and self-assessment submit
  • updatedAt also added to Class, Student, GradeScale, CommentSnippet, CommentBankItem, SelfAssessment, SpeakingSession, DocumentAnalysisResult — set on every create/update via the AppContext reducer
  • syncMerge.ts now applies LWW to all 10 of these collections (previously rubrics-only)
  • attachments, exportTemplates, and favoriteStandards intentionally left out — add/delete-only, no update action, so pending-queue protection already covers their conflicts
  • 1283/1283 unit tests passing, typecheck and lint clean

Phase 2.3 — Wiki Documentation Cleanup ✅ (this session)

  • Added a "Cambridge English exam labels" guide to Features.md
  • Added a "Themes & Appearance" section to Features.md (theme bundles, tonal accent scale, export fonts)
  • Added a "Conflict resolution & sync strategy" section to Supabase-Sync.md documenting LWW, pending-queue protection, deletion handling, and known limits
  • The previously-noted "#38/#39/#40 marked Planned" cleanup item was checked against the current wiki — no page outside this Roadmap references those numbers as "Planned", so no further action was needed there

📊 Next Phases

Phase 2: Infrastructure Stabilization (Immediate Post-Merge)

2.1 Multi-Device E2E Testing 🚧 In Progress

  • Upgraded secondSupabasePage fixture (shares testUserEmail with supabasePage) ✅
  • Race condition scenarios: simultaneous edits across devices ✅
  • Network partition resilience validation ✅
  • Sync state consistency under network failures ✅
  • Owner: Followed spec-14 pattern from existing e2e suite
  • Priority: HIGH — foundational for multi-device feature stability
  • Remaining: run npm run db:start && npm run e2e:supabase against a real local Supabase stack (no Docker daemon was available when the spec was written) and merge feat/multi-device-e2e
  • Note: e2e/specs/17-offline-sync-merge.spec.ts now passes in CI (post PR #128). Two lessons it taught, relevant for the multi-device fixture work:
    1. Sync adapters return { success: false } instead of throwing — pushOne must check the SyncResult, or offline writes are silently dropped instead of queued.
    2. In the Supabase Playwright project, data seeded only into localStorage is wiped by post-reload hydration — seed matching rm_pending_sync upsert entries so the startup flush re-pushes it.

2.2 Extend Last-Write-Wins (LWW) to Remaining Collections ✅ Done

  • LWW now covers rubrics, grades (studentRubrics), peer reviews, classes, students, grade scales, comment snippets, comment bank items, self-assessments, speaking sessions, and analysis results — all via an updatedAt field set on every save and compared in syncMerge.ts
  • attachments, exportTemplates, favoriteStandards are add/delete-only (no edit action) — pending-queue protection already covers them, LWW would add no value
  • No DB migrations needed — all data columns are jsonb, so the new updatedAt field flows through automatically
  • Impact: Enables distributed grading sessions, multi-teacher rubric curation, and concurrent class/student roster edits

2.3 Wiki Documentation Cleanup ✅ Done

  • Verified items #38, #39, #40 are not referenced as "Planned" anywhere else in the wiki — no further status update needed
  • Added visual guides for Cambridge exam framework to Features.md
  • Added theme customization tutorial (theme bundles, accent scale, export fonts) to Features.md
  • Documented LWW sync strategy & conflict resolution limits in Supabase-Sync.md
  • Priority: MEDIUM — UX clarity for adopters

Phase 3: EFL Classroom Enhancements (Month 1–2) ✅ Done

Implemented across four merge waves (branch feature/phase-3-efl-enhancements): Wave 1 — shared infra + test data layer (2ceeeec); Wave 2 — recordings, vocab dashboard, peer analytics, testing UI (45249a7); Wave 3 — test results, class-average adjustment, live monitor (d9f71b9); Wave 4 — e2e test-environment lifecycle + docs (f7e2ae8).

3.1 Speaking Session Recordings ✅

  • Audio/video recording via useMediaRecorder + IndexedDB blob store (src/services/mediaStore.ts) — blobs never touch localStorage/quota
  • Wired into SpeakingSession.tsx; read-only playback in the student portfolio (StudentProfilePage.tsx)
  • Privacy-first: audio allowed local-only (persistent on-device warning banner); video gated behind a configured Supabase database (session-length video doesn't fit a device-only model)
  • Optional cloud sync via RecordingSync.ts (private recordings bucket, 50 MB cap, signed-URL cache); deleting a session cascades to local + cloud blobs
  • Migration 034_recordings_storage.sql

3.2 Vocabulary Profiling Dashboard ✅

  • New /vocabulary route (VocabularyDashboardPage.tsx) with per-student/class CEFR vocabulary distribution charts (VocabCefrDistributionChart.tsx, A1→C2 stacked bars)
  • src/utils/vocabProfileAggregator.ts aggregates DocumentAnalysisResult.levelCounts
  • Open CEFR-banded word lists (src/data/openCefrVocabulary.ts) merged into cefrVocabularyProfiler.ts — reduces reliance on the paid Cambridge API (kept as optional definitions-only enrichment)
  • CSV export of vocab lists filtered by CEFR band

3.3 Peer Review Analytics ✅

  • StudentRubric.gradedBy now populated on peer-review save — peer feedback is traceable ("Anonymous reviewer" only when absent on older data)
  • New /peer-analytics/:rubricId route (PeerReviewAnalyticsPage.tsx): consistency scoring (mean abs deviation vs. teacher baseline), per-reviewer leniency bias, inter-rater spread, comment-frequency heatmap (reusing CriterionHeatmap.tsx), round-over-round trends
  • src/utils/peerReviewAggregator.ts (+ tests covering missing-baseline / missing-gradedBy)

3.4 Testing environment ✅

  • Full Test/StudentTest/TestQuestion/ProctorEvent data model, synced via the standard LWW collection pattern (migrations 033034)
  • Teacher: /tests list + builder (TestBuilderPage.tsx) with MC/short-answer/open questions, CEFR/Standards linking, requireSEB toggle, share-link assignment modal (offline links embed the full test for no-DB use)
  • Student: /test/:code (StudentTestPage.tsx) — no-auth, draft autosave, optional timer, SEB advisory gate (SebGate.tsx, UA-based — documented as deterrent only, not enforcement)
  • Results: /tests/:testId/results/:studentTestId (TestResultsPage.tsx) — auto-scored MC/short-answer, manual grading for open questions, per-standard/CEFR rollups, grade-scale mapping
  • Class-average adjustment: ClassAverageAdjuster.tsx + testCalc.ts — reversible, auditable adjustment field, raw scores preserved
  • Live monitor: /tests/:testId/monitor and /essays/:assignmentId/monitor (LiveMonitorPage.tsx), Formative-style presence/response-grid/live-draft preview, built on the generic useLiveSessionTelemetry hook (tab-switch/copy-paste/battery/heartbeat) and proctorAggregator.ts; offline mode falls back to post-hoc event-log review
  • e2e: 19-test-environment.spec.ts — full offline lifecycle (build → assign → take → submit with proctoring telemetry → import → grade → adjust), green on chromium/firefox/webkit
  • Docs triple-update (DocsPage ROUTE_TREE, README routes table, LandingPage feature cards) completed for all of 3.1–3.4

Verification (WP5): supabase/bootstrap.sql regenerated from 34 migrations (no drift); typecheck clean; lint 0 errors (138 pre-existing any warnings); full unit suite 1475/1475 passing across 99 files; coverage 64.0% lines / 62.6% statements / 54.9% branches / 52.7% functions (all above the 50%/37% thresholds); i18n parity green for en/nl/fr/de/es. e2e: 243 passed, 1 skipped; the only failures are pre-existing and unrelated — 12-navigation.spec.ts on mobile-chrome (fails identically on main, tracked separately) and the supabase project specs (14–17, 19-test-environment.spec.ts firefox flake under full-suite load — passes in isolation), which require npm run db:start (no Docker daemon in this dev sandbox, same outstanding item as Phase 2.1).


Phase 4: Admin & School Operations (Month 2–3)

PR #144 — Admin hardening, audit log, CSV sync, student archive (merged 17 June 2026)

4.1 Expanded Statistics ✅

Implemented in Statistics page — new "Compare" view mode + track/year filters.

  • Class-vs-Class analysis — Compare tab: select up to 4 classes, same rubric → grouped avg bar chart + per-criterion gap chart; class names and counts shown per cell
  • Trend-Analysis — Multi-class trend overlay (LineChart, one line per class, by rubric creation date)
  • Tailored recommendations — Collapsible "Insights" panel with rule-based tips: struggling class (<55% avg), weak criterion (≥15 pp below class avg), largest inter-class divergence (≥20 pp gap)
  • Track + year filters — Dropdowns filter the class selector in both Rubric and Compare modes using Class.voTrack (VMBO-BB/KB/TL, HAVO, VWO) and Class.year (already typed; no migration needed)
  • New utility: src/utils/classComparisonAggregator.ts (compareClasses, buildMultiClassTrend, getInsights)
  • New component: src/components/Statistics/MultiClassTrendChart.tsx

4.2 Activity Dashboard ✅

New page at /activity-dashboard (sidebar: LayoutGrid icon).

  • Activity × Class grid — Horizontally scrollable table; rows = Rubrics / Tests / Essays (section headers); columns = classes (filtered by year + track); sticky activity-name column
  • Assign from view — Rubric cell: Link/Unlink toggles Class.rubricIds; Essay cell: "Assign All" bulk-creates EssayAssignment for unenrolled students using the existing group template; Test cell: "Open" navigates to test builder (tests are URL-based, no pre-assign model)
  • Count badges — Each cell shows submitted/total students; green when > 0
  • School year + track filter — Same filter dropdowns as Statistics; scopes the column set
  • New page: src/pages/ActivityDashboardPage.tsx
  • New utility: src/utils/activityDashboardAggregator.ts (getActivityRows, buildDashboardMatrix)

4.3 Admin Panel Hardening ✅

  • User Roles: userteacher rename; admin/observer roles in Supabase RLS (migration 036) ✅
  • Data Retention: pg_cron retention cleanup (admin 3yr / grade 1yr / export+auth 1mo) ✅
  • Student Anonymisation: Soft-delete archive with Restore + Anonymize actions; Admin → Archive tab ✅
  • Audit Log: audit_logs table (migration 037); AuditLogger wired to role changes, deletes, grade saves, rubric edits, exports, auth; Admin → Audit tab with category filter + CSV export ✅
  • Estimated effort: 3–4 weeks

4.4 Magister SIS Integration (partial)

  • ✅ CSV upsert + class sync: re-importing updates existing students by email; optional sync mode removes students not in the CSV (roster sync)
  • ⬜ Native Magister API integration: bulk import + dynamic ongoing sync
  • ⬜ Mock API testing for common scenarios
  • Note: CSV path is production-ready; Magister API requires a dedicated integration effort
  • Estimated effort: 2–3 weeks (remaining)

4.5 Self-Hosting Operations ✅

  • docs/SELF_HOSTING_OPS.md: backup/restore, upgrade path, resource sizing, pg_cron enablement, log rotation, troubleshooting
  • ✅ HestiaCP/Virtualmin deployment guides updated (PR #144)
  • ⬜ Monitoring: CPU/memory alerts, Supabase quota tracking
  • Estimated effort: 2 weeks

Phase 5: UI/UX Polish (Month 3–4) ✅ Done

Delivered as five parallel work-package PRs (#147#151). Two scoping decisions: "video tours" was implemented as the existing interactive Joyride walkthrough pattern (the app is offline-first with no video infrastructure); the AAA audit took the full-push interpretation, forcing every theme×accent to 7:1 where physically possible.

5.1 Mobile Grading Experience ✅ (PR #148)

  • Touch-friendly level input — a stepper (−/+ + numeric readout) is shown alongside the sub-item/point-range sliders under @media (hover: none), reusing the existing score handlers; the slider stays for pointer devices
  • Sticky score summary — already present (.grade-footer, fixed, safe-area insets)
  • ResponsiveComparativeGrading reflows to a single stacked column below 768px; iPad-portrait CSS overrides; enlarged range thumbs on touch
  • Mobile e2e04-grading + new 04b-grading-mobile spec added to the Playwright mobile-chrome project

5.2 WCAG 2.1 AAA Audit ✅ (PR #147, #151)

  • Color contrast — new src/utils/contrastCheck.ts (WCAG luminance/ratio, dependency-free) + an enforcement test that audits every theme bundle, accent preset, and CEFR badge colour against AAA thresholds; ~14 hex values nudged in themes.ts/cefrDescriptors.ts to clear 7:1 (button labels use the 4.5:1 large-text bar, link text uses the darker accent-700 at 7:1)
  • Focus managementGradeStudent/RubricBuilder modals routed through the shared Radix-backed Modal (focus trap + restoration to trigger + Escape-to-close)
  • Keyboard navigation@hello-pangea/dnd keyboard dragging in the rubric builder with translatable drag-handle labels; global :focus-visible outline and skip-to-content link (now i18n'd)
  • Follow-up: add RubricBuilder/GradeStudent/ComparativeGrading to the jest-axe page suite (deferred — heavy mocking for those large pages)

5.3 Help & Documentation ✅ (PR #149, #150)

  • Interactive tours — "Tour this page" Joyride walkthroughs added to 8 more pages (ComparativeGrading, Essays, Tests, Activity Dashboard, CEFR Overview, Speaking Session, Student Profile, Students), on top of the RubricBuilder/Export/Statistics/Grading tours from PR #146
  • TooltipsHelpPopover promoted to a shared src/components/ui/Tooltip.tsx; contextual help added for score modifiers, LWW sync behaviour (Admin → Database), and proctoring flags (Test Results / Live Monitor)
  • Multilingual — all new tour/help strings translated in EN, NL, FR, DE, ES (i18n parity green)

Phase 6: Strategic Features (Future Roadmap)

6.1 Student Learning Paths

  • Recommend next rubrics based on CEFR targets & past performance
  • Teacher dashboard: cohort analysis, outlier identification, intervention flags

6.2 Rubric Marketplace

  • Community template sharing (CC-BY-SA)
  • Voting & discoverability by subject/level
  • Minimal backend API for metadata

6.3 Integration Ecosystem

  • LMS: Canvas, Blackboard, Moodle (LTI 1.3)
  • Data Feeds: Clever CSV, OneRoster (for large districts)

📌 Known Issues & Technical Debt

Issue Impact Owner Priority

📋 Quick Reference: Recent PR Links

  • PR #128Implement roadmap items #18 (Cambridge), #23 Phase 2 (themes), #15 (sync)

    • Cambridge exam mapping + vocabulary API
    • Theme bundles + tonal accent scales + Google Fonts export
    • Sync conflict resolution (LWW for rubrics)
  • PR #144Phase 4 — admin hardening, audit log, CSV sync, student archive

    • Role rename userteacher; admin/observer RLS roles
    • Audit log table + AuditLogger service; Admin → Audit tab
    • CSV upsert + class sync; roster sync mode
    • Student soft-delete archive with restore & anonymize; Admin → Archive tab
    • Self-hosting ops guide (docs/SELF_HOSTING_OPS.md)
  • Phase 5 (UI/UX Polish) — five work-package PRs:

    • #147 — AAA contrast util + enforcement test, theme/CEFR colour fixes
    • #148 — touch-friendly mobile grading (stepper, reflow, iPad CSS, mobile e2e)
    • #149 — page tours for 8 more pages
    • #150 — contextual help tooltips (score modifier, LWW, proctoring)
    • #151 — accessible modals, focus restoration, translatable a11y labels

🎓 Development Notes

Testing Standards

  • Unit tests: Vitest (target >90% coverage)
  • E2E tests: Playwright (spec-14 pattern for async operations)
  • i18n: Parity tests across EN, NL, FR, DE, ES locales -> New Locales may be added, make sure to follow standards, and check if locale keys fit within the set UI/UX
  • Accessibility: axe-core in CI (WCAG 2.1 AA minimum)
  • Performance: Offline-first validation; sync latency benchmarks for > 100 rubrics

Last updated: 20 June 2026 (Phase 5 — UI/UX Polish ✅: 5.1 Mobile Grading ✅, 5.2 WCAG AAA ✅ (axe page-suite expansion deferred), 5.3 Help & Documentation ✅; delivered as PRs #147–#151)

Clone this wiki locally