Emendator sends your code to three independent LLMs in parallel, merges their findings into a single high-confidence review, and gives you back a scored, annotated, and improved version of your code β through a clean, editor-grade web interface.
Emendator is a full-stack SaaS application that automates code review using a multi-model AI consensus pipeline. Instead of relying on a single LLM (which can hallucinate or miss issues), Emendator queries three different models simultaneously through OpenRouter, then runs their outputs through a custom consensus engine that deduplicates findings, resolves conflicting suggestions, and scores overall confidence β producing one trustworthy, well-reasoned review per submission.
Users can sign up (email/password, Google, or GitHub), paste or write code in a Monaco-powered editor, request a review, and receive:
- An overall quality score
- Categorized issues (bugs, security, performance, style)
- Concrete suggestions and line-level fixes
- An AI-improved version of the code with a side-by-side diff viewer
- A saved history of past reviews they can revisit or edit
βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββ
β React β βββΆ β Express β βββΆ β OpenRouter Review Pipeline β
β Frontend β HTTP β Backend β β β
β(Vite/Tailwind) β (REST API) β β ββββββββββ βββββββββββββ βββββββββββββ
βββββββββββββββ ββββββββ¬ββββββββ β β Gemma β β Nemotron β β GPT-OSS ββ
β β βββββ¬βββββ βββββββ¬ββββββ ββββββ¬βββββββ
βββββββββΌβββββββββ β βββββββββββββββΌβββββββββββββ β
β PostgreSQL β β (run in parallel) β
β via Prisma ORMβ β βΌ β
ββββββββββββββββββ β Consensus Engine (dedupe, β
β conflict resolution, scoring) β
βββββββββββββββββββββββββββββββββββββββββ
Step by step:
- Authentication β Users register/login with email + password (bcrypt-hashed, JWT access + refresh tokens in HTTP-only cookies) or via Google/GitHub OAuth.
- Submitting code β From the Review page, the user pastes code into a Monaco Editor and selects a language (18+ supported languages).
- Parallel AI dispatch β The backend fans the code out to three independent models at once via
Promise.allSettled, so total latency is bound by the slowest model, not the sum of all three. - Consensus building β The
consensus.engine.jsmodule:- Deduplicates overlapping findings using Levenshtein similarity (short strings) and trigram Jaccard similarity (longer strings)
- Detects and resolves conflicting recommendations, keeping the majority view
- Aggregates individual model scores into one confidence-weighted score
- Selects the strongest candidate for the "improved code" output
- Persistence β The final review (score, issues, suggestions, line fixes, improved code, metadata) is saved to PostgreSQL via Prisma, scoped to the authenticated user.
- Review & History UI β Results are rendered with a score ring, categorized issue cards, and a diff editor comparing original vs. AI-improved code. Past reviews are listed on the History page and can be reopened or edited.
- Resilience β If a model has no API key configured or fails, it's automatically excluded from the run (via
Promise.allSettled) rather than failing the whole request; rate limiting and caching protect the AI layer from abuse.
| Technology | Purpose |
|---|---|
| React 18 | UI library |
| Vite | Build tool / dev server |
| Tailwind CSS | Utility-first styling |
| Zustand | Lightweight state management (auth & review stores) |
| React Router DOM | Client-side routing & protected routes |
Monaco Editor (@monaco-editor/react) |
In-browser code editor + diff viewer |
| Axios | HTTP client |
| React Hot Toast | Toast notifications |
| Lucide React | Icon set |
| Technology | Purpose |
|---|---|
| Node.js + Express | REST API server |
| Prisma ORM | Type-safe database access & migrations |
| PostgreSQL | Primary data store (Users, Reviews) |
| JWT (jsonwebtoken) | Access + refresh token authentication |
| bcryptjs | Password hashing |
| Passport-style OAuth (Google & GitHub) | Social login |
| express-validator | Request payload validation |
| express-rate-limit | Global & AI-specific rate limiting |
| Helmet, CORS, cookie-parser, morgan | Security headers, cross-origin handling, request logging |
| Winston + winston-daily-rotate-file | Structured, rotating application logs |
| Technology | Purpose |
|---|---|
| OpenRouter API | Unified gateway to multiple LLMs |
| Gemma, Nemotron, GPT-OSS (via OpenRouter) | The three models queried in parallel for each review |
| Custom Consensus Engine | Deduplicates & merges multi-model output into one verdict |
| Confidence Scorer | Produces an aggregated confidence/quality score |
| In-memory Review Cache | Avoids re-querying models for identical code submissions |
| Technology | Purpose |
|---|---|
| Docker & Docker Compose | Containerized Postgres, backend, and frontend services |
| Nginx (frontend container) | Serves the built React app |
emendator/
βββ backend/
β βββ src/
β β βββ config/ # DB, logger, OAuth, OpenRouter/OpenAI config
β β βββ controllers/ # auth, review, history controllers
β β βββ middleware/ # auth, rate limiting, validation, error handling
β β βββ routes/ # /api/auth, /api/review, /api/history
β β βββ services/
β β β βββ openrouter/
β β β β βββ models/ # gemma, nemotron, gptoss clients
β β β β βββ consensus/ # multi-model consensus engine
β β β β βββ scoring/ # confidence scorer
β β β β βββ prompts/ # system/user prompt builders
β β β β βββ cache/ # review response cache
β β β βββ ai.service.js
β β β βββ auth.service.js
β β β βββ review.service.js
β β β βββ history.service.js
β β βββ utils/ # JWT helpers, response formatting
β βββ prisma/schema.prisma # User & Review data models
β
βββ frontend/
β βββ src/
β β βββ pages/ # Login, Signup, Dashboard, Review, History, Edit, OAuth callback
β β βββ components/ # CodeEditor, DiffEditor, ReviewResult, ScoreRing, Navigation, etc.
β β βββ store/ # Zustand auth & review stores
β β βββ api/ # Axios API clients
β
βββ docker-compose.yml # Postgres + backend + frontend orchestration
- Node.js 18+
- PostgreSQL 15 (or use the provided Docker service)
- OpenRouter API keys (free tier available at openrouter.ai)
- (Optional) Google & GitHub OAuth app credentials
git clone <your-repo-url>
cd emendator
cp .env.example .env # then fill in your own secrets β see note below
β οΈ Security note: Never commit real API keys, database passwords, JWT secrets, or OAuth client secrets to version control. Generate fresh, unique values forJWT_SECRET,JWT_REFRESH_SECRET,POSTGRES_PASSWORD, and your OpenRouter/Google/GitHub credentials, and keep your.envfile out of git (it's already listed in.gitignore).
docker compose up --buildThis starts:
postgreson:5432backend(Express API) on:5000frontend(Vite build served via Nginx) on:5173
# Backend
cd backend
npm install
npx prisma migrate dev
npm run dev # http://localhost:5000
# Frontend
cd frontend
npm install
npm run dev # http://localhost:5173| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register with email/password |
POST |
/api/auth/login |
Login and receive JWT tokens |
GET |
/api/auth/google, /api/auth/github |
Start OAuth flow |
GET |
/api/auth/me |
Get current authenticated user |
POST |
/api/review |
Submit code for multi-model AI review |
GET |
/api/review/:id |
Get a single review |
GET |
/api/history |
List a user's review history |
DELETE |
/api/history/:id |
Delete a review |
- User β id, email, name, password (nullable for OAuth users), avatar, OAuth provider/providerId, related
Review[] - Review β id, userId, code, language, score, issues, suggestions, lineFixes, improvedCode, metadata (JSON), timestamps
- Passwords hashed with bcrypt
- JWT access + refresh token rotation via HTTP-only cookies
- Helmet security headers & strict CORS policy
- Rate limiting on global traffic and separately on AI-heavy endpoints
- Input validation on every mutating route via express-validator
- Centralized error handling middleware
- The AI pipeline gracefully degrades: if one or two model API keys are missing or a model call fails, the review still completes using whichever models succeeded.
- Review results are cached in-memory to avoid redundant model calls for identical submissions.
cre.pyin the repo root is a developer utility script used to flatten the project into a single Markdown file (like the one this README was generated from) β it is not part of the running application.
Built with a Node.js/Express + React stack, PostgreSQL, and a multi-model AI consensus pipeline powered by OpenRouter.