hackx

Backend From Zero

3 / 35

Folders you can explain out loud

If a teammate asks "where does login live?" you should be able to say src/routes/auth.ts without opening Google.

Finished example (compare later, type first): https://github.com/sreecharan-desu/club-portal-backend

"type": "module". Our files import .ts. Generated Prisma imports .js. Config sits in src/ because TypeScript rootDir is src. Prisma schema paths are from the repo root — so we never pass --config.

Mail is SES SendEmail only. No MailDev. No Nodemailer.

club-portal-backend/
├── .github/workflows/blank.yml
├── prisma/schema.prisma
├── src/
│   ├── config.ts              required env. process dies if a secret is missing
│   ├── app.ts                 cors, json, plug in routers
│   ├── server.ts              listen on 0.0.0.0
│   ├── db.ts                  one PrismaClient for the whole app
│   ├── mail.ts                SES. that's the whole mail story
│   ├── prisma.config.ts
│   ├── middleware/auth.ts     "got a Bearer token?"
│   └── routes/
│       ├── health.ts          GET /health — never opens Neon
│       ├── auth.ts            register, login, verify, forgot, reset
│       ├── me.ts              GET /me
│       ├── chat.ts            POST /chat
│       └── ask.ts             POST /ask
├── package.json               prisma + client both 6.12.0
└── .env                       never git. laptop copy AND box copy

Say it in one breath: config, then app, then listen. Each URL family is one file.

MethodPathNeed a login?
GET/healthno. { shipped: "v3" }
POST/auth/registerno
GET/auth/verifyno
POST/auth/loginno
POST/auth/forgot-passwordno
POST/auth/reset-passwordno. copy the token from mail — the link is not a webpage
GET/meyes
POST/chatyes — members room
POST/askyes — same stub, answer + sources

Why two chat URLs? One sentence for the club, one sentence for a hackathon brief. Same process. Same lock. Same "RAG later" JSON.