779 lines
38 KiB
Markdown
779 lines
38 KiB
Markdown
# Prabhupāda Says — Project Context
|
||
|
||
## What this project is
|
||
|
||
A Next.js app presenting the books, letters, essays, lectures, and teachings of His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda in a modern, accessible, and searchable format with proper Unicode Sanskrit (IAST + Devanagari).
|
||
|
||
Content is sourced from the pre-1980s Vedabase, extracted and indexed into MongoDB, and served via a Next.js frontend. Extraction scripts and raw data live separately in the `extractor/` directory.
|
||
|
||
---
|
||
|
||
## Tech Stack
|
||
|
||
- **Next.js 16** with Turbopack, React 19, TypeScript
|
||
- **Tailwind CSS v4** with `@tailwindcss/postcss`
|
||
- **shadcn/ui** (base-nova style, lucide icons) — components: Button, Card, Badge, Tooltip, Input, Drawer
|
||
- **next-themes** for dark/light/system mode
|
||
- **vaul** for mobile drawer navigation
|
||
- **Go BFF API** — all data fetched via `lib/bff.ts` HTTP client calling the Go BFF server (no direct database access)
|
||
- **framer-motion** for audio player animations (spring enter/exit, minimize/expand transitions, audio wave bars)
|
||
- **Python 3** with BeautifulSoup4 + `indic-transliteration` for HTML extraction scripts
|
||
|
||
---
|
||
|
||
## Project Structure
|
||
|
||
The project is split into two directories:
|
||
|
||
- **`knowledgebase/`** — Production Next.js app (~3.5MB excluding node_modules)
|
||
- **`extractor/`** — Extraction scripts, seed scripts, raw data, legacy fonts (~750MB)
|
||
|
||
```
|
||
knowledgebase/
|
||
├── app/
|
||
│ ├── page.tsx → Landing page (Books, Essays, Magazines, Letters, Transcriptions, etc.)
|
||
│ ├── layout.tsx → ThemeProvider + TooltipProvider + TextSelectionToolbar + TextHighlighter
|
||
│ ├── globals.css → Vintage color palette + reading settings CSS
|
||
│ ├── about/page.tsx → About page (mission, data source, roadmap)
|
||
│ ├── books/ → 37 book routes (verse-based + prose)
|
||
│ │ ├── page.tsx → Books index (searchable grid, diacritic-aware search)
|
||
│ │ ├── chapter-viewer.tsx → Shared client component for verse-based books
|
||
│ │ ├── bg/, sb/, cc/, sb1962/, iso/, noi/, bs/, mm/, nbs/ → Verse-based books
|
||
│ │ ├── kb/, nod/, tlc/, ej/, ek/, mg/, bbd/, owk/, rv/ → Prose books
|
||
│ │ ├── poy/, pqpa/, ttp/, ochkm/, hkh/, lcl/, lob/ → More prose books
|
||
│ │ ├── ssr/, ds/ → Hierarchical prose books (sub-chapters)
|
||
│ │ └── sva/, gg/, mog/, cbhc/, bk/, pk/, va/ → Other books
|
||
│ ├── magazines/ → Magazine browsing (BTG 1944-1960, BTG 1966-1973)
|
||
│ ├── letters/
|
||
│ │ ├── page.tsx → Letters index with 3-way nav (year/recipient/location)
|
||
│ │ ├── filter-year-browser.tsx → Shared component: sidebar years + month-grouped content
|
||
│ │ ├── [slug]/page.tsx → Individual letter reader
|
||
│ │ ├── year/[year]/
|
||
│ │ │ ├── page.tsx → Letters by year
|
||
│ │ │ └── year-month-browser.tsx → Sidebar months + letter list
|
||
│ │ ├── recipient/[name]/page.tsx → Letters by recipient (year sidebar + month groups)
|
||
│ │ └── location/[name]/page.tsx → Letters by location (year sidebar + month groups)
|
||
│ ├── essays/ → 23 essays across 6 groups
|
||
│ ├── journals/ → Jaladuta Diary, The Beginning
|
||
│ ├── other-documents/ → 12 miscellaneous documents
|
||
│ ├── glossary/
|
||
│ │ ├── page.tsx → Redirects to /glossary/a
|
||
│ │ ├── glossary-client.tsx → Client component (sidebar terms, single entry view, prev/next nav)
|
||
│ │ └── [letter]/page.tsx → Dynamic route per letter (A-Z)
|
||
│ ├── disciples/ → 4,747 initiated disciples directory
|
||
│ │ ├── page.tsx → Disciples browser (letter nav, suffix filter, search, sort, pagination)
|
||
│ │ └── disciples-browser.tsx → Client component
|
||
│ ├── transcriptions/ → 3,787 transcriptions (lectures, conversations, philosophy, dictations)
|
||
│ │ ├── page.tsx → Browse by year / place / type (3 views)
|
||
│ │ ├── year/[year]/page.tsx → Year listing, grouped by month
|
||
│ │ ├── place/[place]/page.tsx → Place listing
|
||
│ │ ├── type/[type]/page.tsx → Type listing (lecture/conversation), year sidebar
|
||
│ │ └── [slug]/page.tsx → Individual transcription reading page
|
||
│ └── api/
|
||
│ ├── og/route.tsx → Dynamic OG image generator (Noto Sans, Prabhupāda image)
|
||
│ ├── books/ → Book/verse API routes
|
||
│ └── glossary/route.ts → Glossary API
|
||
├── components/
|
||
│ ├── ui/ → shadcn components (button, card, badge, tooltip, input, drawer)
|
||
│ ├── selection-toolbar/ → Text selection toolbar sub-components
|
||
│ │ ├── shared.tsx → KautilyaIcon, types, hooks (useMediaQuery, useCopyFeedback)
|
||
│ │ ├── floating-toolbar.tsx → Desktop floating pill / mobile bottom bar
|
||
│ │ ├── share-modal.tsx → Share modal (desktop) / drawer (mobile)
|
||
│ │ ├── collections-drawer.tsx → Save to collection drawer
|
||
│ │ └── more-popover.tsx → More options popover (desktop) / drawer (mobile)
|
||
│ ├── text-selection-toolbar.tsx → Main orchestrator (event listeners, state management)
|
||
│ ├── text-highlighter.tsx → Processes incoming ?hl= URLs (scroll + highlight)
|
||
│ ├── page-header.tsx → Shared header with ReadingSettings (max-w-5xl)
|
||
│ ├── reading-settings.tsx → Theme/font/size/justify accessibility panel
|
||
│ ├── mobile-nav.tsx → Left-slide drawer for mobile sidebar navigation
|
||
│ ├── site-footer.tsx → Global footer (About + Home links)
|
||
│ ├── audio-player/ → Site-wide floating audio player
|
||
│ │ ├── audio-context.tsx → React context + provider, manages <audio> element
|
||
│ │ ├── floating-player.tsx → Floating player UI (desktop bar / mobile pill)
|
||
│ │ ├── audio-wave.tsx → Reusable animated audio wave bars
|
||
│ │ └── index.ts → Barrel exports
|
||
│ ├── logo.tsx → Theme-aware logo component
|
||
│ └── theme-provider.tsx → next-themes wrapper
|
||
├── lib/
|
||
│ ├── bff.ts → BFF API client (typed fetch wrapper: bff<T>(), bffList<T>(), bffOrThrow<T>())
|
||
│ ├── api.ts → Core data access (books, verses, prose chapters, glossary) — calls BFF API
|
||
│ ├── books.ts → Generic book data layer (replaces 29 individual book files)
|
||
│ ├── constants.ts → Shared constants (BOOK_NAMES, CC_LILAS)
|
||
│ ├── og.ts → OG image metadata builders (ogForVerse, ogForLetter, etc.)
|
||
│ ├── text-highlight.ts → Text fragment encode/decode, highlight matching
|
||
│ ├── source-reference.ts → Source reference from URL (for copy attribution)
|
||
│ ├── disciples.ts → Disciples data access — calls BFF API
|
||
│ ├── letters.ts → Letters data access (by year, recipient, location) — calls BFF API
|
||
│ ├── transcriptions.ts → Transcriptions data access — calls BFF API
|
||
│ ├── utils.ts → cn() helper
|
||
│ ├── [book].ts → Per-book data access layers (nod, tlc, iso, noi, ej, ek, etc.) — calls BFF API
|
||
│ ├── other-documents.ts → Other Documents data access — calls BFF API
|
||
│ ├── journals.ts → Journals data access — calls BFF API
|
||
│ └── magazines.ts → Magazines data access — calls BFF API
|
||
└── public/
|
||
├── fonts/Noto_Sans/static/ → NotoSans-Regular.ttf + NotoSans-Bold.ttf (OG images)
|
||
├── images/ → OG card image (Prabhupāda)
|
||
├── logo_dark.png → Logo for light theme
|
||
├── logo_light.png → Logo for dark theme
|
||
└── robots.txt
|
||
|
||
extractor/ → Extraction & seeding tools (not deployed)
|
||
├── scripts/ → Python extractors + TypeScript seed scripts
|
||
├── jsons/ → Extracted JSON data (books, letters, essays, etc.)
|
||
├── html/ → RTF→HTML converted files
|
||
├── rtfs/ → Original RTF source files
|
||
├── fonts/ → Legacy custom fonts (ScaGoudy, Indevr, Balaram, etc.)
|
||
├── app-rtfs/ → RTF viewer pages (archived)
|
||
└── .venv/ → Python virtual environment
|
||
```
|
||
|
||
---
|
||
|
||
## Data Architecture
|
||
|
||
The knowledgebase **never connects to MongoDB directly**. All data is served by the **Go BFF API** server.
|
||
|
||
### BFF Server
|
||
|
||
- **URL**: Configured via `BFF_URL` environment variable (default: `http://localhost:8080`)
|
||
- The BFF reads from MongoDB — the knowledgebase frontend has no database driver or connection string
|
||
- All API endpoints live under `/api/v1/...` on the BFF server
|
||
|
||
### BFF Client (`lib/bff.ts`)
|
||
|
||
The typed fetch wrapper provides three helpers:
|
||
|
||
- **`bff<T>(path, options?)`** — Fetch JSON from the BFF. Returns `null` on 404, throws `BffError` on other failures.
|
||
- **`bffList<T>(path, options?)`** — Fetch a list. Returns `[]` on 404 (instead of null).
|
||
- **`bffOrThrow<T>(path, options?)`** — Fetch JSON, throwing on 404. Use when a missing resource should be an error.
|
||
|
||
Options include `params` (query parameters), `revalidate` (Next.js ISR seconds, default 60), and `tags` (cache tags).
|
||
|
||
### Response Envelope
|
||
|
||
BFF responses use a `{ success: true, data: ... }` envelope. The `bff()` client auto-unwraps this — callers receive the inner `data` value directly.
|
||
|
||
### Case Mapping
|
||
|
||
The BFF uses **snake_case** JSON field names (Go convention). Each frontend data layer file (`lib/letters.ts`, `lib/transcriptions.ts`, `lib/books.ts`, etc.) maps BFF responses to **camelCase** TypeScript types used by React components.
|
||
|
||
### Data Layer Files
|
||
|
||
Individual `lib/*.ts` files are thin wrappers that:
|
||
1. Call a BFF endpoint via `bff()` / `bffList()` / `bffOrThrow()`
|
||
2. Map the snake_case response to camelCase frontend types
|
||
3. Export typed functions consumed by Next.js server components
|
||
|
||
Key data layers and their BFF endpoint prefixes:
|
||
- `lib/api.ts` → `/api/v1/books/*`, `/api/v1/glossary/*` — Books, verses, prose chapters, glossary
|
||
- `lib/books.ts` → `/api/v1/books/{code}/*` — Generic book data layer (replaces 29 individual per-book files)
|
||
- `lib/letters.ts` → `/api/v1/letters/*` — Letters (by year, recipient, location)
|
||
- `lib/transcriptions.ts` → `/api/v1/transcriptions/*` — Transcriptions (by year, place, type)
|
||
- `lib/disciples.ts` → `/api/v1/disciples/*` — Disciples directory
|
||
- `lib/other-documents.ts` → `/api/v1/other-documents/*` — Other Documents
|
||
- `lib/journals.ts` → `/api/v1/journals/*` — Journals
|
||
- `lib/magazines.ts` → `/api/v1/magazines/*` — Magazines
|
||
|
||
---
|
||
|
||
## Disciples Collection
|
||
|
||
Scraped from `https://sp.krishna.com/disciples_a` through `disciples_y` (21 letter pages; F, Q, W, X, Z have no pages).
|
||
|
||
- **Total**: 4,747 disciples
|
||
- **3,296** Dasa, **1,450** Devi Dasi, **1** Svāmī
|
||
- **4,554** have initiation dates (month + year); **193** are missing dates
|
||
- **4,703** have initiation places; **44** are missing places
|
||
- Initiation dates are set to the **1st day of the month** (exact day unknown from this source)
|
||
- On the UI, exact dates should only be shown when `isVerified` is `true`
|
||
- `karmiName`, `avatar`, `about`, and `tags` are empty by default — intended for manual curation
|
||
|
||
Data files: `data/disciples_a_b_c_d_e.json`, `data/disciples_g_to_l.json`, `data/disciples_m_n_o_p.json`, `data/disciples_r_s_t.json`, `data/disciples_u_v_y.json`
|
||
|
||
Seed script: `npx tsx scripts/seed-disciples.ts`
|
||
|
||
---
|
||
|
||
## Books Extracted
|
||
|
||
### Verse-based Books (stored in `verses` collection)
|
||
|
||
| Book | Code | Verses | Chapters | Division |
|
||
|------|------|--------|----------|----------|
|
||
| Bhagavad-gītā As It Is | `bg` | 653 | 18 | — |
|
||
| Śrīmad-Bhāgavatam | `sb` | 8,258 | 213 | 10 cantos |
|
||
| Śrī Caitanya-caritāmṛta | `cc` | 11,348 | 62 | 3 līlās |
|
||
| SB First Canto (1962 Edition) | `sb1962` | 762 | 19 | — |
|
||
| Śrī Īśopaniṣad | `iso` | 19 | — | Invocation + 18 mantras |
|
||
| The Nectar of Instruction | `noi` | 11 | — | 11 texts |
|
||
| Śrī Brahma-saṁhitā | `bs` | 62 | 1 (Ch. 5) | — |
|
||
| Mukunda-mālā-stotra | `mm` | 6 | 1 | — |
|
||
| Nārada-bhakti-sūtra | `nbs` | 8 | 1 | — |
|
||
|
||
### Prose Books (stored in `prose_chapters` collection)
|
||
|
||
| Book | Code | Chapters | Source |
|
||
|------|------|----------|--------|
|
||
| Kṛṣṇa Book | `kb` | 89 (2 volumes) | other.html |
|
||
| The Nectar of Devotion | `nod` | 51 (4 parts) | other.html |
|
||
| Teachings of Lord Caitanya | `tlc` | 32 (2 parts) | other.html (1968 ed., plain English) |
|
||
| Easy Journey to Other Planets | `ej` | 2 | other.html |
|
||
| Elevation to Kṛṣṇa Consciousness | `ek` | 6 | other.html |
|
||
| Kṛṣṇa Consciousness: The Matchless Gift | `mg` | 7 | other.html |
|
||
| Beyond Birth and Death | `bbd` | 5 | other.html |
|
||
| On the Way to Kṛṣṇa | `owk` | 5 | other.html |
|
||
| Rāja-vidyā: The King of Knowledge | `rv` | 8 | other.html |
|
||
| The Perfection of Yoga | `poy` | 11 | other.html |
|
||
| Perfect Questions Perfect Answers | `pqpa` | 9 | other.html |
|
||
| Transcendental Teachings of Prahlāda Mahārāja | `ttp` | 5 | other.html |
|
||
| On Chanting the Hare Kṛṣṇa Mantra | `ochkm` | 4 | other.html |
|
||
| The Kṛṣṇa Consciousness Handbook | `hkh` | 19 | other.html |
|
||
| The Science of Self-Realization | `ssr` | 50 sub-chapters (8 parents) | other.html |
|
||
| Dialectic Spiritualism | `ds` | 36 sub-chapters (13 parents) | other.html |
|
||
| Life Comes from Life | `lcl` | 16 | other.html |
|
||
| Light of the Bhāgavata | `lob` | 48 | other.html |
|
||
| Teachings of Lord Kapila | `tlk` | 18 | other.html |
|
||
| Teachings of Queen Kuntī | `tqk` | 26 | other.html |
|
||
| Gītār Gān | `gg` | 18 | other.html (Bengali poetic BG) |
|
||
| Songs of the Vaiṣṇava Ācāryas | `sva` | 67 songs (4 parts, hierarchical) | other.html |
|
||
| Message of Godhead | `mog` | 3 | others-before-1977.html |
|
||
| Śrī Caitanya-bhāgavata Commentary | `cbhc` | 4 | others-before-1977.html |
|
||
| Bhagavāner Kathā | `bk` | 2 | others-before-1977.html (ScaGoudy) |
|
||
| Prayers of King Kulaśekhara (1958) | `pk` | 6 | others-before-1977.html |
|
||
| Vaiśiṣṭyāṣṭakam | `va` | 8 | others-before-1977.html |
|
||
|
||
### Essays (stored in `essays` collection)
|
||
|
||
| Essay | Slug | Group | Year |
|
||
|-------|------|-------|------|
|
||
| Krishna The Reservoir Of Pleasure | `krishna-reservoir-of-pleasure` | `two-essays` | 1966 |
|
||
| Who Is Crazy? | `who-is-crazy` | `two-essays` | 1966 |
|
||
| The Spiritual Masters | `the-spiritual-masters` | `cc-essays` | 1960 |
|
||
| The Absolute Truth | `the-absolute-truth` | `cc-essays` | 1957 |
|
||
| The Causes of Lord Caitanya's Incarnation | `causes-of-lord-caitanyas-incarnation` | `cc-essays` | 1957 |
|
||
| The Confidential Reasons for Lord Caitanya's Appearance | `confidential-reasons-for-lord-caitanyas-appearance` | `cc-essays` | 1957 |
|
||
| The Glories of Lord Nityānanda | `glories-of-lord-nityananda` | `cc-essays` | 1957 |
|
||
| Man Is the Architect of His Own Fortune | `man-is-the-architect-of-his-own-fortune` | `pre-1977-essays` | — |
|
||
| What Is the Matter with the World? | `what-is-the-matter-with-the-world` | `pre-1977-essays` | 1957 |
|
||
| Religion Is Godly Life | `religion-is-godly-life` | `pre-1977-essays` | — |
|
||
| Truth and Beauty | `truth-and-beauty` | `pre-1977-essays` | 1958 |
|
||
| Misuse of Public Fund in the Name of Religion | `misuse-of-public-fund-in-the-name-of-religion` | `pre-1977-essays` | 1958 |
|
||
| Perfection at Home | `perfection-at-home` | `pre-1977-essays` | — |
|
||
| How Should One Cultivate Human Spirit | `how-should-one-cultivate-human-spirit` | `pre-1977-essays` | 1961 |
|
||
| Viswa Dharma | `viswa-dharma` | `pre-1977-essays` | — |
|
||
| Glorification of Śrīla Bhaktisiddhānta Sarasvatī Ṭhākura | `glorification-of-srila-bhaktisiddhanta-sarasvati-thakura` | `pre-1977-essays` | 1952 |
|
||
| Who Is Crazy? (Back to Godhead #66) | `who-is-crazy-btg66` | `pre-1977-essays` | — |
|
||
| Manifestation of Dharma in Human Being | `manifestation-of-dharma-in-human-being` | `pre-1977-essays` | 1972 |
|
||
| Message of Krishna Consciousness | `message-of-krishna-consciousness` | `pre-1977-essays` | 1972 |
|
||
| A Wrong Civilization | `a-wrong-civilization` | `pre-1977-essays` | 1936 |
|
||
| Vedānta-sūtra (Typed Transcript) | `vedanta-sutra-typed` | `typed-transcripts` | 1969 |
|
||
| Shaktipujah | `shaktipujah` | `reviews` | — |
|
||
| Devotee and the Divinity | `devotee-and-the-divinity` | `standalone` | — |
|
||
|
||
### Other Documents (stored in `other_document_meta` + `other_document_chapters` collections)
|
||
|
||
| Document | Code | Chapters |
|
||
|----------|------|----------|
|
||
| An Analysis of Bhagwat Geeta | `analysis-bg` | 3 |
|
||
| Solution of Present Crisis by Bhagwat Geeta | `solution-crisis` | 4 |
|
||
| Śrī Caitanya Mahāprabhu | `sri-caitanya` | 3 |
|
||
| Conception of Geeta Nagari on the Principles of Gandhi | `geeta-nagari` | 1 |
|
||
| The Real Peace Formula | `real-peace-formula` | 3 |
|
||
| International Institution for God Consciousness | `intl-institution-god-consciousness` | 1 |
|
||
| "Srimad Bhawatam" India's Message of Peace and Goodwill | `srimad-bhawatam-message` | 1 |
|
||
| Viraha Aṣṭaka | `viraha-astaka` | 8 |
|
||
| Vṛndāvana Bhajana | `vrndavana-bhajana` | 1 |
|
||
| Prayer unto the Lotus Feet of Kṛṣṇa | `prayer-unto-lotus-feet-of-krsna` | 1 |
|
||
| Märkine Bhägavata-dharma | `markine-bhagavata-dharma` | 1 |
|
||
| Jaladuta Pamphlet | `jaladuta-pamphlet` | 1 |
|
||
|
||
### Journals (stored in `journal_meta` + `journal_chapters` collections)
|
||
|
||
| Journal | Code | Chapters | Structure |
|
||
|---------|------|----------|-----------|
|
||
| The Jaladuta Diary, 1965 | `jaladuta-diary` | 85 | Preface, Introduction, 83 day entries grouped by month (Apr–Nov 1965) |
|
||
| The Beginning — The 1966 New York Journal | `the-beginning` | 215 | Introduction, 3 place-based chapters with day entries, Memoranda, Epilogue, 20 Excerpts |
|
||
|
||
### Magazines (stored in `magazine_meta` + `magazine_issues` collections)
|
||
|
||
| Magazine | Code | Issues | Articles | Flag | Source |
|
||
|----------|------|--------|----------|------|--------|
|
||
| Back to Godhead (1944–1960) | `btg` | 29 | 89 | Pre 1978 | btg-1960.html |
|
||
| Back to Godhead (1966–1973) | `btg-1978` | 30 | 1,035 | Pre 1978 | btg-1978.html |
|
||
|
||
### Letters (stored in `letters` collection)
|
||
|
||
| Metric | Value |
|
||
|--------|-------|
|
||
| Total letters | 6,866 |
|
||
| Unique recipients (individual) | 2,243 |
|
||
| Unique locations | 164 |
|
||
| Year range | 1947–1977 |
|
||
| Total paragraphs | 52,261 |
|
||
|
||
**Top recipients**: Satsvarupa (182), Brahmananda (168), Hansadutta (117), Tamala Krsna (115), Gurudasa (103), Mukunda (105), Madhudvisa (90), Karandhara (90)
|
||
|
||
**Top locations**: Los Angeles (1,392), Bombay (1,086), Vrindaban (532), Mayapur (305), London (264), Calcutta (250), Honolulu (239)
|
||
|
||
**Schema notes**:
|
||
- `recipients` is an array of individual names (e.g., `["Mukunda", "Janaki"]`)
|
||
- `recipientDisplay` is the original combined string (e.g., `"Mukunda, Janaki"`)
|
||
- Searching for a recipient filters via the BFF endpoint (matches any letter where that person appears)
|
||
- Multi-recipient groups are split by `,`, `;`, ` and `, ` & `
|
||
- Trailing punctuation (`:`, `,`, `.`) cleaned from names
|
||
|
||
### Transcriptions (stored in `transcriptions` collection)
|
||
|
||
3,787 transcriptions of Śrīla Prabhupāda's lectures and conversations (1966–1977), plus 59 philosophy discussions and 12 SB dictations.
|
||
|
||
- **Lectures** (2,179): Bhagavad-gītā, Śrīmad-Bhāgavatam, Caitanya-caritāmṛta, Nectar of Devotion, Īśopaniṣad, Brahma-saṁhitā, and general lectures
|
||
- **Conversations** (1,537): Morning walks, room conversations, interviews, press conferences, initiations
|
||
- **Philosophy Discussions** (59): Western philosophers discussed with Śyāmasundara and Hayagrīva
|
||
- **SB Dictations** (12): Śrīmad-Bhāgavatam 3rd Canto translation/purport dictations
|
||
- **Audio**: 99.1% have linked audio recordings from Cloudflare R2 (`audioUrl` field)
|
||
- **Empty content**: 30 transcriptions (Hindi/Bengali lectures) have no English text but may have audio
|
||
|
||
Data layer: `lib/transcriptions.ts` (calls BFF API, NOT local JSON files or direct MongoDB)
|
||
|
||
### Other
|
||
|
||
| Content | Collection |
|
||
|---------|-----------|
|
||
| Glossary (2,749 entries) | `glossary` |
|
||
| Transcriptions (3,787 entries) | `transcriptions` collection |
|
||
|
||
---
|
||
|
||
## Font Encoding System
|
||
|
||
### ScaGoudy → IAST mapping (used in BG, SB, CC, ISO, NOI, NoD, and most 1969+ books)
|
||
|
||
```
|
||
ä→ā Ä→Ā å→ṛ Å→Ṛ ñ→ṣ Ñ→Ṣ ö→ṭ Ö→Ṭ ë→ṇ Ë→Ṇ ò→ḍ Ò→Ḍ
|
||
ç→ś Ç→Ś ì→ṅ ï→ñ ü→ū Ü→Ū é→ī É→Ī à→ṁ ù→ḥ è→ṝ û→ṁl ÿ→ḷ
|
||
```
|
||
|
||
### Bengali fonts (Inbenr/Inbeni in CC)
|
||
|
||
Custom-encoded fonts where ASCII codepoints render as Bengali script. Fixed by `fix-bengali-encoding.py`.
|
||
|
||
### RM Devanagari font (used in ISO, NOI)
|
||
|
||
Custom-encoded Devanagari font (p51 CSS class). The text appears as garbled ASCII without the font. **Skipped during extraction** — Unicode Devanagari is generated from IAST transliteration instead.
|
||
|
||
### Devanagari generation
|
||
|
||
IAST transliteration → Devanagari via `indic-transliteration` library. Key fixes:
|
||
- `join_virama_words()` — joins virāma + consonant AND virāma + vowel
|
||
- `normalize_devanagari_anusvara()` — ङ् → ं before velars, ञ् → ं before palatals
|
||
|
||
### Books without ScaGoudy encoding
|
||
|
||
- **TLC (1968 Edition)** — plain English transliterations ("Krishna" not "Kṛṣṇa")
|
||
- **Two Essays (1966)** — plain English
|
||
- **GG (Gītār Gān)** — Bengali poetic text (ScaGoudy decoded for transliteration)
|
||
- **LCL (Life Comes from Life)** — dialogue book, ScaGoudy decoded
|
||
- **MOG, CBHC, PK** — pre-1977 handwritten documents, plain English
|
||
- **BK (Bhagavāner Kathā)** — pre-1977, uses ScaGoudy encoding
|
||
- **CC Essays, Vedānta-sūtra transcript** — plain English
|
||
- All other books from other.html use ScaGoudy encoding
|
||
|
||
---
|
||
|
||
## Book Types and URL Patterns
|
||
|
||
### Verse-based books (use ChapterViewer client component)
|
||
|
||
| Route Pattern | Books |
|
||
|---------------|-------|
|
||
| `/books/bg/[chapter]/[verse]` | BG |
|
||
| `/books/sb/[canto]/[chapter]/[verse]` | SB |
|
||
| `/books/cc/[lila]/[chapter]/[verse]` | CC |
|
||
| `/books/sb1962/[chapter]/[verse]` | SB1962 |
|
||
| `/books/iso/[mantra]` | Īśopaniṣad (verse + intro segments) |
|
||
| `/books/noi/[text]` | Nectar of Instruction (verse + intro segments) |
|
||
| `/books/bs/[chapter]/[verse]` | Brahma-saṁhitā (chapter 5, 62 verses) |
|
||
| `/books/mm/[chapter]/[verse]` | Mukunda-mālā-stotra (6 mantras) |
|
||
| `/books/nbs/[chapter]/[verse]` | Nārada-bhakti-sūtra (8 sūtras) |
|
||
|
||
### Prose books (use per-book data layers + reading pages)
|
||
|
||
| Route Pattern | Books |
|
||
|---------------|-------|
|
||
| `/books/kb/[volume]/[slug]` | Kṛṣṇa Book |
|
||
| `/books/{code}/[chapter]` | NoD, TLC, EJ, EK, MG, BBD, OWK, RV, POY, PQPA, TTP, OCHKM, HKH, LCL, LOB, TLK, TQK, GG, MOG, CBHC, BK, PK |
|
||
|
||
### Hierarchical prose books (sub-chapters as separate pages)
|
||
|
||
| Route Pattern | Books |
|
||
|---------------|-------|
|
||
| `/books/ssr/[chapter]` | Science of Self-Realization (slugs: "1-1", "1-2", "intro-foreword", etc.) |
|
||
| `/books/ds/[chapter]` | Dialectic Spiritualism (slugs: "1-1" = Socrates, "1-2" = Plato, etc.) |
|
||
| `/books/sva/[chapter]` | Songs of the Vaiṣṇava Ācāryas (slugs: "1-1" = Śrī Guru Praṇāma, etc.) |
|
||
|
||
### Essays
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/essays` | Searchable essay grid (23 essays across 6 groups) |
|
||
| `/essays/[slug]` | Individual essay reader |
|
||
|
||
### Other Documents
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/other-documents` | Searchable other documents grid (12 documents) |
|
||
| `/other-documents/[slug]` | Document index (chapter listing) |
|
||
| `/other-documents/[slug]/[chapter]` | Individual chapter reader |
|
||
|
||
### Journals
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/journals` | Journals index (grid) |
|
||
| `/journals/[slug]` | Journal chapter listing (hierarchical: place → month → day) |
|
||
| `/journals/[slug]/[chapter]` | Individual journal entry reader (slug-based, e.g., `apr-3`, `sep-17`, `excerpt-...`) |
|
||
|
||
### Magazines
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/magazines` | Magazines index (grouped by flag: "Pre 1978 Editions") |
|
||
| `/magazines/[slug]` | Magazine issue listing (grouped by volume) |
|
||
| `/magazines/[slug]/[issue]` | Individual issue reader (slug-based, e.g., `v1-p1`, `no-17`) |
|
||
|
||
### Letters
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/letters` | Letters index with 3-way navigation tabs |
|
||
| `/letters?view=year` | Year grid (1947–1977) with search |
|
||
| `/letters?view=recipient` | Recipient list (2,243 individuals) with search + pagination |
|
||
| `/letters?view=location` | Location grid (164 locations) with search + pagination |
|
||
| `/letters/year/1968` | All letters from a specific year |
|
||
| `/letters/recipient/Mukunda` | All letters to/including a specific recipient |
|
||
| `/letters/location/Los%20Angeles` | All letters from a specific location |
|
||
| `/letters/[slug]` | Individual letter reader with prev/next navigation |
|
||
|
||
### Transcriptions
|
||
|
||
```
|
||
/transcriptions → Browse by year / place / type
|
||
/transcriptions?view=year → Year grid view
|
||
/transcriptions?view=place → Place grid view
|
||
/transcriptions?view=type → Lecture vs Conversation cards
|
||
/transcriptions/year/[year] → Year listing, grouped by month
|
||
/transcriptions/place/[place] → Place listing
|
||
/transcriptions/type/[type] → Type listing (lecture/conversation), year sidebar
|
||
/transcriptions/[slug] → Individual transcription reading page
|
||
```
|
||
|
||
Each transcription page shows:
|
||
- Title, type badge (Lecture/Conversation), date, place, reference, duration
|
||
- Participants list
|
||
- Play Audio button (links to Cloudflare R2 mp3)
|
||
- Content blocks: paragraphs with speaker labels, verses (centered italic), quotes (border-left), notes
|
||
- Prev/next navigation within same year
|
||
- `?hl=` text highlight sharing support with OG image
|
||
|
||
### Other routes
|
||
|
||
| Route | Content |
|
||
|-------|---------|
|
||
| `/` | Landing page (responsive 3-column grid) |
|
||
| `/books` | Searchable book grid |
|
||
| `/glossary` | Searchable glossary (2,749 entries) |
|
||
| `/journals` | Journals (2 journals, 300 chapters) |
|
||
| `/magazines` | Magazines (2 magazines, 59 issues, Pre 1978) |
|
||
| `/letters` | Letters (6,866 letters, 3-way navigation) |
|
||
| `/rtfs` | RTF viewer (gated by ALLOW_RTF=true) |
|
||
| `/api/verify-access` | Password protection endpoint |
|
||
|
||
---
|
||
|
||
## Volume Convention
|
||
|
||
Books without volumes use `volume: 0` as a sentinel value in the `prose_chapters` collection. This satisfies the Prisma schema's `@@unique([book, volume, slug])` constraint without requiring schema changes.
|
||
|
||
- KB uses `volume: 1` and `volume: 2`
|
||
- All other prose books use `volume: 0`
|
||
|
||
---
|
||
|
||
## Hierarchical Books (SSR, DS)
|
||
|
||
SSR and DS have parent chapters with sub-chapters stored as individual `prose_chapters` docs:
|
||
|
||
- Sub-chapter slugs: `"1-1"`, `"1-2"`, `"2-1"`, etc.
|
||
- Parent chapter info stored in `intro.json` metadata:
|
||
```json
|
||
{
|
||
"chapters": [
|
||
{
|
||
"number": 1,
|
||
"title": "Learning the Science of the Soul",
|
||
"subChapters": [
|
||
{ "slug": "1-1", "title": "Seeing the Aim of Human Life" },
|
||
{ "slug": "1-2", "title": "Your Original Consciousness Is Kṛṣṇa Consciousness" }
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
- Sidebar UI shows parent headings (non-clickable) with sub-chapters indented below
|
||
- Prev/next navigation skips parent headings
|
||
|
||
---
|
||
|
||
## UI Features
|
||
|
||
### Reading Settings (accessibility)
|
||
- **Theme**: Light / Dark / System toggle
|
||
- **Serif Font**: Toggle to switch reading content to Georgia/serif
|
||
- **Font Size**: Slider (XS → XXL) using CSS `zoom` on `main` and `aside`
|
||
- **Justify Text**: Toggle for justified text alignment on reading content
|
||
- Settings persist in `localStorage` under `spsays_reading_prefs`
|
||
- Applied via CSS classes on `<html>` element
|
||
|
||
### Mobile Navigation
|
||
- Left-slide drawer (vaul) triggered by a menu button next to the Previous button
|
||
- Only visible below `lg` breakpoint
|
||
- Shows the full sidebar navigation grouped by section
|
||
- Implemented in all 24+ reader pages via shared `MobileNav` component
|
||
|
||
### Search
|
||
- Books page: diacritic-aware search (typing "Krsna" matches "Kṛṣṇa")
|
||
- Glossary page: full-text search across terms and definitions
|
||
- Uses Unicode NFD normalization + manual IAST character stripping
|
||
|
||
### Color Palette
|
||
- **Light mode ("Aged Parchment")**: Warm cream backgrounds, deep sepia text, saffron/ochre primary
|
||
- **Dark mode ("Ancient Manuscript")**: Deep warm brown backgrounds, parchment text, golden saffron primary
|
||
|
||
### Text Selection Toolbar
|
||
- Global floating toolbar appears on text selection across all reading pages (except RTFs)
|
||
- **Desktop**: floating pill above selection; **Mobile**: fixed bottom bar
|
||
- Actions: Ask Kautilya (Phase II), Share, Copy (with source reference), More
|
||
- **Share**: modal (desktop) / bottom drawer (mobile) — share to feed, copy highlight link
|
||
- **More**: popover (desktop) / bottom drawer (mobile) — bookmark, save to collection, copy link, mention
|
||
- **Copy** appends source reference: title, chapter/verse, highlight URL
|
||
- All toolbar surfaces use dark contrast treatment (bg-black, border-white/10)
|
||
- Kautilya lotus icon for the AI companion button
|
||
- On iOS Safari mobile, selection is saved/restored when drawers open/close to prevent focus conflicts
|
||
|
||
### Text Highlight Links
|
||
- Selected text encoded as compact URL fragment: `?hl=prefix§suffix§length`
|
||
- Uses `§` delimiter (safe for Sanskrit, English, and all Vedic text)
|
||
- Short selections (≤8 words) use full text as prefix
|
||
- Incoming `?hl=` URLs: text is found in DOM, wrapped in `<mark>`, scrolled to, highlighted permanently
|
||
- `TextHighlighter` component runs on page load via `useSearchParams`
|
||
- Server-side `extractMatchedText()` searches paragraphs for OG image quote extraction
|
||
- Case-insensitive matching for both DOM highlighting and server-side text extraction
|
||
- Cross-paragraph matching via position mapping (spaces inserted at element boundaries)
|
||
|
||
### Dynamic OG Images
|
||
- `/api/og` route generates 1200×630 PNG images using `next/og` (Satori)
|
||
- Left panel: Prabhupāda image with quote mark and branding (from PNG)
|
||
- Right panel: title (bold), detail, quote text, "Read more at prabhupadasays.org"
|
||
- Font: Noto Sans Regular + Bold loaded from `public/fonts/Noto_Sans/static/` — full IAST diacritical support
|
||
- All 104 content pages have `generateMetadata` with contextual fallback descriptions
|
||
- When `?hl=` is present, the actual selected text is extracted from DB content for the OG quote
|
||
|
||
### Audio Player
|
||
|
||
A site-wide floating audio player for transcription recordings (and future music library). Built with framer-motion for animations.
|
||
|
||
- **Desktop**: Centered floating bar (max-width 680px) with cover image, track info, transport controls (prev/play/next), volume slider, source link, close button
|
||
- **Mobile**: Full player shows two rows: track info row + centered transport controls
|
||
- **Auto-minimize**: After 8 seconds of inactivity on **both mobile and desktop**, the player auto-minimizes to a floating pill. The minimized pill shows cover image with a circular progress ring and audio wave animation. Tap/click to expand.
|
||
- **X button behavior**: Minimizes the player if audio is playing; stops playback entirely if audio is paused
|
||
- **Clicking outside the player**: Minimizes it (does not stop playback)
|
||
- **Z-index**: `z-40` — below text selection toolbar (z-80), drawers (z-90), modals (z-100)
|
||
- **Hidden when selection toolbar is active** on mobile to avoid overlap
|
||
- **Forced dark surface** (`bg-[#1c1c1e]`) for accessibility contrast regardless of theme
|
||
- **Keyboard shortcuts**: Space (play/pause), ←/→ (seek ±10s), ↑/↓ (volume), M (mute), Esc (close)
|
||
- **Progress seeker**: 8px tall bar at top of player, click/drag to seek
|
||
- **Volume**: Persisted to localStorage. Mobile relies on hardware volume buttons
|
||
- **framer-motion**: Spring animations for enter/exit, AnimatePresence for minimize/expand transitions, motion.div for audio wave bars
|
||
|
||
Components:
|
||
- `components/audio-player/audio-context.tsx` — React context + provider, manages `<audio>` element
|
||
- `components/audio-player/floating-player.tsx` — Floating player UI
|
||
- `components/audio-player/audio-wave.tsx` — Reusable animated audio wave bars
|
||
- `components/audio-player/index.ts` — Barrel exports
|
||
|
||
The `AudioPlayerProvider` wraps the entire app in `layout.tsx`. The `FloatingPlayer` is rendered before `SiteFooter`.
|
||
|
||
### Site Footer
|
||
- Global footer on every page with © year, About link, Home link
|
||
|
||
### Consistent Container Width
|
||
- All pages use `max-w-5xl` for both header and body containers
|
||
|
||
---
|
||
|
||
## Environment Variables
|
||
|
||
```
|
||
BFF_URL=http://localhost:8080 # Go BFF API server URL (default: http://localhost:8080)
|
||
ALLOW_RTF=true # Enable RTF viewer (development only)
|
||
NEXT_PUBLIC_SITE_URL=https://prabhupadasays.org # Public site URL for OG images
|
||
```
|
||
|
||
---
|
||
|
||
## How to Run
|
||
|
||
```bash
|
||
# 1. Start the Go BFF server (required — all data comes from the BFF)
|
||
cd spsays-bff && go run cmd/api/main.go # Starts on :8080 by default
|
||
|
||
# 2. Development (from knowledgebase/)
|
||
npm run dev # Next.js dev server with Turbopack
|
||
|
||
# 3. Build
|
||
npx next build
|
||
|
||
# Extraction & seeding scripts are in extractor/ — see extractor/scripts/
|
||
```
|
||
|
||
> **Note**: No `npx prisma generate`, `npx prisma db push`, or MongoDB connection string needed in the frontend. The BFF server must be running for any page to load data.
|
||
|
||
---
|
||
|
||
## Verse JSON Schema (BG/SB/CC/SB1962/ISO/NOI)
|
||
|
||
```json
|
||
{
|
||
"book_title": "Śrīmad-Bhāgavatam",
|
||
"canto": 1,
|
||
"chapter": 1,
|
||
"verse": 1,
|
||
"verse_end": null,
|
||
"reference": "SB 1.1.1",
|
||
"devanagari": "ॐ नमो भगवते वासुदेवाय\nजन्माद्यस्य यतो ...",
|
||
"bengali": null,
|
||
"transliteration": "om namo bhagavate vāsudevāya\njanmādy asya yato ...",
|
||
"synonyms": [
|
||
{ "word": "om", "meanings": ["O my Lord"] },
|
||
{ "word": "namaḥ", "meanings": ["offering my obeisances"] }
|
||
],
|
||
"translation": "<b>I offer my obeisances unto Lord Śrī Kṛṣṇa...</b>",
|
||
"purport": ["paragraph 1...", "paragraph 2..."]
|
||
}
|
||
```
|
||
|
||
## Prose Chapter JSON Schema
|
||
|
||
```json
|
||
{
|
||
"book": "ek",
|
||
"chapter": 1,
|
||
"title": "Choosing Human and Animal Lives",
|
||
"type": "chapter",
|
||
"paragraphs": ["<b>heading</b>", "body text...", "<div style=\"text-align:center\"><i>verse</i></div>"]
|
||
}
|
||
```
|
||
|
||
## Intro Segment JSON Schema
|
||
|
||
```json
|
||
{
|
||
"slug": "preface",
|
||
"title": "Preface",
|
||
"type": "intro-segment",
|
||
"book": "ek",
|
||
"order": 2,
|
||
"paragraphs": ["paragraph 1...", "paragraph 2..."]
|
||
}
|
||
```
|
||
|
||
## Essay JSON Schema
|
||
|
||
```json
|
||
{
|
||
"slug": "krishna-reservoir-of-pleasure",
|
||
"title": "Krishna The Reservoir Of Pleasure",
|
||
"author": "His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda",
|
||
"year": 1966,
|
||
"group": "two-essays",
|
||
"order": 1,
|
||
"paragraphs": ["paragraph 1...", "paragraph 2..."]
|
||
}
|
||
```
|
||
|
||
## Glossary JSON Schema
|
||
|
||
```json
|
||
{
|
||
"title": "Glossary of Vedic Terms",
|
||
"description": "A comprehensive glossary...",
|
||
"totalEntries": 2749,
|
||
"letters": ["A", "B", "C", ...],
|
||
"entries": [
|
||
{
|
||
"term": "Ācārya",
|
||
"definition": "a spiritual master who teaches by his own example...",
|
||
"definition_html": "a spiritual master who teaches by his own example..."
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Glossary is browsed via `/glossary/{letter}` routes (A-Z). Each letter page shows terms grouped by base letter (diacritical variants mapped: Ā→A, Ś→S, Ṛ→R, etc.). Single entry view with prev/next navigation.
|
||
|
||
## Transcription JSON Schema
|
||
|
||
```json
|
||
{
|
||
"slug": "720911sb-los-angeles",
|
||
"name": "Śrīmad-Bhāgavatam 1.2.6",
|
||
"type": "lecture",
|
||
"date": "September 11, 1972",
|
||
"year": 1972,
|
||
"month": 9,
|
||
"day": 11,
|
||
"place": "Los Angeles",
|
||
"context": null,
|
||
"reference": "SB 1.2.6",
|
||
"durationMinutes": 45,
|
||
"participants": ["Prabhupāda", "Devotees"],
|
||
"audioUrl": "https://s3.prabhupadasays.com/sp-audio/...",
|
||
"content": [
|
||
{
|
||
"text": "So Kṛṣṇa consciousness movement...",
|
||
"format": "paragraph",
|
||
"alignment": "left",
|
||
"speaker": "Prabhupāda"
|
||
},
|
||
{
|
||
"text": "<i>oṁ namo bhagavate...</i>",
|
||
"format": "verse",
|
||
"alignment": "center",
|
||
"speaker": null
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Content block formats: `"paragraph"` (body text), `"verse"` (centered italic), `"quote"` (translation/purport), `"heading"` (TEXT/TRANSLATION/PURPORT labels), `"note"` (editorial notes).
|
||
|
||
---
|
||
|
||
## Known Issues
|
||
|
||
1. **BFF dependency** — The knowledgebase requires the Go BFF server to be running; all pages will fail to load data if the BFF is down.
|
||
|
||
2. **SB verse numbering**: 5 duplicate verse reference tags in the HTML. Fixed by using the TEXT N header as authoritative.
|
||
|
||
3. **RTF routes gated**: `/rtfs` only accessible when `ALLOW_RTF=true`.
|
||
|
||
4. **`scripts/` excluded from tsconfig**: Prevents TypeScript build errors from seed scripts.
|
||
|
||
5. **CSS zoom for font scaling**: `zoom` property works in Chrome/Safari/Edge but may not work in older Firefox (< 126). A `transform: scale()` fallback is provided via `@supports not (zoom: 1.1)`.
|
||
|
||
6. **Transcription BSON fallback** — 1 document stores content as `contentJson` string due to BSON wire protocol limits; `getTranscription()` transparently parses it
|
||
|
||
7. **Empty transcriptions** — 30 entries have no English text content (Hindi/Bengali recordings); the UI shows "No transcription available" with the audio player still accessible
|
||
|
||
8. **Audio player z-index** — Player is hidden when text selection toolbar is active on mobile to avoid overlap |