REST API for the Daily Planner app - built with NestJS, TypeORM, and MySQL. Manages tasks, goals, notes, and hourly schedule entries, each scoped to a calendar date.
Daily Planner API is a backend-only project built with NestJS, demonstrating clean module separation, typed data validation, and database-agnostic persistence through an ORM.
What it demonstrates
- NestJS modular architecture: Four independent feature modules (
task,goal,note,schedule) each own their entity, DTO, service, and controller - no cross-module coupling. Adding a fifth resource follows the exact same structure. - Input validation with class-validator: Every incoming request body is validated by a DTO before reaching the service layer. Required fields, type constraints, and value ranges (
@Min(1)/@Max(5)on goal priority) are declared declaratively with decorators. - Safe partial updates: The
updatemethods build an explicitPartial<Entity>from only the fields present in the request, so a PUT that omits an optional field never accidentally clears it. - TypeORM + MySQL: Entities map directly to database tables via decorators.
autoLoadEntitiesmeans no manual entity list - each module registers its own entity viaTypeOrmModule.forFeature(). - Swagger UI: The OpenAPI spec is auto-generated from the code and exposed at
/apifor interactive endpoint testing without any separate HTTP client. - Docker Compose: A
compose.yamlspins up the app and a MySQL instance together - zero local setup required. - Environment-driven config: All secrets (DB host, credentials, port) come from
.envvia@nestjs/config; nothing is hardcoded.
Stack: NestJS · TypeScript · TypeORM · MySQL 8 · Swagger · Docker Compose
src/
├── task/
│ ├── dto/task.dto.ts # Input validation (CreateTaskDto, UpdateTaskDto)
│ ├── task.controller.ts # REST endpoints (POST / GET / PUT / DELETE)
│ ├── task.entity.ts # TypeORM entity → tasks table
│ ├── task.module.ts # Module wiring
│ └── task.service.ts # Business logic & DB access
├── goal/ # Same structure as task/
├── note/ # Same structure as task/
├── schedule/ # Same structure as task/
├── app.module.ts # Root module - TypeORM + ConfigModule setup
└── main.ts # Bootstrap, CORS, Swagger
Each resource follows the same layered pattern:
| Layer | File | Responsibility |
|---|---|---|
| Controller | *.controller.ts |
HTTP routing, 404 handling, parameter parsing |
| Service | *.service.ts |
Business rules, partial-update logic, DB calls |
| Entity | *.entity.ts |
Table schema declared with TypeORM decorators |
| DTO | dto/*.dto.ts |
Request body shape and validation rules |
All resources expose the same five operations:
| Method | Path | Description |
|---|---|---|
POST |
/tasks |
Create a task |
GET |
/tasks |
List all tasks (add ?date=YYYY-MM-DD to filter by day) |
GET |
/tasks/:id |
Get one task (404 if missing) |
PUT |
/tasks/:id |
Partial update - omitted fields are not cleared |
DELETE |
/tasks/:id |
Delete a task |
Replace /tasks with /goals, /notes, or /schedules for the other resources. All four follow the same contract.
The GET /health endpoint is available as a liveness probe (returns { status, timestamp, uptime }).
Interactive docs are available at http://localhost:3000/api once the app is running (Swagger UI).
git clone https://github.com/Yan739/daily-planner-api.git
cd daily-planner-api
cp .env.example .env # fill in your values, or leave the defaults for local dev
docker compose upThe API starts at http://localhost:3000. MySQL is provisioned automatically.
Prerequisites: Node 20+, MySQL 8 running locally.
git clone https://github.com/Yan739/daily-planner-api.git
cd daily-planner-api
npm install
cp .env.example .env # set DB_HOST, DB_PORT, DB_USER, DB_PASS, DB_NAME
npm run start:dev| Variable | Description | Default |
|---|---|---|
DB_HOST |
MySQL hostname | localhost |
DB_PORT |
MySQL port | 3306 |
DB_USER |
Database user | - |
DB_PASS |
Database password | - |
DB_NAME |
Database name | - |
npm run test # unit tests (Jest)
npm run test:cov # with coverage report
npm run test:e2e # end-to-end tests