Simple API + demo frontend inspired by Undertale.
- Backend: Node.js + Express + MongoDB (Mongoose)
- Auth: JWT
- Frontend: static
- User registration/login
- Player creation and retrieval (per authenticated user)
- Public read-only monster catalog
- Game lifecycle endpoints (
create,attack,move) - Aggregate authenticated overview (
players + monsters)
The frontend in /public is a demo client that consumes these endpoints.
all of this lives in project-root/ btw:
server.js: app bootstrap, middleware, route mountingroutes/: route definitionscontrollers/: request handlingservices/: game/business logicrepositories/: DB access abstractionmodels/: Mongoose schemasutils/: helpers (jwt,serializer,generateId, etc.)public/: demo frontend
From project-root/:
docker compose up --buildServices:
- API:
http://localhost:3000/api - Frontend:
http://localhost:8100 - dbgate:
http://localhost:8081
modify the example .env:
Protected endpoints require header:
Authorization: Bearer <token>Token comes from:
POST /api/auth/registerPOST /api/auth/login
If missing/invalid, API returns 401.
Base URL: /api
-
POST /auth/register- Body:
{ "username": "...", "email": "...", "password": "..." } - Success:
{ token, user }
- Body:
-
POST /auth/login- Body:
{ "username": "...", "password": "..." } - Success:
{ token, user }
- Body:
-
GET /monsters- Success:
{ "count": number, "monsters": [...] }
- Success:
-
GET /monsters/:id- Supports either custom
idor Mongo_id-compatible values
- Supports either custom
GET /playersGET /players/meGET /players/:idPOST /players- Body:
{ "name": "..." }
- Body:
POST /games- Body:
{ "playerId": "..." }
- Body:
POST /games/:id/attack- Body (optional):
{ "action": "fight|mercy", "timingScore": 0..1, "dodgeScore": 0..1 }
- Body (optional):
POST /games/:id/move
GET /overview- Returns
{ players, monsters }
- Returns