Developer Onboarding — HMP IoT Platform
Welcome. This guide gets you from zero to a running development environment in under 15 minutes.
1. What This Project Is
HMP IoT Platform is a multi-tenant aquaculture monitoring and management system for the Vietnamese market (fish/shrimp farming). It connects IoT sensors to business operations — tracking water quality, growth data, farming cycles, inventory, financials, and more.
Monorepo: Bun workspaces
Backend: NestJS + PostgreSQL + Redis + MQTT + TypeORM
Frontend: React 19 + Vite + Ant Design + TanStack Query + Zustand
Firmware: ESP32 with PlatformIO (gateway firmware)
2. Prerequisites
| Tool | Version | Install |
|---|---|---|
| Bun | latest | curl -fsSL https://bun.sh/install | bash |
| Docker + Docker Compose | v2+ | Docker Desktop or engine |
| Git | any | — |
| Make | any | macOS: Xcode CLI tools; Linux: build-essential |
| (Optional) PlatformIO CLI | latest | Only if working on gateway_firmware/ |
Verify:
bun --version # should be 1.2+
docker compose version
make --version
git --version
3. First-Time Setup
3.1 Clone and Install
git clone <repo-url>
cd iot_platform
bun install
Important: This repo uses Bun exclusively. Do not use
npm installoryarn.
3.2 Environment Files
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
Default values are pre-configured to work with Docker infrastructure services. You typically do not need to change them for local development.
3.3 Database Migrations
bun run migrate
This creates tables and seeds initial data (users, roles, organizations).
4. Running the Development Environment
Quick Start (Recommended)
make dev
This command:
- Installs dependencies
- Starts infrastructure containers (PostgreSQL, Redis) in detached mode
Then, in separate terminals, start the app processes:
make backend-dev # Runs the backend (bun run backend:dev)
make frontend-dev # Runs the frontend (bun run frontend:dev)
Press Ctrl+C in each terminal to stop the backend and frontend. Run make dev-stop to also tear down infrastructure containers.
Services & Access
| Service | URL | Credentials |
|---|---|---|
| Frontend App | http://localhost:5173 | — |
| Backend API | http://localhost:3000/api/v1 | — |
| Swagger Docs | http://localhost:3000/api | — |
Device messaging runs through ThingsBoard, which runs as a separate service (not bundled in the infra compose). See
thingsboard-setup.md.
Demo Login Accounts
| Role | Password | |
|---|---|---|
| Super Admin | superadmin@hmpiot.com | Demo@123456 |
| Admin | admin@bentre-shrimp.vn | Demo@123456 |
| Owner | owner1@bentre-shrimp.vn | Demo@123456 |
Other Useful Commands
make dev-infra # Start only infrastructure containers
make dev-stop # Stop and remove all infrastructure containers
make backend-dev # Run the backend dev server natively
make frontend-dev # Run the frontend dev server natively
docker compose logs -f postgres # Tail PostgreSQL logs
5. Development Workflow
5.1 Daily Commands
# Start working
make dev
make backend-dev # In its own terminal
make frontend-dev # In its own terminal
# In another terminal — run tests
make backend-test # All backend tests
make backend-test FILE=src/devices/devices.service.spec.ts
make frontend-test # All frontend tests
# Code quality
make lint # Biome lint check
bun run check # Lint + build + format check
make build # Production build
5.2 Commit Workflow
- Create a feature branch:
git checkout -b feature/my-feature - Write code following conventions below
- Run tests:
make test - Run lint:
make lint - Commit and push
6. Architecture at a Glance
High-Level Structure
iot_platform/
├── backend/ # NestJS API (port 3000)
├── frontend/ # React SPA (port 5173)
├── gateway_firmware/ # ESP32 firmware (PlatformIO)
├── docs-website/ # Documentation site
├── mobile/ # Flutter app (out of scope unless asked)
├── docker/ # Dev Dockerfiles
└── deploy/ # Native deploy: scripts, Caddyfile, pm2 ecosystem config
Two Architecture Rules to Never Forget
- Multi-tenancy is fundamental. Nearly every business entity is scoped by
organizationId. The backend enforces this automatically via interceptors. - Authorization is not just route guards. Permission parsing, read-scope enforcement, and query filtering all participate in access control.
Backend Module Map
Entry point: backend/src/app.module.ts
Key modules:
auth/— JWT login, refresh tokens, password resetrbac/— Role-based access control, permissions, read scopesusers/,organizations/,roles/— Identity managementfarm/— Farms, areas, pondsaquaculture/— Species, farming cycles, daily logs, growth recordsdevices/,mqtt/,telemetry/— IoT device registry, messaging, datadashboard/— Aggregated role-specific dashboardsinventory/,suppliers/— Stock managementfinancial/,reports/— Costs, revenue, reportingautomation/— Rule-based telemetry triggers and actionsnotifications/,websocket/,redis/— Realtime infrastructure
Frontend Structure
Entry point: frontend/src/App.tsx
pages/— Route-level page componentscomponents/— Reusable UI pieceshooks/— TanStack Query hooks and data accessservices/— API client helperslib/— Permissions, formatting, utilitiesroutes/— Route guards (ProtectedRoute,PermissionRoute)
7. Conventions & Non-Negotiable Rules
Read AGENTS.md for the full rules. Key highlights:
| Rule | Detail |
|---|---|
| Package Manager | Bun only. Never npm or yarn. |
| Lint/Format | Biome only. Never ESLint or Prettier directly. |
| Imports | Use @/ aliases. No relative imports like ../. |
| TypeScript | Never use any. |
| Testing | Follow TDD. Write tests before or with implementation. |
| Code Style | SOLID principles. Small, focused changes. |
| Backend DTOs | Use class-validator decorators. |
| Database | snake_case column names in entities. |
| Frontend State | TanStack Query for server state, Zustand for light client-global state. |
File Organization
- Backend tests live next to source files:
*.spec.ts - Frontend tests:
*.spec.tsx - Backend DTOs:
[name].dto.ts - Backend entities:
[name].entity.ts
8. Testing
Never run
bun test— it invokes Bun’s own runner and bypasses Jest/Vitest. Use the Makefile targets or workspacebun run test.
Backend (Jest)
make backend-test # All backend tests
make backend-test FILE=src/devices/devices.service.spec.ts # Single file
cd backend && bun run test:e2e # E2E tests
Frontend (Vitest)
make frontend-test # All frontend tests
make frontend-test FILE=src/pages/dashboard/SomePage.spec.tsx # Single file
Test-Rich Areas to Study
backend/src/devices/system-device-inventory.service.spec.tsbackend/src/auth/backend/src/inventory/backend/src/mqtt/frontend/src/pages/dashboard/frontend/src/pages/system-devices/
9. Common First Tasks
To get familiar with the codebase, try these in order:
- Log in with the demo accounts and explore the dashboard.
- Read
frontend/src/App.tsxto understand the route tree. - Read
backend/src/app.module.tsto see domain boundaries. - Pick a simple entity (e.g.,
backend/src/farm/entities/pond.entity.ts) and trace it through controller → service → entity. - Add a small feature like a new column to a DTO/entity and see it flow end-to-end.
10. Troubleshooting
| Issue | Fix |
|---|---|
bun install fails |
Ensure Bun is latest: bun upgrade |
| Database connection refused | Run make dev-infra first to start PostgreSQL |
| Port already in use | Check if another make backend-dev/make frontend-dev is running, or kill processes on ports 3000/5173/5432/6379 |
| Migrations fail | Ensure backend/.env exists and DATABASE_URL is correct |
| ThingsBoard not reachable | Ensure the ThingsBoard service is running and THINGSBOARD_BASE_URL in backend/.env is correct (see thingsboard-setup.md) |
| Lint errors | Run bun run lint:fix in the affected workspace |
11. Key Documents
| Document | Purpose |
|---|---|
../CODEBASE_MAP.md |
Architecture overview, entry points, hotspots |
../AGENTS.md |
Coding rules, tooling workflow, verification requirements |
../README.md |
Build and deployment procedures |
../deploy/README.md |
Native production deployment runbook |
thingsboard-setup.md |
ThingsBoard infrastructure configuration |
12. Getting Help
- Check
CODEBASE_MAP.mdfor subsystem entry points. - Ask an AI assistant to explore the codebase — they can query relationships, callers, and tests directly.
Next step: Run make dev, then make backend-dev and make frontend-dev in separate terminals, log in at http://localhost:5173, and explore.