A courses-management project: an Express + TypeScript REST API (server/) with a Bruno API collection (bruno/) for manual testing, plus GitHub Actions CI/CD and AI tooling.
Try the deployed API in your browser with the interactive docs page:
- Docs page: https://mohamedemary.github.io/courses-app/
- Live API base URL:
https://courses-app-zffh.onrender.com/api
The docs page runs requests against the deployed API. Recommended flow:
- Run
Login(orRegister) to get an access token. - Run
Add Courseto create a course. Get,Update, andDelete Course, plus the user endpoints, then use that course and user.
The page is generated from the bruno/ collection.
server/: the deployable Express 5 + TypeScript REST API (Mongoose, Zod, JWT + argon2, Multer). Setup, env vars, scripts, and the API reference live inserver/README.md.bruno/: Bruno API collection (OpenCollection YAML) for exercising the API. Conventions inbruno/AGENTS.md.index.html: the generated API-docs page (inline copy of the Bruno collection), served via GitHub Pages..github/workflows/: GitHub Actions.pr.yml(PR checks),quality.yml(reusable: lint → typecheck → test → build),deploy.yml(merge tomain→ quality + Render deploy), andopencode.yml(AI agent you trigger by commenting; maintainers only)..agents/skills/: AI skills for this project, usable by any AI agent (bruno-collection-generator,node,code-review,grill-me+ deps).AGENTS.md: guidance for AI agents working in this repo (alsoserver/AGENTS.mdandbruno/AGENTS.md).
flowchart LR
subgraph repo["courses-app"]
API["server/ (Express API)"] --> SREADME["server/README.md"]
BR["bruno/ (API collection)"] --> BAGENTS["bruno/AGENTS.md"]
CI[".github/workflows/"] --> PR["pr.yml"] & Q["quality.yml"] & DEP["deploy.yml"] & OC["opencode.yml"]
SK[".agents/skills/"]
end
flowchart TD
Client([Client / Browser / Bruno])
subgraph Entry ["App Entry"]
Main["main.ts<br/>(Bootstrap & Listen)"]
App["app.ts<br/>(createApp & Global Middleware)"]
end
subgraph Middleware ["Global Middleware"]
CORS["cors"]
JSON["express.json"]
Cookie["cookieParser"]
Static["express.static (/uploads)"]
end
subgraph Routing ["Routes (/api)"]
RAuth["/auth (auth.route.ts)"]
RCourse["/course (courses.route.ts)"]
RUser["/users (users.route.ts)"]
end
subgraph Guards ["Route Guards & Validation"]
V["validateRequest (Zod)"]
A["requireAuth (JWT Access)"]
Role["requireRole (admin)"]
end
subgraph Controllers ["Controllers"]
CAuth["auth.controller.ts"]
CCourse["courses.controller.ts"]
CUser["users.controller.ts"]
end
subgraph DataLayer ["Data & Errors"]
DB[("MongoDB (Mongoose)")]
Err["errorHandler (JSend)"]
end
Client -->|HTTP Request| Main --> App
App --> Middleware --> Routing
RAuth --> V --> CAuth
RCourse --> A --> Role --> V --> CCourse
RUser --> A --> Role --> V --> CUser
CAuth & CCourse & CUser --> DB
CAuth & CCourse & CUser -.->|Throws AppError| Err
Err -->|JSend Response| Client
cd server
pnpm install
cp .env.example .env # fill in the values
docker compose up -d # start local MongoDB
pnpm dev # http://localhost:3000Full instructions, env vars, tests, build/deploy, and the API reference are in server/README.md.
- Pull requests →
quality.yml: lint → typecheck → test → build. - Merge to
main→ quality again, then trigger the Render deploy hook (deploy.yml). - OpenCode agent → post a comment containing
/opencodeor/ocon an issue or PR review (maintainers only); it analyzes the repo and replies. SeeAGENTS.md.
Read AGENTS.md for guidance; project skills live in .agents/skills/.