A platform that tracks events (not articles), where every piece of information is a claim with evidence, contributors have reputation scores, and the crowd can fact-check and participate in prediction markets.
- Frontend: React (Vite) + TypeScript – event/claim browsing, reputation, fact-checking UI, prediction markets
- Backend: NestJS + TypeScript – REST API, PostgreSQL via TypeORM
- Infra: Docker Compose (PostgreSQL, backend, frontend)
- Events – Each event (e.g. “Bridge collapse in Lisbon”) has a timeline of reports, eyewitness accounts, media, official statements, and analysis.
- Claims with evidence – Claims have labels: Unverified → Evidence provided → Multiple confirmations → Confirmed. Each claim can have attached evidence (documents, videos, links).
- Login – Contributors can sign in with Google or Facebook (OAuth). JWT is issued and used for authenticated requests.
- Reputation – Contributors get a reliability score that goes up (confirmed reports, correct fact-checks) or down (false claims, repeated corrections).
- Crowd fact-checking – Users can challenge claims, add counter-evidence, confirm reports, or add context (Community Notes–style, attached to claims).
- Prediction markets – Users predict the probability that a claim will turn out true; good predictors gain reputation.
- Create Events – Anyone can propose an event, Event starts as unverified, Event becomes public after community confirmation, High-reputation users and verified reporters can bypass event verification
# From project root
docker compose up --build- Frontend: http://localhost:5173 (Vite proxies
/apito the backend) - Backend API: http://localhost:3000/api (e.g. http://localhost:3000/api/events)
cd backend
cp .env.example .env # set DATABASE_URL if needed
npm install
npm run start:devcd frontend
npm install
npm run devEnsure PostgreSQL is running and create a database truestory, or use the one from Docker:
docker compose up postgres -d
# then run backend with DATABASE_URL=postgresql://truestory:truestory_secret@localhost:5432/truestoryWith the stack running, you can create an event and a claim via the API:
# Create a user (contributor)
curl -s -X POST http://localhost:3000/api/users -H "Content-Type: application/json" \
-d '{"displayName":"Reporter1"}'
# Create an event (use the slug you want)
curl -s -X POST http://localhost:3000/api/events -H "Content-Type: application/json" \
-d '{"title":"Bridge collapse in Lisbon","slug":"bridge-collapse-lisbon","description":"Ongoing coverage."}'
# Create a claim (replace EVENT_ID and USER_ID with IDs from above)
curl -s -X POST http://localhost:3000/api/claims -H "Content-Type: application/json" \
-d '{"eventId":"EVENT_ID","authorId":"USER_ID","content":"Three people were injured in the collapse.","status":"evidence_provided"}'Then open http://localhost:5173 and you should see the event and its timeline.
Contributors can log in via the header buttons. To enable OAuth:
- Google: Create a project in Google Cloud Console, enable the Google+ API (or Google Identity), create OAuth 2.0 credentials (Web application), and set the authorized redirect URI to
http://localhost:3000/api/auth/google/callback(or your backend URL in production). - Facebook: Create an app in Facebook for Developers, add Facebook Login, and set the valid OAuth redirect URI to
http://localhost:3000/api/auth/facebook/callback.
Set these in the backend environment (e.g. in backend/.env or docker-compose):
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_CALLBACK_URLFACEBOOK_APP_ID,FACEBOOK_APP_SECRET,FACEBOOK_CALLBACK_URLJWT_SECRET(min 32 chars in production),FRONTEND_URL(where to redirect after login, e.g.http://localhost:5173)
If these are not set, the app still runs; Google/Facebook login will fail until credentials are configured.
TrueStory.bro/
├── docker-compose.yml
├── backend/ # NestJS API
│ ├── src/
│ │ ├── events/
│ │ ├── claims/
│ │ ├── users/
│ │ ├── auth/ # Google/Facebook OAuth, JWT
│ │ ├── evidence/
│ │ ├── fact-checking/
│ │ └── predictions/
│ └── Dockerfile
└── frontend/ # React (Vite)
├── src/
└── Dockerfile