Curated quotations by Castalia faculty authors, linked to texts in Bibliotech with EPUB locators (CFI) for Readest.
Site: https://quotes.castalia.institute/
Quote of the day: HTML · JSON
Table faculty_quotes (Castalia Supabase project, shared with Bibliotech):
| Column | Purpose |
|---|---|
faculty_id |
public.faculty.id (e.g. a.shakespeare) |
book_id |
public.books.id when the EPUB is in corpus |
quote_text |
The quotation |
passage_label |
Human citation (act, chapter, poem) |
cfi |
EPUB Canonical Fragment Identifier for Readest |
epub_locator |
JSON fallback before CFI is resolved |
source / source_id |
Bibliotech catalog keys (gutenberg, id) |
View faculty_quotes_public adds faculty_name and readest_url.
Migration: supabase/migrations/20260517120000_create_faculty_quotes.sql (also copied to castalia.institute/supabase/migrations).
cp ../castalia.institute/.env .env # or export SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY
npm install
npm run seed:dry
npm run seedRows with matching books.source + books.source_id get book_id filled automatically.
- Open the book via
readest_url(or Bibliotech library?book=<uuid>). - Navigate to the passage and copy the CFI from developer tools / note sync.
- Update
faculty_quotes.cfiso highlights deep-link correctly (&cfi=on the Readest URL is reserved for this).
Static site in docs/ with docs/CNAME = quotes.castalia.institute.
npm run build # writes docs/quote-of-the-day.{json,html}Enable Pages → GitHub Actions (workflow pages.yml). Daily cron rebuilds quote-of-the-day.
DNS-only CNAME quotes → castaliainstitute.github.io:
set -a && source ../castalia.institute/.env && set +a
[[ -z "${CLOUDFLARE_API_TOKEN:-}" && -n "${CLOUDFLARE_TOKEN:-}" ]] && export CLOUDFLARE_API_TOKEN="$CLOUDFLARE_TOKEN"
npm run dnsThen in GitHub: Settings → Pages → Custom domain → quotes.castalia.institute.
Each published quote has a search_text document (quote, passage, work title, tags) and a embedding (vector(1536), OpenAI text-embedding-3-small).
npm run embed # embed via edge (OpenRouter → Gemini fallback)
npm run search -- "stoicism and resilience"
npm run search -- "libraries paradise" --jsonEmbeddings use Gemini gemini-embedding-001 at 1536 dimensions on the server (OpenRouter when credits are available). Re-embed after adding quotes: npm run embed or npm run embed:force.
SQL RPC: search_faculty_quotes(query_embedding, match_count, match_threshold, filter_faculty_id)
Edge function: POST /functions/v1/search-quotes with { "query": "…", "limit": 8, "faculty_id": "a.plato" }
Deploy from castalia.institute:
supabase functions deploy search-quotes --project-ref pilmscrodlitdrygabvoWeb UI: quotes.castalia.institute/search.html (requires search-config.js from npm run build:search-config).
When quotes change, re-run npm run embed (trigger clears embedding if search_text changes).
{
"date": "2026-05-17",
"index": 3,
"total": 12,
"quote": {
"faculty_id": "a.woolf",
"quote_text": "...",
"passage_label": "...",
"book_title": "...",
"readest_url": "https://bibliotech.castalia.institute/read/?book=..."
}
}