Code Standards

1. Overview

This document defines the coding standards and conventions for the HMP IoT Platform project.


2. Technology Stack

2.1 File Size Guidelines

Keep individual code files under 200 lines for optimal context management:

  • Split large files into smaller, focused components/modules
  • Use composition over inheritance for complex widgets
  • Extract utility functions into separate modules
  • Create dedicated service classes for business logic

Layer Technology
Monorepo Bun workspaces
Package Manager Bun (NEVER npm/yarn)
Linter/Formatter Biome (NOT ESLint/Prettier)
Backend NestJS, TypeScript
Frontend React 19, Vite
UI Libraries Ant Design, Tailwind CSS, Recharts
Database PostgreSQL + TimescaleDB, TypeORM
Cache Redis
MQTT EMQX

3. TypeScript Guidelines

3.1 Type Safety

  • NEVER use any - Use unknown, proper types, or generics
  • Enable strict mode in tsconfig.json
  • Define interfaces for all API responses

3.2 Naming Conventions

Type Convention Example
Files kebab-case create-user.dto.ts
Classes/Interfaces PascalCase UserService
Variables/Functions camelCase userId
Database tables snake_case (plural) users
Database columns snake_case created_at

3.3 Import Rules

// CORRECT - Using alias
import { UserService } from '@/users/user.service';
import { CreateUserDto } from '@/users/dto/create-user.dto';

// WRONG - Relative paths
import { UserService } from '../users/user.service';

4. NestJS Backend Standards

4.1 Module Structure

Each module follows this pattern:

module/
├── dto/
│   ├── create-xxx.dto.ts
│   ├── update-xxx.dto.ts
│   └── xxx-response.dto.ts
├── entities/
│   └── xxx.entity.ts
├── controllers/
│   └── xxx.controller.ts
├── services/
│   └── xxx.service.ts
└── module.ts

4.2 Entity Pattern

@Entity('table_name')
export class EntityName {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ name: 'organization_id' })
  organizationId: string;

  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt: Date;
}

4.3 API Decorators

Use Swagger decorators on all endpoints:

@ApiTags('Users')
@ApiOperation({ summary: 'Create user' })
@ApiResponse({ status: 201, description: 'User created' })
@Post()
create(@Body() createUserDto: CreateUserDto) { }

4.4 RBAC Implementation

Permission format: resource:action:scope

  • Resource: pond, device, cycle
  • Action: create, read, update, delete
  • Scope: own, all
@RequirePermission('pond:read:own')
@Get()
findAll() { }

5. React Frontend Standards

5.1 Component Structure

// Functional components with TypeScript
const UserList: React.FC<UserListProps> = ({ users, onSelect }) => {
  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} user={user} onSelect={onSelect} />
      ))}
    </div>
  );
};

5.2 State Management

  • TanStack Query: Server state, API calls
  • Zustand: Global client state
  • Zod: Form validation schemas

5.3 File Organization

src/
├── pages/           # Page components
├── components/      # Reusable components
├── hooks/           # Custom hooks
├── services/        # API services
├── stores/          # Zustand stores
├── types/           # TypeScript types
└── utils/           # Utility functions

6. Database Standards

6.1 Migrations

  • Generate migrations: bun run migration:generate -- src/migrations/Name
  • Run migrations: bun run migration:run
  • Use snake_case for table/column names

6.2 Soft Deletes

Use TypeORM softDelete for data retention:

@DeleteDateColumn({ name: 'deleted_at' })
deletedAt: Date;

6.3 Indexes

Add indexes for frequently queried columns:

  • Foreign keys
  • Organization-scoped queries
  • Date range queries

7. API Standards

7.1 REST Conventions

Method Action
GET /resource List all
GET /resource/:id Get one
POST /resource Create
PATCH /resource/:id Update
DELETE /resource/:id Delete

7.2 Response Format

// Standard response
{
  "data": { ... },
  "message": "Success"
}

// Paginated response
{
  "data": [...],
  "meta": {
    "total": 100,
    "page": 1,
    "limit": 20
  }
}

7.3 Error Handling

Throw NestJS exceptions:

throw new NotFoundException('User not found');
throw new UnauthorizedException('Invalid credentials');
throw new BadRequestException('Invalid input');

8. Testing Standards

  • Use Jest for unit tests
  • Follow AAA pattern: Arrange, Act, Assert
  • Test error scenarios
  • Mock external dependencies
describe('UserService', () => {
  it('should create a user', async () => {
    // Arrange
    const dto = { email: 'test@test.com', password: 'password' };

    // Act
    const result = await service.create(dto);

    // Assert
    expect(result.email).toBe(dto.email);
  });
});

9. Git & Code Quality

9.1 Pre-commit Checklist

From root (monorepo), run:

  • bun run check (runs Biome lint + format on entire project)
  • Or from backend: bun run lint:fix + bun run format
  • Verify no compile errors
  • Tests pass (backend)
  • Verify no compile errors
  • Tests pass (backend)

9.2 Commit Messages

Use conventional commits:

feat: add user profile page
fix: resolve login redirect issue
docs: update API documentation
refactor: simplify user service

10. Security Standards

  • Never commit secrets (.env, credentials)
  • Validate all inputs with class-validator/Zod
  • Use parameterized queries (TypeORM handles this)
  • Implement proper CORS configuration
  • Sanitize user inputs

Last updated: March 2026