The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Live: https://lyncei.com (demo data)
The social network where every post can be peer-reviewed. Science, made social. Rigor, made visible. Scientists, made human.
This repository is the private-beta codebase described in the Technical Build Specification (v1.1) and the PRD (v2.1).
| Area | Implemented |
|---|---|
| Sign-in | Passwordless email links (15-minute, single-use, hashed), 30-day sessions in HttpOnly cookies |
| ORCID | Connect an ORCID iD via OAuth /authenticate scope (proves ownership only; never grants reviewer status) |
| Posts | Video explainer, Visual, Thread, Behind the Paper and Open Question formats; DOI field with Crossref lookup; AI-assistance disclosure |
| Rigor labels | Unreviewed · Source-linked · Source-checked · Expert-reviewed · Disputed · Source retracted, derived from sources, reviews and moderation (src/lib/rigor.ts), never from likes |
| Transparent peer review | Verified reviewers (anonymous to readers by default; signing is opt-in) submit source-fidelity, methodological, statistical or clinical-relevance reviews with checklist, required conflict declaration, and study-quality ratings; labels update automatically |
| Discussion | Typed contributions (question, evidence, objection, interpretation, correction); evidence requires a DOI; threaded replies |
| Social | Feed (For you, Following, Reviewed, Open questions) with transparent ranking and a "Shown because…" line; likes and insightful reactions; saves; follows |
| Questions | Persistent questions with follow, linked posts and an evidence summary |
| Profiles | Bio, current work, ORCID, verified-reviewer badge, posts, reviews written, contribution credits |
| Moderation | Reports, moderator queue, Disputed state with public rationale, author notifications |
| Integrity | Append-only audit_events table (UPDATE/DELETE blocked by trigger) for posts, reviews, labels, reports and roles |
| Data rights | GET /api/v1/me/export downloads all of a user's data as JSON |
| Jobs | npm run jobs:sync-sources re-checks DOIs against Crossref, resolves pending ones and records corrections and retractions |
| API | GET /api/v1/questions, GET /api/v1/posts/:id (rigor + reviews; reviewer named only if signed), GET /api/v1/me/export |
public/welcome.html (served at /welcome) is the public landing page. Its two forms (researchers, labs and programs) post to POST /api/waitlist, which validates the email, rejects cross-origin posts, throttles repeated attempts, and stores email + interest (individual or institutional) in the waitlist table. The page shows success only after the API confirms the row was saved.
Nothing else is needed beyond DATABASE_URL: the table is created by migration 0002_waitlist, which the Vercel build applies. To read the list:
select email, interest, created_at from waitlist order by created_at desc;
Not built yet: confirmation emails to people who join, and an admin screen for the list.
Next.js 15 (App Router, server actions) · React 19 · TypeScript · PostgreSQL 16 · Drizzle ORM · Zod · Vitest. No client-side state library; almost everything renders on the server.
Requirements: Node 20.9+ and Docker (or any PostgreSQL 16).
docker compose up -d # PostgreSQL on localhost:5432
cp .env.example .env
npm install
npm run db:migrate
npm run db:seed # fictional demo people, questions and posts
npm run dev # http://localhost:3000
Signing in during development: without RESEND_API_KEY, the sign-in link is printed in the terminal running npm run dev. Open it in the browser.
Demo accounts (all fictional; the moderator account [email protected] is excluded from public demo sign-in): [email protected], [email protected] (reviewers), [email protected] (member).
Granting roles: a person signs in once, then:
npm run admin:grant -- [email protected] reviewer "Cardiology,Clinical trials"
npm run admin:grant -- [email protected] moderator
| Command | Purpose |
|---|---|
npm run dev / build / start | Develop, build and serve |
npm test | Unit tests (rigor rules, DOI parsing, Crossref mapping) |
npm run typecheck | TypeScript check |
npm run db:generate | Create a migration after editing src/db/schema.ts |
npm run db:migrate | Apply migrations |
npm run db:seed | Load demo data (refuses to run in production) |
npm run jobs:sync-sources | Nightly Crossref sync (schedule with cron) |
npm run admin:grant | Grant a role |
src/
app/ routes (feed, posts, reviews, questions, profiles, moderation, settings, auth, api/v1)
actions.ts all server actions: validation, permissions, transactions, audit, notifications
components/ ui.tsx (server), client.tsx (forms), rail.tsx
db/ schema.ts, migrate.ts, seed.ts
lib/ rigor.ts, doi.ts, queries.ts, auth.ts, audit.ts, email.ts, text.ts
jobs/ sync-sources.ts
drizzle/ SQL migrations (0001 makes audit_events append-only)
scripts/grant-role.ts
Demo deployment on Vercel (no email provider needed): import the repo in Vercel, add a Neon Postgres database from the Storage tab (it sets DATABASE_URL), and set APP_URL (or SITE_URL, which takes precedence) to the deployment URL, ALLOW_DEMO_SEED=1 and DEMO_ACCOUNTS=1. The build runs migrations and seeds demo data on first deploy, and the sign-in page offers one-click demo accounts. Remove DEMO_ACCOUNTS and set ALLOW_DEMO_SEED=0 before inviting real users.
Production:
DATABASE_URL.APP_URL, CROSSREF_MAILTO, RESEND_API_KEY, EMAIL_FROM and, optionally, the ORCID_* variables.npm run db:migrate against the production database (from CI or locally).npm run jobs:sync-sources daily (Vercel Cron, GitHub Actions schedule or any worker)./activities/update scope)admin:grant)computeRigor.