Development
Local development setup and workflows for AsaHome Cloud.
Prerequisites
- Node.js 20+ (LTS recommended)
- npm 9+ or yarn 1.22+
- Docker and Docker Compose
- PostgreSQL 16+ (or use Docker)
- Git
Initial Setup
1. Clone Repository
git clone <repository-url>
cd asahome-cloud
2. Install Dependencies
npm install
3. Environment Configuration
# Copy example environment file
cp env.example .env
# Generate development JWT secret
echo "JWT_SECRET=$(openssl rand -base64 32)" >> .env
Edit .env for development:
NODE_ENV=development
PORT=3000
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE=asahome_cloud_dev
DB_SYNCHRONIZE=false
DB_LOGGING=true
# JWT
JWT_SECRET=your-development-secret
JWT_EXPIRES_IN=1h
JWT_REFRESH_EXPIRES_IN=7d
# CORS
CORS_ORIGINS=*
# Rate limiting (relaxed for development)
THROTTLE_TTL=60
THROTTLE_LIMIT=1000
4. Start Database
Using Docker (recommended):
docker run -d \
--name asahome-postgres-dev \
-p 5432:5432 \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=asahome_cloud_dev \
-v asahome_pg_data:/var/lib/postgresql/data \
postgres:16-alpine
Or use Docker Compose:
docker-compose up -d postgres
5. Run Migrations
npm run migration:run
6. Start Development Server
npm run start:dev
The API will be available at http://localhost:3000/api/v1
API Base URL: http://localhost:3000/api/v1
Makefile Commands
| Command | Description |
|---|---|
make setup | Initial project setup |
make dev | Start development environment |
make up | Start all containers |
make down | Stop all containers |
make logs | View all logs |
make logs-app | View application logs |
make health | Check service health |
make shell-db | Open PostgreSQL shell |
make shell-app | Open application shell |
make test | Run tests |
make lint | Run linter |
make format | Format code |
make clean | Remove containers and volumes |
npm Scripts
| Script | Description |
|---|---|
npm run start | Start production server |
npm run start:dev | Start with hot reload |
npm run start:debug | Start with debugging |
npm run build | Build for production |
npm run lint | Run ESLint |
npm run format | Format with Prettier |
npm test | Run unit tests |
npm run test:watch | Run tests in watch mode |
npm run test:cov | Run tests with coverage |
npm run test:e2e | Run e2e tests |
Database Migrations
Create New Migration
npm run migration:generate -- -n MigrationName
This creates a new migration file in src/migrations/.
Run Migrations
npm run migration:run
Revert Last Migration
npm run migration:revert
Show Migration Status
npm run migration:show
Migration Example
// src/migrations/1700000000000-AddDeviceMetadata.ts
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';
export class AddDeviceMetadata1700000000000 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.addColumn(
'devices',
new TableColumn({
name: 'metadata',
type: 'jsonb',
isNullable: true,
}),
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn('devices', 'metadata');
}
}
Git Workflow
Branch Strategy
main # Production branch (protected)
├── dev # Development branch
│ ├── feature/add-devices
│ ├── feature/websocket-auth
│ └── fix/token-refresh
Commit Messages
Follow conventional commits:
feat: add device registration endpoint
fix: correct token refresh logic
docs: update API documentation
refactor: simplify auth service
test: add device controller tests
chore: update dependencies
Pull Request Workflow
- Create feature branch from
dev - Make changes and commit
- Push and create PR to
dev - Get code review
- Merge to
dev - When ready, create PR from
devtomain
Code Style
ESLint Configuration
ESLint is configured in .eslintrc.js:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
},
};
Prettier Configuration
Prettier is configured in .prettierrc:
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"semi": true
}
Pre-commit Hooks
Husky and lint-staged are configured:
// package.json
{
"lint-staged": {
"*.ts": [
"eslint --fix",
"prettier --write"
]
}
}
Debugging
VS Code Configuration
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug NestJS",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "start:debug"],
"console": "integratedTerminal",
"restart": true,
"autoAttachChildProcesses": true
}
]
}
Debug with Chrome DevTools
npm run start:debug
Open chrome://inspect in Chrome and connect to the Node.js process.
Logging
Enable verbose logging in development:
# .env
DB_LOGGING=true
DEBUG=nest:*
Common Development Tasks
Add New Module
# Generate module
npx nest g module feature-name
# Generate controller
npx nest g controller feature-name
# Generate service
npx nest g service feature-name
Add New Entity
- Create entity file:
// src/feature-name/entities/feature.entity.ts
@Entity('features')
export class Feature {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@CreateDateColumn()
createdAt: Date;
}
- Add to module:
@Module({
imports: [TypeOrmModule.forFeature([Feature])],
})
export class FeatureModule {}
- Generate migration:
npm run migration:generate -- -n AddFeature
npm run migration:run
Test API Endpoints
Use Postman or curl to test endpoints:
# Login
curl -X POST http://localhost:3000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "password123"}'
# Use token for authenticated requests
curl -X GET http://localhost:3000/api/v1/users/me \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Troubleshooting
Port Already in Use
# Find process using port
lsof -i :3000
# Kill process
kill -9 <PID>
Database Connection Issues
# Check if PostgreSQL is running
docker ps | grep postgres
# View database logs
docker logs asahome-postgres-dev
# Restart database
docker restart asahome-postgres-dev
Module Not Found
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Clear NestJS cache
rm -rf dist
npm run build
Migration Errors
# Check migration status
npm run migration:show
# Revert and rerun
npm run migration:revert
npm run migration:run