Getting Started¶
This chapter is for developers joining the SIS backend. Start with REFERENCE.md to locate the domain you are changing and read the repository's agent instructions before asking an agent to edit it.
1. Stack and entry points¶
The backend is a NestJS 11 application using TypeScript, Prisma 7 with the PostgreSQL driver adapter, and PostgreSQL. Node.js 24 is required by package.json engines.node, which CI and Railway also use to choose the Node version; use the lockfile for exact dependency versions. TypeScript targets ES2023 with NodeNext module resolution. Jest and Supertest cover unit and HTTP behavior.
| Path | Purpose |
|---|---|
src/main.ts |
HTTP bootstrap, validation, CORS, API documentation, startup invariants |
src/app.module.ts |
Module composition, global guards and tenant transaction interceptor |
src/common/ |
Shared contracts, CRUD base service, errors and temporal primitives |
src/prisma/ |
Runtime and administrative clients, RLS coverage and tenant helpers |
src/auth/, src/permissions/ |
Authentication, session context and authorization |
src/<domain>/ |
Controllers, services, query functions, DTOs and unit specs |
prisma/schema.prisma, prisma/migrations/ |
Database model and ordered SQL migrations |
src/generated/prisma/ |
Generated client; never edit by hand |
test/ |
E2E configuration, database provisioning, fixtures and HTTP specs |
backoffice/ |
Embedded internal React application |
solver/ |
Python timetable generation service |
The complete domain map belongs in REFERENCE.md, rather than a second module inventory here.
2. Local setup¶
Install Node.js and Docker, then install the locked dependencies. These commands are instructions for a developer; agents run setup, migrations and verification only when authorized under the repository workflow.
Edit .env before starting the application:
- Keep
DATABASE_URLas the owner connection for migrations and tooling. SetAPP_DATABASE_URLto the restrictedapp_userconnection used by the application. - Use
NODE_ENV=localand a local JWT secret. SetMAIL_TRANSPORT=logto avoid requiring real Resend credentials; the template contains provider placeholders. - Configure the
S3_*values for your local bucket.S3_ENDPOINTmust reach the MinIO API port published by Docker, and the bucket must exist or local auto-creation must be enabled. Check the container listener and host mapping together when diagnosing connectivity. - Keep
PUSH_TRANSPORT=logunless deliberately configuring Firebase delivery.
Read migration safety before running migration commands. For a local development database:
db:setup starts Docker Compose, runs prisma migrate dev, and provisions the application database role. Prisma client generation is a separate step. Seed behavior depends on the environment; see seeding.
Docker Compose defines PostgreSQL and MinIO. NestJS runs on the host, with port 8080 as its default. The API prefix is /api/v1. Health routes are /api/v1/health/live and /api/v1/health/ready. In local mode, Swagger is at /docs and Scalar at /reference.
3. Request lifecycle¶
An authenticated domain request passes through authentication and permission guards, then the tenant transaction interceptor. DTO validation and the controller/service execute inside that request boundary; query helpers use the tenant-scoped Prisma connection. Response filtering strips fields the session cannot read. External side effects registered for post-commit run only after the transaction succeeds.
Read multitenancy, permissions, and CRUD patterns when changing those boundaries. Public, administrative and background flows have explicit transaction rules of their own.
4. Commands¶
package.json is the command authority.
| Command | Effect |
|---|---|
npm run start:dev |
NestJS with hot reload |
npm run build |
Install/build the backoffice, generate Prisma client, compile NestJS |
npm run lint |
ESLint with automatic fixes |
npm run format |
Format TypeScript under src/ and test/ |
npm test |
Unit specs |
npm run test:e2e |
E2E runner with its database provisioning lifecycle |
npm run test:e2e:scale |
Dedicated scale runner |
npm run test:cov |
Unit coverage |
npx prisma generate |
Regenerate the Prisma client |
npx prisma migrate dev |
Create/apply local development migrations |
npx prisma db seed |
Run the environment-aware seed |
npm run db:provision-app-role |
Provision the restricted runtime database role |
npm run docker:up / docker:down |
Start/stop Compose services |
npm run docker:reset |
Destroy Compose volumes, restart, provision the role, migrate, provision again and seed |
docker:reset destroys local database and storage volumes. It is not an ordinary startup command and does not need a second migrate dev appended to it.
5. Prisma and the first change¶
prisma.config.ts supplies the CLI datasource URL and seed command. Application services inject PrismaService; they do not instantiate PrismaClient. Import generated model types with import type, keep domain queries in their owning query files, and parameterize raw SQL with Prisma's tagged templates.
Choose an existing implementation from REFERENCE.md, read its chapter, and follow the workflow recipes. Keep tenant, academic-year, record-access and field-access rules intact. Update the handbook only when implemented behavior or a durable development rule changes; progress and release notes do not belong in numbered chapters.