# ClassicsLens

A daily Latin and Greek reading platform with morphological parsing, spaced-repetition vocabulary review, instructor tools, and AI-assisted learning aids.

**Live:** [classicslens.com](https://classicslens.com)

---

## What It Is

ClassicsLens delivers one short Latin or Greek passage per day drawn from a curated library of 9,755 passages (Caesar, Cicero, Homer, Thucydides, Vergil, Aristotle, and more). Every word is clickable: tap any token for its lemma, definition, morphology, and principal parts. Save words to a spaced-repetition deck. Analyze any word you encounter anywhere. Instructors can create classes, assign passages, upload their own texts, and track student completion.

---

## User Types

| Role | What they do |
|------|-------------|
| **Student (free)** | Read daily passages, 10 parses/day, SRS review, Anki export |
| **Student (in instructor class)** | All of the above, unlimited parses, see assigned readings |
| **Pro** | Unlimited parses, all reading features |
| **Instructor** | Create classes, invite students, assign passages, upload custom texts, completion dashboard |
| **Academic** | Multi-instructor team accounts, department-level access |
| **Admin** | Full user management, tier overrides, promo codes, instructor student limits |

---

## Features

### Today Tab
- One new passage per day per language (Latin, Greek, or alternating — configurable)
- Tap any word for a popup: headword, definition, morphology, principal parts, frequency rank, links to Logeion and Perseus
- One-tap "Save to review" adds the word to your SRS deck
- POS color-coding: verbs amber, nouns blue, adjectives green, pronouns violet (togglable)
- Collapsible passage context card — AI-generated historical notes and thematic tags
- Translation reveal — collapsible, hidden by default
- Comprehension questions where available
- Streak counter and day tracker
- Mark as done — advances your day counter and maintains your streak

### Review Tab
- SM-2 spaced repetition flashcard review
- Inflected surface form on front; lemma, definition, morphology, passage context on back
- Grade: **Again / Good / Easy**
- Due-count badge on nav icon updates every 60 seconds
- Post-session summary: breakdown by grade, next review schedule
- Anki-compatible TSV export (`/api/review/export`)

### Analyze Tab
- Parse any Latin or Greek word (accentless input supported)
- Three-tier lookup: local SQLite DB → Morpheus sidecar → in-memory inflection tables
- Full compound verb detection: identifies prefix + root with one-click root search
- Collapsible paradigm tables — full conjugation/declension for any lemma
- AI-generated usage gloss below each definition
- External links to Logeion and Perseus
- Save directly to SRS deck from parse results

### Assignments (Student)
- Assigned readings appear above the daily passage on the Today tab
- Click "Read" to load an assigned passage inline — full word-click experience
- "Mark as done" tracked per-assignment, visible to instructor
- Assignments from multiple classes shown together, sorted by due date

### Instructor Tools
- Create and manage classes
- Invite students by email — pending invites auto-activate when student signs up
- Students in your classes get Pro access automatically (unlimited parses, full SRS)
- Assign any corpus passage or your own custom text, with optional due date and instructions
- Upload custom Latin/Greek texts (up to 50,000 characters) — every word auto-parsed and clickable exactly like curated passages
- Per-class completion dashboard: who has read what, completion timestamps per student
- Preview any passage or custom text as a student via the standalone `/read/` route
- Student limit enforced per account (default 30 active students; adjustable by admin)

### Progress Tab
- Reading activity heatmap (52-week GitHub-style calendar)
- Vocabulary growth chart (words added to SRS over time)
- Grammar weak spots: ranked list of morphological patterns by average easiness score
- Accessible from the Today page ("View your progress" link)

### Settings
- Language mix: Latin only / Greek only / Alternating / Mostly Latin / Mostly Greek
- POS color-coding toggle
- Dark / light mode (syncs across devices when logged in)
- Data export (full JSON: `GET /api/user/export`)
- Account deletion

---

## Architecture

```
classicslens.com (Cloudflare DNS → VPS 93.188.166.21)
    │
nginx (n8n-nginx-1, SSL termination, letsencrypt)
    │
    └── lector-app  (Node/Express + React SPA, port 5001; container name kept for continuity)
            │
            ├── morphology.db       (SQLite, volume-mounted, ~500MB, read-only)
            │     ├── morphology    — 222K entries, 128K lemmas
            │     └── definitions   — 115K short defs (Logeion shortdefs)
            │
            ├── lector-postgres     (PostgreSQL 16, separate container; name kept for continuity)
            │     ├── users, user_settings, user_state
            │     ├── passages (9,755), passage_word_occurrences
            │     ├── review_items (SM-2 SRS)
            │     ├── paradigms (Latin ~1M rows, Greek ~1.6M rows)
            │     ├── lemma_glosses, passage_context (AI-generated)
            │     ├── instructor_classes, class_students
            │     ├── assigned_passages, custom_texts, custom_text_completions
            │     ├── teams, team_members (academic tier)
            │     ├── promo_codes, promo_redemptions
            │     ├── parse_quota_log, password_reset_tokens
            │     └── sessions (connect-pg-simple)
            │
            └── morpheus-api        (Python sidecar, port 5100, internal only)
                    └── Morpheus (Perseus Project, real-time morphological analysis)
```

No external API calls at runtime. All parsing and dictionary lookups are local.

---

## Tech Stack

| Layer | Technology |
|-------|-----------|
| Frontend | React 18, Tailwind CSS, shadcn/ui, Vite, wouter (hash routing) |
| Backend | Node.js, Express |
| ORM | Drizzle ORM |
| Database | PostgreSQL 16 |
| Auth | Passport.js — Google OAuth 2.0 + email/password (bcrypt + Resend for reset emails) |
| Morphology DB | SQLite via better-sqlite3 (read-only) |
| Parser | Morpheus (Perseus Project) via Python HTTP sidecar |
| Session store | connect-pg-simple (sessions in PostgreSQL) |
| Payments | Stripe (checkout, webhooks, customer portal) |
| Email | Resend |
| Deployment | Docker Compose |
| Tests | Playwright E2E (55 tests) |

---

## Parse Lookup — Three-Tier Strategy

1. **SQLite morphology DB** — exact Unicode match, then diacritics-stripped bare match. Fast (~1ms).
2. **Morpheus sidecar** — real-time analysis of any inflected form. Handles accentless Greek by generating all valid accent-position variants in Beta Code. Slower (~100–500ms).
3. **In-memory inflection tables** — hand-built paradigm tables for common forms. Fallback of last resort.

The `source` field in parse responses indicates which tier responded.

---

## Passage Library

9,755 passages, 100% with English translations.

| Author | Work | Passages |
|--------|------|----------|
| Livy | Ab Urbe Condita | 4,312 |
| Epictetus | Enchiridion / Discourses | 690 |
| Aristotle | Nicomachean Ethics, Politics | 483 |
| Xenophon | Various | 478 |
| Caesar | Gallic War, Civil War | 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 |
| + others | | |

---

## Paradigm Tables

Full conjugation/declension tables served from the `paradigms` PostgreSQL table.

| Language | Category | Rows |
|----------|----------|------|
| Latin | Verbs | ~834K |
| Latin | Nouns | ~202K |
| Latin | Adjectives, Pronouns | seeded |
| Greek | Verbs | ~1.43M |
| Greek | Nouns | ~202K |
| Greek | Adjectives, Pronouns | seeded |
| Greek | -μι verbs | εἰμί, φημί, δίδωμι, τίθημι, ἵστημι, ἵημι |

---

## Billing Tiers

| Feature | Free | Pro | Instructor | Academic |
|---------|------|-----|-----------|----------|
| Daily passages | ✅ | ✅ | ✅ | ✅ |
| Word popups | ✅ | ✅ | ✅ | ✅ |
| SRS review | ✅ | ✅ | ✅ | ✅ |
| Anki export | ✅ | ✅ | ✅ | ✅ |
| Parses/day | 10 | Unlimited | Unlimited | Unlimited |
| Create classes | ❌ | ❌ | ✅ | ✅ |
| Assign passages | ❌ | ❌ | ✅ | ✅ |
| Upload custom texts | ❌ | ❌ | ✅ | ✅ |
| Completion dashboard | ❌ | ❌ | ✅ | ✅ |
| Multi-instructor | ❌ | ❌ | ❌ | ✅ |
| **Price** | Free | $4.99/mo | $49.99/mo | $199–349/mo |

---

## Data Sources & Licenses

| Data | Source | License |
|------|--------|---------|
| Morphological forms | [Morpheus](https://github.com/perseids-tools/morpheus-perseids) (Perseus Project) | MPL-2.0 |
| Greek/Latin definitions | [helmadik/shortdefs](https://github.com/helmadik/shortdefs) (Logeion, U. Chicago) | CC BY-SA |
| LSJ / Lewis & Short | Perseus Digital Library | Public domain |
| Passage translations | Perseus, Gutenberg | Public domain |

App code: MIT.

---

## Docs

- [User Guide](docs/USER-GUIDE.md) — how to use ClassicsLens as a student, instructor, or admin
- [API Reference](docs/API.md) — parse endpoint and all REST routes
- [Deployment Guide](docs/DEPLOYMENT.md) — VPS setup, nginx, SSL, environment variables
- [Roadmap](ROADMAP.md) — feature status and future plans
