-
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 outlines completed features, current work in progress, and planned development phases.
- ✅ 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
PR #128 — Final Three Roadmap Items
Supabase-first implementation with intelligent merge strategy
-
src/utils/syncMerge.tsreplaces 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)
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
showCambridgeLabelssetting 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
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
updateSettingscall with newcolorPresetfield
-
Tonal Scale Generation (
src/utils/accentScale.ts)-
--accent-50..900scale via CSScolor-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
- Added
secondSupabasePagefixture toe2e/fixtures/supabase.fixture.ts— a second browser context signed in as the SAME test user (sharestestUserEmailwithsupabasePage), 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, persyncMerge.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 in17-offline-sync-merge.spec.tsis 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:supabaseonce Docker (Desktop/colima/orbstack) is available and iterate as needed before merging.
-
StudentRubric.updatedAtadded; set on every grade/peer-review save and self-assessment submit -
updatedAtalso added toClass,Student,GradeScale,CommentSnippet,CommentBankItem,SelfAssessment,SpeakingSession,DocumentAnalysisResult— set on every create/update via theAppContextreducer -
syncMerge.tsnow applies LWW to all 10 of these collections (previously rubrics-only) -
attachments,exportTemplates, andfavoriteStandardsintentionally 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
- 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.mddocumenting 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
- Upgraded
secondSupabasePagefixture (sharestestUserEmailwithsupabasePage) ✅ - 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:supabaseagainst a real local Supabase stack (no Docker daemon was available when the spec was written) and mergefeat/multi-device-e2e -
Note:
e2e/specs/17-offline-sync-merge.spec.tsnow passes in CI (post PR #128). Two lessons it taught, relevant for the multi-device fixture work:- Sync adapters return
{ success: false }instead of throwing —pushOnemust check theSyncResult, or offline writes are silently dropped instead of queued. - In the Supabase Playwright project, data seeded only into
localStorageis wiped by post-reload hydration — seed matchingrm_pending_syncupsert entries so the startup flush re-pushes it.
- Sync adapters return
- 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 anupdatedAtfield set on every save and compared insyncMerge.ts -
attachments,exportTemplates,favoriteStandardsare add/delete-only (no edit action) — pending-queue protection already covers them, LWW would add no value - No DB migrations needed — all
datacolumns arejsonb, so the newupdatedAtfield flows through automatically - Impact: Enables distributed grading sessions, multi-teacher rubric curation, and concurrent class/student roster edits
- 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
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).
- Audio/video recording via
useMediaRecorder+ IndexedDB blob store (src/services/mediaStore.ts) — blobs never touchlocalStorage/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(privaterecordingsbucket, 50 MB cap, signed-URL cache); deleting a session cascades to local + cloud blobs - Migration
034_recordings_storage.sql
- New
/vocabularyroute (VocabularyDashboardPage.tsx) with per-student/class CEFR vocabulary distribution charts (VocabCefrDistributionChart.tsx, A1→C2 stacked bars) -
src/utils/vocabProfileAggregator.tsaggregatesDocumentAnalysisResult.levelCounts - Open CEFR-banded word lists (
src/data/openCefrVocabulary.ts) merged intocefrVocabularyProfiler.ts— reduces reliance on the paid Cambridge API (kept as optional definitions-only enrichment) - CSV export of vocab lists filtered by CEFR band
-
StudentRubric.gradedBynow populated on peer-review save — peer feedback is traceable ("Anonymous reviewer" only when absent on older data) - New
/peer-analytics/:rubricIdroute (PeerReviewAnalyticsPage.tsx): consistency scoring (mean abs deviation vs. teacher baseline), per-reviewer leniency bias, inter-rater spread, comment-frequency heatmap (reusingCriterionHeatmap.tsx), round-over-round trends -
src/utils/peerReviewAggregator.ts(+ tests covering missing-baseline / missing-gradedBy)
- Full
Test/StudentTest/TestQuestion/ProctorEventdata model, synced via the standard LWW collection pattern (migrations033–034) - Teacher:
/testslist + builder (TestBuilderPage.tsx) with MC/short-answer/open questions, CEFR/Standards linking,requireSEBtoggle, 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, auditableadjustmentfield, raw scores preserved - Live monitor:
/tests/:testId/monitorand/essays/:assignmentId/monitor(LiveMonitorPage.tsx), Formative-style presence/response-grid/live-draft preview, built on the genericuseLiveSessionTelemetryhook (tab-switch/copy-paste/battery/heartbeat) andproctorAggregator.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).
- User Roles: Expand teacher-only to admin/observer roles
- Data Retention: Auto-purge old grades, GDPR deletion workflows
- Student Anonymisation: Support for external/standardized assessments
- Audit Log: Track all edits, exports, role changes
- Estimated effort: 3–4 weeks
- Bulk import students + classes from Dutch VO schools
- Ongoing sync: add/retire students dynamically
- Mock API testing for common scenarios
- Note: Docstring present in codebase, validation needed
- Estimated effort: 2–3 weeks
- Validate & update HestiaCP & Virtualmin guides against latest Docker compose
- Backup/restore automation with cross-version migration testing
- Monitoring: CPU/memory alerts, Supabase quota tracking
- Estimated effort: 2 weeks
- Touch-friendly rubric level input (replace sliders for mobile)
- Sticky score summary during grading
- Responsive tests: iOS/Android, iPad portrait mode
- Estimated effort: 2–3 weeks
- Current: AA compliant (axe-core in CI)
-
Stretch Goals:
- Focus management for complex workflows
- Color contrast audits on new theme bundles
- Keyboard navigation for rubric builder
- Tool: axe DevTools + manual screen reader testing
- Estimated effort: 2–3 weeks
- In-app: Video tours (create rubric, grade, export)
- Tooltips: Complex features (score modifiers, LWW sync behavior)
- Multilingual: EN, NL, FR, DE, ES
- Estimated effort: 2–3 weeks
- Recommend next rubrics based on CEFR targets & past performance
- Teacher dashboard: cohort analysis, outlier identification, intervention flags
- Community template sharing (CC-BY-SA)
- Voting & discoverability by subject/level
- Minimal backend API for metadata
- LMS: Canvas, Blackboard, Moodle (LTI 1.3)
- Data Feeds: Clever CSV, OneRoster (for large districts)
| Issue | Impact | Owner | Priority |
|---|---|---|---|
| e2e offline sync not tested locally (Docker unavailable at PR #128 write time) | Offline sync race conditions untested in CI | Dev | HIGH — confirm e2e passes post-merge |
Multi-device e2e specs (18-multi-device-sync.spec.ts) not yet run against a real Supabase stack — no Docker daemon in dev sandbox |
Multi-device propagation/LWW/partition scenarios statically reviewed but unverified end-to-end | QA |
HIGH — run npm run db:start && npm run e2e:supabase and merge feat/multi-device-e2e
|
-
PR #128 — Implement 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)
- Before merging PR #128: Confirm e2e suite passes in CI with Docker stack
-
Branch
feat/multi-device-e2e: runnpm run db:start && npm run e2e:supabaseagainst a real local Supabase stack and merge once green - Month 1 Priority: Stabilize sync infrastructure (Phase 2) before new EFL features
- Tech Stack: TypeScript + React; Supabase for optional cloud sync; Playwright for e2e
- 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
- Accessibility: axe-core in CI (WCAG 2.1 AA minimum)
- Performance: Offline-first validation; sync latency benchmarks for > 100 rubrics
Last updated: 13 June 2026 (Phase 3 — EFL Classroom Enhancements — complete)