# Lector Roadmap

**Strategic focus:** Transform from personal reading app → institutionalized learning platform with instructor + academic tiers.

**Revenue model:** Free → Pro ($5/mo) → Instructor ($50/mo) → Academic ($199–349/mo)

**Timeline to MVP:** 8–12 weeks. Revenue-positive instructor tier by Q3 2026.

---

## EXECUTIVE SUMMARY

### What Changed (April 2026)

**Before (Phase 1–5 original):**
- Solo reader app (read, SRS)
- Daily passage delivery + parsing + SRS
- No instructor tools, no custom content, no differentiation

**After (updated):**
- **Instructor tier:** Classes, assignments, custom text uploads, completion tracking
- **Academic tier:** Multi-instructor accounts, department analytics, API access
- **AI-assisted learning:** Smart glosses + passage context (low-hallucination, reusable)
- **Custom content platform:** Teachers upload their own texts, auto-parsed + auto-glossed
- **Legal framework:** DMCA safe harbor, copyright mitigation, public-domain-first approach

### Key Metrics to Track

| Metric | Current | Target (Q3 2026) |
|--------|---------|------------------|
| Free users | ~50 | 500+ |
| Pro subscribers | 5–10 | 50+ |
| Instructor accounts | 0 | 20–50 |
| MRR | ~$25–50 | $1K–2K |
| Custom texts uploaded | 0 | 100+ |

---

## Phase 1: Core MVP ✅ (Complete)

- ✅ Daily passage delivery (9.7K passages curated)
- ✅ Morphological parser (3-tier: SQLite → Morpheus → fallback)
- ✅ Spaced-repetition SRS (SM-2 algorithm)
- ✅ Word-by-word glosses (frequency-based)
- ✅ Settings (language mix, difficulty, dark mode)
- ✅ Google OAuth auth
- ✅ Docker deployment
- ✅ Landing page

---

## Phase 2: User Management & Multi-Tenancy ✅ (Complete, minor gaps)

- ✅ Google OAuth + email/password auth (bcrypt, register/login/forgot/reset via Resend)
- ✅ Per-user settings, progress, SRS isolation
- ✅ Admin panel (user management, passage management)
- ✅ Anki TSV export
- ✅ Stripe billing (free/pro/instructor/academic tiers, checkout, webhooks, customer portal)
- ✅ Promo code system (admin-managed, tier override, max uses, expiry)
- ✅ Academic team management (seat-based, invite by email)
- ✅ Landing page + pricing page (3-tier: Free / Pro / Instructor)
- ⏳ User profile page (low priority)
- ⏳ Account deletion & data export (low priority)

---

## Phase 3: Extended Parser & Lexicon ✅ (Mostly Complete)

