A PDF occlusion study app with a React + Vite frontend and an Express + PostgreSQL backend. It supports occlusions, bookmarks, and spaced‑repetition (SM‑2) review data.
- Create and sync PDF occlusions per document
- Bookmark pages
- Spaced repetition (SM‑2) review scheduling
- Local/offline‑friendly sync primitives
- Frontend: React, TypeScript, Vite, Zustand, pdfjs
- Backend: Node.js, Express, PostgreSQL
- Storage: PostgreSQL schema in
backend/schema.sql
.
├── backend
│ ├── index.js
│ ├── package.json
│ └── schema.sql
└── frontend
├── package.json
├── vite.config.ts
└── src/
- Node.js 18+ (recommended)
- PostgreSQL 14+ (recommended)
cd backend
npm installInitialize the database:
psql -d occlusion_engine -f schema.sqlRun the server:
node index.jsBy default the server connects via local Unix socket using:
- user:
harry - database:
occlusion_engine - host:
/var/run/postgresql
To override, set DATABASE_URL:
export DATABASE_URL="postgres://user:pass@localhost:5432/occlusion_engine"The server runs on PORT=3000 by default.
cd frontend
npm install
npm run devVite will print the local dev URL.
GET /health— DB connectivity check
GET /api/sync/:file_hash?since=TIMESTAMPPOST /api/sync
GET /api/bookmarks/:file_hash?since=TIMESTAMPPOST /api/bookmarks/sync
POST /api/srs/reviewGET /api/srs/cards/:file_hash?since=TIMESTAMPPOST /api/srs/syncGET /api/dashboard/:file_hash
All sync endpoints expect timestamps in milliseconds and use last‑write‑wins logic where applicable.
- The backend verifies DB connectivity at startup and exits with a helpful message if the schema isn’t initialized.
- Frontend uses Vite + React with TypeScript and Zustand for state management.
Pull requests and issues are welcome. Please include context, reproduction steps, and screenshots where helpful.
No license has been specified yet.