Dogeared exists to create a better place for readers.
It is built for people who love books, who want to track what they read, discover what’s next, and share those experiences with others.
Dogeared is not driven by ads, algorithms, or profit. It is free to use, supported by optional donations, and designed with a focus on simplicity, usefulness, and respect for its users.
We believe books are for everyone. No book should be hidden, restricted, or left behind because of trends, systems, or gatekeeping.
This is a space for readers, built and maintained with care, where the goal is not growth at all costs, but something better, a tool that stays useful, thoughtful, and true to the people who use it.
Dogeared now includes a Neon-ready schema for app-driven genre lists. The catalog layer is designed to persist normalized book metadata and source identifiers only. Avoid storing or re-serving full third-party payloads unless the provider terms explicitly allow it.
db/neon-schema.sql: core tables +get_top_books_by_genre(...)ranking function.src/lib/catalog.ts: catalog-source helpers for source mapping persistence.src/lib/neon.ts: Vercel server runtime Neon client.src/pages/api/activity/recent.ts: API route for recent user activity from Neon.src/pages/api/profile/info.ts: API route for persisted profile metadata in Neon.src/pages/api/lists/top.ts: API route for Top books by genre.
Set this in local .env and in Vercel Project Settings:
DATABASE_URL: Neon pooled connection string.GOOGLE_BOOKS_API_KEY: existing key for search/suggest routes.BREVO_API_KEY: API key for Dogeared magic-link email delivery.BREVO_FROM_EMAIL: verified sender email used for magic-link emails.BREVO_FROM_NAME: optional sender name for magic-link emails.APP_BASE_URL: production base URL used by scheduled monitoring workflow (store as GitHub secret).ADMIN_USERNAMES: comma-separated usernames allowed to access/admin/data-health(default:wylie).
- Create a Neon project and copy its pooled
DATABASE_URL. - Run
db/neon-schema.sqlin Neon SQL Editor. - Add
DATABASE_URLto Vercel. - Deploy to Vercel.
- Query top list route:
/api/lists/top?genre=fantasy- Optional:
limit(1-50),windowDays(1-3650)
get_top_books_by_genre(...) ranks titles from real user shelves:
readingweighted highestfinishedweighted mediumwant_to_readweighted baseline- plus unique reader count
Recurring metadata maintenance is now centralized:
npm run backfill:report: outputs JSON coverage for book/author metadata and duplicate work-key groups.npm run backfill:metadata: runs quality report, author bio/avatar backfills, synopsis backfill, genre backfill, then a final report.
Optional env controls:
BACKFILL_DRY_RUN=1: run without writes for author scripts.BACKFILL_LIMIT=500: cap records processed per script (0 or unset = no cap).BACKFILL_CONCURRENCY=4: worker concurrency for supported scripts.METRICS_FACT_LIMIT=3000: max analytics fact rows included in live metrics payload.
GitHub Actions:
.github/workflows/metadata-backfills.ymlruns weekly on Monday and supports manual dispatch.- Scheduled runs default to dry-run mode with a bounded limit.
- CI now includes smoke-level endpoint checks in
tests/production-smoke.test.ts. /api/healthprovides a lightweight health signal with DB status/latency..github/workflows/production-monitor.ymlruns every 30 minutes and checks:/api/health/api/books/search/api/lists/top
- On failure, the monitor workflow creates or updates a
Production monitor failureissue with a link to the failed run.
Client auth state is now centralized in src/lib/clientAuth.ts and used across navigation and shelf actions.
For local UI checks, you can force view mode per URL:
?authView=logged-in?authView=logged-out?authView=live(or remove the param)
The override is stored in local storage (dogeared:auth-preview) so you can quickly refresh and compare authenticated vs unauthenticated views while building profile/privacy/follow flows.
If you find Dogeared useful and want to help it grow, this is a simple way to do that.