E-Campus is a university platform. It runs a university's whole academic operation (admissions, institutional hierarchy, course catalogue, enrolment, teaching, grading, announcements, and the permanent student record) for students, teaching staff, and administrators, behind one account and one API.
This repository is the Go server behind it. It replaces the handful of disconnected tools most institutions run with one system: one process, one PostgreSQL database, one deployment per institution.
internal/ is split into nine bounded contexts, so the directory listing reads like the product.
| Context | Owns |
|---|---|
identity |
user accounts, credentials, sessions, roles, staff profiles, preferences |
authz |
the decision engine: who may do what, checked before any handler runs |
subscription |
the institution's plan, tiers, and resource limits |
management |
hierarchy, calendar, catalogue, admissions, enrolment, students and their history |
classroom |
what happens inside a course: materials, assignments, exams, attendance, grading, Q&A |
announcements |
university-wide posts and the personalised activity feed |
communication |
notifications and mutes |
files |
content-addressed file storage |
shared |
infrastructure only: config, logger, middleware, pagination |
- Modular monolith. One binary, one database, deployed as a unit. It is single-tenant: one deployment serves one institution. The internal boundaries are real enough to split a context out into its own service later, but a university's load never needs it. (architecture.md, decisions/0001)
- Hexagonal, with a flat core. Each context is a pure domain in the middle with adapters (
http/,postgres/,minio/) around it. One rule holds it together: a domain package imports only the standard library,uuid, and small shared helpers, and never a web framework, a database driver, or another context. (decisions/0002) - Functional core, imperative shell. Business rules are pure functions a test can run with no database; services orchestrate them around the database.
- Correctness lives in the schema. Foreign keys, check constraints, and unique indexes mean a bug in the code cannot write a record the database forbids.
Four things a reviewer usually asks about, each with the full write-up one click away.
- Authorization. A policy engine runs before every handler and checks two kinds of authority: a staff member's role (how much power, over how much of the institution, in which function) and a person's seat in a course (teacher, assistant, student, or observer). It fails closed, and a startup check proves no route was left unguarded. → docs/access-control.md
- The academic record is permanent. Grades are never edited or deleted; a correction is a new entry, and term results are computed from the underlying grades rather than stored by hand and kept in sync. → decisions/0004
- Files are content-addressed. Every attachment is a counted reference to stored bytes, so the same file is never stored twice and nothing is deleted while something still points at it. → decisions/0007
- The API is resource-oriented. URLs name resources, and anything that is not standard CRUD is a named action, like
POST /students/:id:activate. There are three surfaces (public, authenticated, admin), with short-lived access tokens and rotating refresh cookies. → docs/api.md
The server needs Go, PostgreSQL, Redis, and an S3-compatible store (MinIO locally). Configuration is read from the environment, and the justfile holds the commands:
just devruns the server against a local database.just migrate-upapplies the migrations.just test-raceruns the tests under the race detector.just docopens the package reference in a browser, a local pkg.go.dev for this module.
Full setup, and how to deploy or swap the database and storage for managed services, is in docs/deployment.md.
The docs/ tree explains the system in depth. Read it in this order; each page builds on the last.
- access-control.md: who may do what, and how it is decided.
- data-model.md: the nouns of the system and how they relate.
- architecture.md: the shape, the dependency graph, and one request traced end to end.
- docs/: the full set, including the API and schema contracts, the lifecycles, one page per context, and the decision records.
For the code-level reference (every package, type, and function, with runnable examples), run just doc to browse it locally like pkg.go.dev.
To make a change, start with docs/CONTRIBUTING.md and the code conventions in docs/conventions.md.
Cited where they are used: Google's API Improvement Proposals (the API), AWS IAM (authorization over a single role column), Google Classroom (the course model), and the Unix inode (the file model).