Compare commits
1 Commits
ec3cbe7a19
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
0938cf1ccf
|
159
AGENTS.md
Normal file
159
AGENTS.md
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# 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 issues
|
||||||
|
- `pnpm run format` - Format code with Prettier
|
||||||
|
- `pnpm run test` - Run all Jest tests
|
||||||
|
- `pnpm run test:watch` - Run tests in watch mode
|
||||||
|
- `pnpm run test:cov` - Run tests with coverage report
|
||||||
|
- `pnpm run start:dev` - Start development server with hot reload
|
||||||
|
- `pnpm run init-db` - Initialize database (run scripts/init-db.ts)
|
||||||
|
|
||||||
|
### Running Single Tests
|
||||||
|
- `jest path/to/test.spec.ts` - Run a specific test file
|
||||||
|
- `jest -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:
|
||||||
|
```typescript
|
||||||
|
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/providers
|
||||||
|
- `module-name.controller.ts` - HTTP request handlers
|
||||||
|
- `module-name.service.ts` - Business logic and database operations
|
||||||
|
- `dto/` - Zod validation schemas
|
||||||
|
- `module-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:
|
||||||
|
```typescript
|
||||||
|
@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 `Error` for business logic failures (guards handle auth)
|
||||||
|
- Use transactions with `prisma.$transaction()` for multi-step operations
|
||||||
|
|
||||||
|
### Validation (DTOs)
|
||||||
|
- Use Zod schemas in `dto/index.ts` files
|
||||||
|
- Define validation rules with Chinese error messages
|
||||||
|
- Export from `dto/index.ts` barrel file
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```typescript
|
||||||
|
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 failures
|
||||||
|
- `NotFoundException` - Resource not found
|
||||||
|
- Throw `Error` in services for business logic errors
|
||||||
|
- Provide Chinese error messages: `throw new Error("用户名或密码错误")`
|
||||||
|
|
||||||
|
### Response Format
|
||||||
|
API responses follow this structure:
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
message: "操作描述(中文)",
|
||||||
|
data?: any,
|
||||||
|
pagination?: {
|
||||||
|
page: number,
|
||||||
|
limit: number,
|
||||||
|
total: number,
|
||||||
|
totalPages: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database (Prisma)
|
||||||
|
- Access Prisma client via `DatabaseService.getPrisma()`
|
||||||
|
- Use `select` to limit returned fields for security
|
||||||
|
- Use `include` for 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: Request` and 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 dev` then `npx 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")
|
||||||
Reference in New Issue
Block a user