Self-hosted academic publication tracker. Track Google Scholar profiles, discover new papers automatically, resolve open-access PDFs, and stay on top of the literature you care about.
Find a file
2026-02-17 20:23:48 +01:00
.github/workflows First product 2026-02-17 14:51:25 +01:00
alembic First product 2026-02-17 14:51:25 +01:00
app removed old UI 2026-02-17 15:21:08 +01:00
scripts First product 2026-02-17 14:51:25 +01:00
tests removed old UI 2026-02-17 15:21:08 +01:00
.dockerignore First product 2026-02-17 14:51:25 +01:00
.env.example removed old UI 2026-02-17 15:21:08 +01:00
.gitignore First product 2026-02-17 14:51:25 +01:00
.python-version First product 2026-02-17 14:51:25 +01:00
AGENTS.MD removed old UI 2026-02-17 15:21:08 +01:00
alembic.ini First product 2026-02-17 14:51:25 +01:00
docker-compose.yml removed old UI 2026-02-17 15:21:08 +01:00
Dockerfile First product 2026-02-17 14:51:25 +01:00
pyproject.toml removed old UI 2026-02-17 15:21:08 +01:00
README.md removed old UI 2026-02-17 15:21:08 +01:00
uv.lock removed old UI 2026-02-17 15:21:08 +01:00

scholarr

API-first, self-hosted scholar tracking backend in the spirit of the *arr ecosystem.

The legacy server-rendered UI has been removed. This repository now focuses on core ingestion, scheduling, and multi-user API functionality.

Current Scope

  • Multi-user accounts with admin-managed user lifecycle
  • Same-origin cookie sessions with CSRF enforcement
  • API auth flows (login, logout, me, password change)
  • Admin user management API
  • Scholar CRUD per user
  • Per-user ingestion settings
  • Manual runs with idempotency support
  • Run history, run detail diagnostics, and continuation queue actions
  • Publication listing (new / all) and mark-all-read
  • Ingestion scheduler + continuation queue retries
  • Structured logging with request IDs + redaction
  • PostgreSQL + Alembic migrations
  • Container-first development workflow with uv

Functionality Tracking

Planned and supported backend functionality is tracked in:

  • AGENTS.MD

API Base

  • Base path: /api/v1
  • Success envelope:
    • {"data": ..., "meta": {"request_id": "..."}}
  • Error envelope:
    • {"error": {"code": "...", "message": "...", "details": ...}, "meta": {"request_id": "..."}}

Auth & Session Model

  • Session transport: same-origin cookie session (HttpOnly, SameSite=Lax)
  • CSRF:
    • Required for unsafe methods (POST, PUT, PATCH, DELETE) via X-CSRF-Token
    • Bootstrap token via GET /api/v1/auth/csrf

API Surface

  • Auth:
    • GET /api/v1/auth/csrf
    • POST /api/v1/auth/login
    • GET /api/v1/auth/me
    • POST /api/v1/auth/change-password
    • POST /api/v1/auth/logout
  • Admin users:
    • GET /api/v1/admin/users
    • POST /api/v1/admin/users
    • PATCH /api/v1/admin/users/{id}/active
    • POST /api/v1/admin/users/{id}/reset-password
  • Scholars:
    • GET /api/v1/scholars
    • POST /api/v1/scholars
    • PATCH /api/v1/scholars/{id}/toggle
    • DELETE /api/v1/scholars/{id}
  • Settings:
    • GET /api/v1/settings
    • PUT /api/v1/settings
  • Runs:
    • GET /api/v1/runs
    • GET /api/v1/runs/{id}
    • POST /api/v1/runs/manual (Idempotency-Key supported)
    • GET /api/v1/runs/queue/items
    • POST /api/v1/runs/queue/{id}/retry
    • POST /api/v1/runs/queue/{id}/drop
    • DELETE /api/v1/runs/queue/{id}
  • Publications:
    • GET /api/v1/publications
    • POST /api/v1/publications/mark-all-read
  • Ops:
    • GET /healthz

Quick Start

  1. Copy environment defaults:
cp .env.example .env
  1. Optional bootstrap admin on startup:
export BOOTSTRAP_ADMIN_ON_START=1
export BOOTSTRAP_ADMIN_EMAIL=admin@example.com
export BOOTSTRAP_ADMIN_PASSWORD=change-me-now
  1. Start stack:
docker compose up --build
  1. Health check:
http://localhost:8000/healthz

Admin Bootstrap (Manual)

docker compose run --rm app uv run python scripts/bootstrap_admin.py \
  --email admin@example.com \
  --password change-me-now \
  --force-password

Test Workflow

  • Unit tests:
docker compose run --rm app uv run pytest tests/unit
  • Integration tests:
docker compose run --rm app uv run pytest -m integration
  • Smoke checks:
./scripts/smoke_compose.sh

Logging

Configurable env vars:

  • LOG_LEVEL (default INFO)
  • LOG_FORMAT (console or json, default console)
  • LOG_REQUESTS (1/0, default 1)
  • LOG_UVICORN_ACCESS (1/0, default 0)
  • LOG_REQUEST_SKIP_PATHS (default /healthz)
  • LOG_REDACT_FIELDS (additional redact keys)

Project Layout

app/         FastAPI app (API routers, auth, services, db, middleware)
alembic/     Migration environment and versions
scripts/     Entrypoint, db wait/bootstrap, smoke automation
tests/       Unit, integration, and smoke suites
planning/    Scope and implementation planning notes