Paperlog is a social reading diary for research papers: find papers, rate them, leave fast reader notes, organize lists, discuss interpretations, and document code/reproducibility experiences.
Live MVP: paperlog.net
- Current MVP and alpha plan
- Next-steps roadmap
- Friend testing guide
- 2026-07-12 build and operations handoff
- 2026-07-13 Google, GitHub, and ChatGPT authentication handoff
- 2026-07-13 verified production status
- Data-rights implementation audit
- Private backup and isolated restore procedure
- OpenAlex paper search plus direct DOI, arXiv, OpenReview, and OpenAlex ID resolution
- public DOI redirects at
/paper/resolve?doi=…(with/paper/doiretained as an alias) for durable links from related applications - a verified 12-paper Paper Picture fallback catalog, keeping those destinations available during OpenAlex outages or unauthenticated rate limits
- live rating and log aggregates from the first real rating
- profiles with bios, affiliations, interests, follows, saved papers, and public lists
- reader logs with engagement status, helpful votes, replies, reports, and notifications
- structured reproducibility reports with repository, commit, environment, data, outcome, score, notes, and evidence
- manually verified paper-author responses
- metadata/version correction workflow
- private moderation console, audit trail, rate limits, health endpoint, and JSON backup export
- browser security headers, same-origin protection for state-changing APIs, scheduled uptime checks, and dependency monitoring
- account export/deletion, alpha onboarding, legal pages, and responsive/accessibility treatment
- unified Google, GitHub, and managed ChatGPT sign-in with verified-email account linking
- Node.js
>=22.13.0
npm install
npm run dev
npm run buildThis starter does not use wrangler.jsonc.
- edit site code under
app/ .openai/hosting.jsondeclares optional Sites D1 and R2 bindingsvite.config.tssimulates declared bindings for local developmentdb/schema.tsdefines the D1 persistence modelapp/api/contains public reads, authenticated writes, and admin operationsapp/alphais the five-person test scriptdrizzle.config.tssupports local migration generation when needed
OpenAI workspace sites can read the current user's email from
oai-authenticated-user-email.
SIWC-authenticated workspace sites may also receive
oai-authenticated-user-full-name when the user's SIWC profile has a non-empty
name claim. The full-name value is percent-encoded UTF-8 and is accompanied by
oai-authenticated-user-full-name-encoding: percent-encoded-utf-8.
Treat the full name as optional and fall back to email when it is absent:
import { headers } from "next/headers";
export default async function Home() {
const requestHeaders = await headers();
const email = requestHeaders.get("oai-authenticated-user-email");
const encodedFullName = requestHeaders.get("oai-authenticated-user-full-name");
const fullName =
encodedFullName &&
requestHeaders.get("oai-authenticated-user-full-name-encoding") ===
"percent-encoded-utf-8"
? decodeURIComponent(encodedFullName)
: null;
const displayName = fullName ?? email;
// ...
}Paperlog keeps the Sites-managed ChatGPT sign-in and adds app-owned Google and
GitHub OAuth through the unified /signin page. Import the compatibility
helpers from app/chatgpt-auth.ts when a page needs optional or required
identity:
- Use
getChatGPTUser()for optional signed-in UI. - Use
requireChatGPTUser(returnTo)for server-rendered pages that should send anonymous visitors through Sign in with ChatGPT. - Use
chatGPTSignInPath(returnTo)andchatGPTSignOutPath(returnTo)for the unified provider chooser and provider-aware sign-out. - Pass a same-origin relative
returnTopath for the destination after sign-in or sign-out. The helper validates and safely encodes it. - Mark protected pages with
export const dynamic = "force-dynamic"because they depend on per-request identity headers.
Sites owns /signin-with-chatgpt, /signout-with-chatgpt, /callback, its
cookies, and ChatGPT identity header injection. Do not implement app routes for
those reserved paths. Paperlog owns /api/auth/* and stores Google/GitHub users,
linked accounts, and sessions in the existing D1 database. Provider tokens are
encrypted, and accounts are linked only through provider-verified matching
email addresses.
Configure BETTER_AUTH_SECRET, BETTER_AUTH_URL, and the Google/GitHub client
credentials documented in .env.example. Register these production callbacks:
https://paperlog.net/api/auth/callback/googlehttps://paperlog.net/api/auth/callback/github
If a provider credential pair is absent, its button is hidden and ChatGPT sign-in continues to work.
SIWC establishes identity only; it does not prove workspace membership. Use the Sites hosting platform's access policy controls for workspace-wide restrictions, or enforce explicit server-side membership or allowlist checks.
Use SIWC for account pages, user-specific dashboards, saved records, and write actions tied to the current ChatGPT user. Leave public content anonymous.
npm run dev: start local developmentnpm run build: verify the vinext build outputnpm test: build Paperlog and run the complete automated test suitenpm run test:unit: run API/security, restore, and rendered-experience tests without rebuildingnpm run test:api: start an isolated local app and smoke-test live API routesnpm run audit: fail on high- or critical-severity dependency findingsnpm run backup:restore -- --input … --output …: verify an administrator export in an isolated local SQLite databasenpm run db:generate: generate Drizzle migrations after schema changes
The custom domain is connected, the MVP is publicly reachable, and OPENALEX_API_KEY is configured as a protected hosting secret. Keep private production exports on a regular schedule, run restore drills, review automated dependency updates before merging, and have the policies reviewed before a broad public launch.