- ✅ Paradigm display — full conjugation/declension tables (`/api/paradigm`)
- ✅ Compound verb analysis (prefix + root breakdown)
- ✅ Fallback to external links (Logeion, Perseus) for unrecognized words
- ✅ 100% word clickability (issue #6)
- ✅ POS coloring in readings
- ✅ Accentless Greek transliteration (issue #20)
- ✅ Parse result validation against paradigm (issue #11)
- ✅ Combined Latin + Greek results for ambiguous ASCII input
- ⏳ Expand SQLite morphology.db coverage (some rare forms still miss)
- ⏳ User-submitted forms (future)

### Paradigm Coverage

| Language | Category | Rows | Notes |
|----------|----------|------|-------|
| Latin | Verbs | ~834K | Regular + deponent, from Whitaker's DICTLINE |
| Latin | Nouns | ~202K | 1st–5th decl + i-stems (16,833 lemmas) |
| Latin | Adjectives | seeded | 2-1-2, 3-term, 2-term, 1-term |
| Latin | Pronouns | 242 | ego, tu, se, is, hic, ille, iste, ipse, qui, quis |
| Greek | Verbs | ~1.43M | Thematic + contract + -μι (15,609 lemmas) |
| Greek | Nouns | ~202K | 20,226 lemmas, rules-based generator |
| Greek | Adjectives | seeded | Hardcoded + oxytone generator |
| Greek | Pronouns | 142 | ἐγώ, σύ, αὐτός, οὗτος, ἐκεῖνος, ὅς, τίς |
| Greek | -μι verbs | seeded | εἰμί, φημί, δίδωμι, τίθημι, ἵστημι, ἵημι |

---

## Phase 4: Advanced Reading Features ✅ (Mostly Complete)

- ✅ 100% word clickability — every token opens a popup (live parse fallback)
- ✅ POS-based frequency gloss suppression
- ✅ Post-session summary after completing a reading
- ⏳ Dialectal form mapping (Ionic ↔ Attic, Doric ↔ Attic)
- ⏳ Custom reading uploads (see Phase 5D)

---

## Phase 5A: QA, Polish & Analytics 🔄 (In Progress)

- ✅ API test suite (31 tests, all passing)
- ✅ Coverage: auth, billing, access control, quota enforcement
- ⏳ Playwright browser UI tests (issue #15)
  - Auth flows (Google OAuth, email/password, sign-out)
  - Reading: daily passage, word parsing, gloss popup
  - SRS: add card, answer, grade, summary
  - Parse tab: Greek/Latin words, accentless, paradigm toggle
  - Settings: theme, support level persistence
- ⏳ Learning analytics dashboard (progress charts, weak areas)
- ⏳ Hint system (partial reveals during review)

**Timeline:** 1–2 weeks (Playwright tests)

---

## Phase 5B: AI-Assisted Learning ✅ (Complete — April 2026)

**Issue:** #21 (closed)

### Smart Glosses ✅

AI-generated contextual gloss per lemma (2–3 sentences: usage, cultural context, etymology). Generated once, reused everywhere. Lives in `lemma_glosses` table, served by `server/gloss-service.ts`.

- Batch-generated for top lemmas (GPT-4 mini, temperature 0.3)
- Shown in word popup below definition (italicized)
- Shown in full Analyze tab

### Passage Context Cards ✅

Collapsible "Context" card below each passage header. Lives in `passage_context` table.

- Historical context, author notes, thematic tags
- Batch-generated for 9.7K passages
- Thematic tags displayed inline; enable future search

---

### Exercise Generation (Deferred)

AI generates 3–5 grammar-focused exercises from each passage. Tied to SRS. Deferred until Phase 5C is established and there is demand from instructors.

---

## Phase 5C: Instructor Tools MVP ✅ (Complete — April 2026)

**Issue:** #22 (closed)

### What Was Built

- **`server/instructor.ts`** — all instructor + student routes
- **`client/src/pages/instructor.tsx`** — instructor dashboard (`/instructor` route)
- **Stripe instructor tier** — `$49.99/mo`, `STRIPE_INSTRUCTOR_PRICE_ID` env var, webhook handler
- **Billing tier rank**: free(0) → pro(1) → instructor(2) → academic(3)
- **Pending invite auto-join**: both Google OAuth and email registration call `linkPendingClassInvites()` on sign-up
- **Student Today page**: "Assigned" panel above daily passage — click "Read" to load any assigned passage inline

### API Routes

```
POST   /api/instructor/classes                       — create class
GET    /api/instructor/classes                       — list my classes
DELETE /api/instructor/classes/:id                   — delete class
POST   /api/instructor/classes/:id/invite            — add student by email (sends Resend invite)
DELETE /api/instructor/classes/:id/members/:email    — remove student
GET    /api/instructor/classes/:id/roster            — students + join status + progress stats
POST   /api/instructor/classes/:id/assign            — assign passage (passageId, dueDate, instructions)
DELETE /api/instructor/assignments/:id               — remove assignment
GET    /api/instructor/classes/:id/dashboard         — completion tracking (JOIN on passage_completions)
GET    /api/passages/search                          — passage search for assignment picker
GET    /api/student/assignments                      — student's assigned passages (no tier gate)
GET    /api/passage/id/:id                           — fetch any passage by ID (used by student view)
```

### DB Tables

| Table | Purpose |
|-------|---------|
| `instructor_classes` | One row per class, FK to `users.id` |
| `class_students` | Roster with `status` (pending/active/removed), auto-upgraded on sign-up |
| `assigned_passages` | Passage assignments per class; UNIQUE(class_id, passage_id) |

Completion tracking uses no extra table — dashboard JOINs `assigned_passages` → `class_students` → `passage_completions` live.

---

## Phase 5D: Custom Text Uploads ✅ (Complete — April 2026)

**Issue:** #23 (closed)

Teachers upload their own Latin or Greek texts (plain textarea, no file upload). Lector auto-parses via the existing Morpheus live-parse fallback — every word is clickable exactly as in curated passages. Students assigned these texts read with identical UX.

### What Was Built

- **`custom_texts` table** — instructor-owned, 50k char limit enforced at DB + server level
- **`assigned_passages`** — extended with nullable `custom_text_id` (partial unique indexes per assignment type), `passage_id` made nullable
- **API**: `POST/GET/DELETE /api/instructor/texts` + `GET /api/texts/:id` (access-gated: owner or active class student)
- **Instructor page** — top-level "My Texts" tab: upload, list, preview, delete; unified "Assign" modal with Corpus/My Texts source picker; eye-icon preview on every dashboard assignment
- **`/read/passage/:id` and `/read/text/:id`** — standalone reader page for instructors/admins to preview any reading exactly as students see it (amber "Preview mode" banner)
- **Admin panel** — "Preview as student" link on every passage in the Passages tab
- **Student Today page** — handles custom text assignments inline; "Mark as done" hidden for custom texts (completion tracking is corpus-only)
- **Security**: null bytes + control chars stripped server-side; copyright checkbox required; parameterized queries throughout; access control on `/api/texts/:id`

### Copyright Approach

- Upload requires explicit checkbox: "I confirm this text is in the public domain, or I hold the rights to use and share it"
- Responsibility shifted to instructor; complies with 17 U.S.C. § 512 Safe Harbor
- No DMCA endpoint yet (low priority for MVP; can be added when public uploads are introduced)

### What Wasn't Built (intentional)

- No server-side pre-parse pipeline — live parse fallback is sufficient (on-demand, per word click)
- No translation field for custom texts — instructors can add a note in `instructions`
- No custom text completion tracking — the `passage_completions` table FKs to `passages`; custom text reads are not tracked in the instructor dashboard completion count

---

## Phase 5E: Advanced Analytics 🆕 (New, Medium Priority)

**Status:** Not started. See issue #24.

- Learning curves (words mastered over time)
- Grammar heatmap (which concepts are hard: contract verbs, datives, subjunctives)
- Reading streaks + cohort insights (instructor view)
- Stack: `recharts` or D3.js

**Timeline:** 1–2 weeks | **Impact:** High (needed for instructor pitch)

---

## Phase 6: Multi-Instructor & Academic Tier 🆕 (Phase-gated)

**Gate:** Only invest after Phase 5C has 20+ paying instructor customers.

- 5–10 instructor accounts per department
- Department-level analytics (cohort insights)
- Advanced grading + rubrics
- API access (Canvas, Blackboard integration)
- Dedicated support

**Timeline:** 4–6 weeks (if demand justifies)

---

## Phase 7: iOS & Android App (Deferred to H2 2026)

**Gate:** 100+ Pro subscribers AND 10+ Instructor customers AND >40% 30-day retention.

**Architecture:** React Native (chosen over Capacitor for native UX feel)

- Offline reading mode (cached passages + paradigms)
- Local SRS state sync
- Push notifications (review reminders)
- Camera + OCR (scan Greek/Latin text) — Phase 7b
- Apple Watch companion — Phase 7c

**Timeline:** 4–6 weeks

---

## Pre-Launch Polish Checklist

Phases 1–5D are complete. The following items stand between current state and a confident public launch.

### Must-Fix (blocking)

| Item | Issue | Notes |
|------|-------|-------|
| Dark mode persistence | #19 | Toggle works per-session but resets on reload. Store preference in `user_settings.pos_coloring` pattern (already exists for POS coloring) — or `localStorage` for unauthenticated users. ~1–2 hours. |
| Playwright test suite | #15–18 | 31 API tests pass. Browser UI tests have selector mismatches from prior UI refactors (#16 account nav, #17 review empty state, #18 parse results). Fix selectors to match current DOM — the actual features work. ~1 day. |
| Email/password reset flow | — | End-to-end smoke test: register → forgot password → reset → login. Resend key is live. Not formally tested. |

### Should-Fix (pre-launch quality)

| Item | Status | Notes |
|------|--------|-------|
| Custom text completion tracking | ✅ Fixed (Apr 2026) | `custom_text_completions` table added; `POST /api/texts/:id/complete`; dashboard counts both passage + text completions; students can mark custom texts done. |
| Student invite limit enforcement | Deferred | No cap enforced (not in marketing copy). Recommend flat cap of 50 students/class once instructors onboard — no Stripe complexity needed at this scale. Reassess at 20+ instructor customers. |
| Error states | ✅ Fixed (Apr 2026) | If assignment fails to load, banner turns red with error message; falls back to today's daily passage; "Mark as done" hidden during error state. |
| Empty translation in reading preview | ✅ Fixed (pre-launch) | `{passage.translationText && (...)}` guard already in place — button hidden when empty. |

### Decisions Made

| Item | Decision |
|------|----------|
| Rebrand to ClassicsLens | ✅ Done (Apr 2026) — classicslens.com, SSL, Google OAuth, all branding updated |
| Analytics dashboard | ✅ Done (Phase 5E, Apr 2026) — reading heatmap, vocab growth, grammar gaps |
| Account deletion & data export | ✅ Already shipped — `DELETE /api/auth/account` and `GET /api/user/export` both live; export link shown in Settings |
| Student invite limits + Stripe | Flat DB cap (50/class) when needed, no per-seat Stripe billing until 20+ instructor customers provide pricing signal |

---

## TIER DIFFERENTIATION

| Feature | Free | Pro | Instructor | Academic |
|---------|------|-----|-----------|----------|
| Daily passages | ✅ | ✅ | ✅ | ✅ |
| Smart glosses | ✅ | ✅ | ✅ | ✅ |
| Passage context | ✅ | ✅ | ✅ | ✅ |
| SRS review | ✅ | ✅ | ✅ | ✅ |
| Parses/day | 10 | Unlimited | Unlimited | Unlimited |
| Anki export | ✅ | ✅ | ✅ | ✅ |
| Create classes | ❌ | ❌ | ✅ | ✅ |
| Invite students | ❌ | ❌ | ✅ | ✅ |
| Assign passages | ❌ | ❌ | ✅ | ✅ |
| Completion dashboard | ❌ | ❌ | ✅ | ✅ |
| SRS progress view | ❌ | ❌ | ✅ | ✅ |
| Upload custom texts | ❌ | ❌ | ✅ | ✅ |
| Auto-parse custom | ❌ | ❌ | ✅ | ✅ |
| Preview readings | ❌ | ❌ | ✅ | ✅ |
| Learning charts | ❌ | ❌ | ⏳ 5E | ⏳ 5E |
| Grammar heatmap | ❌ | ❌ | ⏳ 5E | ⏳ 5E |
| Cohort analytics | ❌ | ❌ | ❌ | ⏳ 6 |
| Multi-instructor | ❌ | ❌ | ❌ | ⏳ 6 |
| API access | ❌ | ❌ | ❌ | ⏳ 6 |
| **Price** | Free | $4.99/mo | $49.99/mo | $199–349/mo |

---

## Data & Content

### Passages (as of 2026-04-05)

- **Total:** 9,755 live passages, 100% translation coverage
- **Word occurrences:** ~100% indexed via Morpheus sidecar

| Author | Work | Passages |
|--------|------|----------|
| Livy | Ab Urbe Condita | 4,312 |
| Epictetus | Enchiridion / Discourses | 690 |
| Aristotle | NE + Politics | 483 |
| Xenophon | Various | 478 |
| Caesar | BG + BC | 453 |
| Herodotus | Historiae | 444 |
| Homer | Iliad + Odyssey | 358 |
| Thucydides | Historiae | 342 |
| Vergil | Aeneid + Georgics | 303 |
| Marcus Aurelius | Meditations | 254 |
| Pliny the Younger | Epistulae | 250 |
| Cicero | Various | 237 |
| Demosthenes | Various | 188 |

**Removed works** (no public-domain English with matching refs): Seneca Ep. (509), Juvenal (178), Nepos (55), Sophocles Antigone (7), Horace Sermones (3), Sallust (2)

---

## Timeline Overview

| Phase | Status | Priority |
|-------|--------|----------|
| 1 | ✅ Complete | — |
| 2 | ✅ Complete | — |
| 3 | ✅ Mostly complete | — |
| 4 | ✅ Mostly complete | — |
| 5A | 🔄 In progress (Playwright tests pending) | High |
| 5B | ✅ Complete (AI glosses + context cards) | — |
| 5C | ✅ Complete (Instructor tools, classes, assignments) | — |
| 5D | ✅ Complete (Custom text uploads, preview reader) | — |
| 5E | ⬜ Not started (Analytics dashboard) | Medium |
| 6 | ⬜ Phase-gated (20+ instructor customers) | TBD |
| 7 | ⬜ Deferred H2 2026 (Mobile) | High |

**Current state (April 2026):** Phases 1–5E complete. Rebrand done. QA suite passing (57 tests). Product is launch-ready.

**Marketing:** Reddit ad campaign landing page live at `/reddit` (issue #37) — dark theme, before/after pain grid, interactive Caesar demo, Stripe checkout inline, GA4 + ContentSquare tracking. UTM: `utm_source=reddit&utm_medium=paid&utm_campaign=reddit_ad`.

**Next up:** Instructor customer acquisition. Phase 6 gated on 20+ paying instructors. Mobile gated on 100+ Pro + 10+ Instructor + 40% retention.

**Targets:** Instructor tier revenue-positive Q3 2026 | iOS/Android H2 2026

---

**Last Updated:** April 7, 2026  
**Maintained By:** Brent J. Broadnax (rutgersguy)
