Repository navigation
Faculties API
Read-only faculty catalog. Status: current. Part of the API Catalog.
All three routes require a session; anonymous callers get 401 unauthorized before the handler
runs (see Authentication).
| Status | Method | Path | Description |
|---|---|---|---|
| ✅ | GET |
/v1/faculties |
All faculties, ordered by acronym |
| ✅ | GET |
/v1/faculties/:acronym |
One faculty |
| ✅ | GET |
/v1/faculties/:acronym/courses |
Courses offered by a faculty; optional ?year=
|
A faculty is identified by its acronym (FEUP, FCUP), not a numeric id.
GET /v1/faculties
→ 200 [
{ "acronym": "FCUP", "name": "Faculdade de Ciências" },
{ "acronym": "FEUP", "name": "Faculdade de Engenharia" }
]- Ordered by
acronymascending. -
namecan benullif SIGARRA did not provide one. - An empty catalog answers
[], not404.
Faculty
{ "acronym": "FEUP", "name": "Faculdade de Engenharia da Universidade do Porto" }GET /v1/faculties/FEUP
→ 200 { "acronym": "FEUP", "name": "…" }| Status | code |
When |
|---|---|---|
200 |
— | Found |
401 |
unauthorized |
No session |
404 |
faculty-not-found |
The acronym does not exist |
422 |
validation-error |
The path is malformed |
The acronym is compared exactly — feup does not match FEUP.
GET /v1/faculties/FEUP/courses?year=2025
→ 200 [Course]| Query | Required | Notes |
|---|---|---|
year |
no | Academic year as an integer (2025) |
| Status | code |
When |
|---|---|---|
200 |
— | Courses, or [] if the faculty offers none |
401 |
unauthorized |
No session |
404 |
faculty-not-found |
The acronym does not exist |
422 |
validation-error |
?year=abc or a malformed path |
The faculty is checked first. An unknown acronym is a 404; a known faculty with no matching
courses is a 200 []. This is deliberately stricter than GET /v1/courses?faculty=…, which treats
an unknown faculty as "matches nothing".
Course is the shared catalog shape — see Courses API.
| Concern | File |
|---|---|
| Routes | apps/backend/src/interface/routes/faculties.routes.ts |
| Response schema | apps/backend/src/interface/routes/catalog.schemas.ts |
| Port | apps/backend/src/domain/ports/faculty.repository.ts |
| Prisma repository | apps/backend/src/infrastructure/database/repositories/prisma-faculty.repository.ts |
| Tests | apps/backend/tests/interface/routes/catalog/faculties.test.ts |
The route mounts createRequiredAuthMiddleware, registers the ApiError model locally, and throws
HttpError('faculty-not-found', …, 404). The repository reads Faculty and, for the courses route,
the explicit FacultyCourse join.
-
Courses API — the
Courseshape and its filters - Glossary — faculty vs course
- API Catalog — conventions and error contract
Last verified: 2026-10-27
- Local setup
- Environment variables
- Auth in development
- Troubleshooting
- Newcomer workshop
- Overview
- Backend layers
- Request lifecycle
- Frontend architecture
- Auth & sessions
- Domain model
- SIGARRA SDK
- Real-time collaboration
- API Catalog
- Adding an endpoint
- Auth
- Faculties
- Courses
- Course units
- Planned endpoints
- Legacy route map
- Environments
- CI
- Deployment
- Monitoring
- Runbooks
- Decision records (ADRs)
README · Contributing · Issues · Roadmap
Italic pages are planned; they become links when written.