Conduit Backend (RealWorld)
A RealWorld / Conduit backend implemented in TypeScript + Express + Prisma/PostgreSQL, following a layered (ports & adapters) architecture:
routes → services → repositories → Prisma/PostgreSQL
- Routes (driving adapters): validate input with Zod and delegate to services. They never call
prisma.directly. - Services: business logic and orchestration. Depend on repositories.
- Repositories (driven adapters): the only layer that touches Prisma.
Setup
npm install
cp .env.example .env # set DATABASE_URL, JWT_SECRET, PORT
npm run prisma:generate
npm run prisma:migrate
npm run dev
Endpoints
Auth / User
POST /api/users— registerPOST /api/users/login— loginGET /api/user— current user (auth)PUT /api/user— update user (auth)
Profiles
GET /api/profiles/:usernamePOST /api/profiles/:username/follow(auth)DELETE /api/profiles/:username/follow(auth)
Articles
GET /api/articles— list (filters: tag, author, favorited; limit/offset)GET /api/articles/feed(auth)GET /api/articles/:slugPOST /api/articles(auth)PUT /api/articles/:slug(auth, author only)DELETE /api/articles/:slug(auth, author only)POST /api/articles/:slug/favorite(auth)DELETE /api/articles/:slug/favorite(auth)
Comments
GET /api/articles/:slug/commentsPOST /api/articles/:slug/comments(auth)DELETE /api/articles/:slug/comments/:id(auth, author only)
Tags
GET /api/tags
Errors
All errors use the RealWorld format:
{ "errors": { "body": ["message"] } }
Validation failures return HTTP 422, missing/invalid auth 401, forbidden 403, and not-found 404.
Tests
npm test # run unit + integration suites
npm run test:coverage # with coverage (threshold: 80% lines)
Integration tests run with Supertest against a real PostgreSQL test database (set DATABASE_URL to a disposable test database before running).