5.4 KiB
5.4 KiB
AGENTS.md - Coding Guidelines for Trace Backend
Build, Lint, and Test Commands
Essential Commands
pnpm run build- Build the NestJS application to dist/pnpm run lint- Run ESLint and auto-fix issuespnpm run format- Format code with Prettierpnpm run test- Run all Jest testspnpm run test:watch- Run tests in watch modepnpm run test:cov- Run tests with coverage reportpnpm run start:dev- Start development server with hot reloadpnpm run init-db- Initialize database (run scripts/init-db.ts)
Running Single Tests
jest path/to/test.spec.ts- Run a specific test filejest -t "test name"- Run tests matching a pattern
Project Overview
This is a NestJS backend for the Trace (贝凡溯源) management platform with:
- Framework: NestJS 11.x with TypeScript
- Database: SQLite via Prisma ORM with better-sqlite3 adapter
- Validation: Zod schemas with nestjs-zod global pipe
- Auth: JWT-based authentication with Passport
- Package Manager: pnpm 10.x
Code Style Guidelines
Imports and Organization
- Use double quotes for all imports:
import { X } from "package" - Group external framework imports first, then internal imports
- Use relative imports with
../or./notation - Example:
import { Injectable, UnauthorizedException } from "@nestjs/common"; import { JwtService } from "@nestjs/jwt"; import * as bcrypt from "bcryptjs"; import { DatabaseService } from "../database/database.service"; import { User, AuthUser } from "../types";
Naming Conventions
- Classes: PascalCase -
AuthService,AuthGuard,SerialsService - Methods/Functions: camelCase -
validateUser,login,getProfile - Variables: camelCase -
const prisma = ... - Interfaces/Types: PascalCase -
User,AuthUser,JWTPayload - DTOs: PascalCase with "Dto" suffix -
LoginDto,ChangePasswordDto - Models: PascalCase -
User,Company,Serial(Prisma models)
Module Structure
Each feature follows the NestJS pattern:
module-name/module-name.module.ts- Module definition with imports/providersmodule-name.controller.ts- HTTP request handlersmodule-name.service.ts- Business logic and database operationsdto/- Zod validation schemasmodule-name.guard.ts- Guards (if needed)
Controllers
- Use appropriate decorators:
@Controller,@Get,@Post,@Patch,@Delete - Apply guards:
@UseGuards(AuthGuard)or@UseGuards(AuthGuard, AdminGuard) - Set status codes explicitly:
@HttpCode(HttpStatus.OK) - Extract params/query with decorators:
@Param,@Query,@Body,@Req - Validate DTOs:
@Body(LoginDto) loginDto: any - Return structured responses (see Response Format below)
Example:
@Controller("auth")
export class AuthController {
constructor(private authService: AuthService) {}
@Post("login")
@HttpCode(HttpStatus.OK)
async login(@Body(LoginDto) loginDto: any) {
const user = await this.authService.validateUser(loginDto.username, loginDto.password);
return this.authService.login(user);
}
}
Services
- Mark with
@Injectable()decorator - Inject dependencies via constructor
- Use
DatabaseService.getPrisma()to get Prisma client - Throw
Errorfor business logic failures (guards handle auth) - Use transactions with
prisma.$transaction()for multi-step operations
Validation (DTOs)
- Use Zod schemas in
dto/index.tsfiles - Define validation rules with Chinese error messages
- Export from
dto/index.tsbarrel file
Example:
export const LoginDto = z.object({
username: z.string().min(1, "用户名不能为空"),
password: z.string().min(1, "密码不能为空"),
});
Error Handling
- Throw NestJS exceptions in controllers/guards:
UnauthorizedException- Auth failuresNotFoundException- Resource not found
- Throw
Errorin services for business logic errors - Provide Chinese error messages:
throw new Error("用户名或密码错误")
Response Format
API responses follow this structure:
{
message: "操作描述(中文)",
data?: any,
pagination?: {
page: number,
limit: number,
total: number,
totalPages: number
}
}
Database (Prisma)
- Access Prisma client via
DatabaseService.getPrisma() - Use
selectto limit returned fields for security - Use
includefor relations (user, company) - Serial numbers should be uppercase:
serialNumber.toUpperCase()
Authentication
- Use
@UseGuards(AuthGuard)for authenticated routes - Use
@UseGuards(AuthGuard, AdminGuard)for admin-only routes - Access user via
@Req() req: Requestand cast:(req as any).user - User object contains:
id,username,name,role
TypeScript Configuration
- Target: ES2021
- Strict mode disabled (per tsconfig.json)
- Experimental decorators enabled
- Module: commonjs
Database Schema
Located in prisma/schema.prisma:
- Models: User, Company, Serial
- Relations: User -> Serial, Company -> Serial
- After schema changes:
npx prisma migrate devthennpx prisma generate
Static Files
- Production: serves from
frontend/dist/ - Development: serves from
frontend/public/ - Static assets served via
@nestjs/serve-static
Development Notes
- Global API prefix:
/api - CORS enabled
- QR code color: dark="#165DFF", light="#ffffff"
- Default serial prefix: "BF" + current year (e.g., "BF26")