# AGENTS.md - Coding Agent Guidelines Bu dosya, bu repoda çalışan AI kodlama ajanları için rehberdir. --- ## 1. Build / Lint / Test Commands ```bash # Development npm run start:dev # Dev server with watch mode npm run build # Production build (nest build) # Linting & Formatting npm run lint # ESLint with Prettier npm run format # Prettier write # Testing npm run test # Run all unit tests npm run test:watch # Watch mode npm run test:e2e # End-to-end tests npx jest src/path/to/file.spec.ts # Run single test file npx jest --testNamePattern="test name" # Run specific test # Database npx prisma generate # Generate Prisma client (required after install) npx prisma migrate dev # Run migrations npx prisma db seed # Seed database # Feeder Scripts npm run feeder:historical # Historical data fetch npm run feeder:live # Live match data fetch npm run feeder:basketball # Basketball data fetch ``` --- ## 2. Code Style Guidelines ### Imports (Sıralama) ```typescript // 1. NestJS/common imports import { Controller, Get, Post, Body } from '@nestjs/common'; import { ApiTags, ApiOperation } from '@nestjs/swagger'; // 2. External packages import { plainToInstance } from 'class-transformer'; import * as bcrypt from 'bcrypt'; // 3. Local imports (relative) import { UsersService } from './users.service'; import { CreateUserDto } from './dto/user.dto'; import { ApiResponse, createSuccessResponse } from '../../common/types'; ``` ### Formatting - **Single quotes** for strings - **Trailing commas** always - Prettier ile formatlama zorunlu - Dosya sonu boş satır ### Types & Type Safety - `strictNullChecks: true` - null/undefined kontrolü zorunlu - `noImplicitAny: false` - any kullanımına izin var (Prisma dynamic access için) - Fonksiyon return type belirt: `async findOne(id: string): Promise` - Interface > Type alias (objeler için) ### Naming Conventions ```typescript // Classes & Interfaces: PascalCase class UsersService {} interface ApiResponse {} // Variables & Functions: camelCase const userService = new UsersService(); async function findUserById() {} // Constants: UPPER_SNAKE_CASE const JWT_SECRET = 'secret'; const IS_PUBLIC_KEY = 'isPublic'; // Files: kebab-case user.dto.ts; users.service.ts; predictions.processor.spec.ts; // DTOs: Entity + Dto suffix (CreateUserDto, UpdateUserDto, UserResponseDto); ``` --- ## 3. DTO Pattern ### Request DTOs ```typescript export class CreateUserDto { @ApiPropertyOptional({ example: 'user@example.com' }) @IsEmail() email: string; @IsString() @MinLength(8) password: string; @IsOptional() @IsString() firstName?: string; } ``` ### Response DTOs (Security Critical) ```typescript @Exclude() export class UserResponseDto { @Expose() id: string; @Expose() email: string; // passwordHash intentionally NOT exposed } ``` ### Controller Usage ```typescript @Get('me') async getMe(@CurrentUser() user: User): Promise> { const fullUser = await this.usersService.findOneWithDetails(user.id); return createSuccessResponse( plainToInstance(UserResponseDto, fullUser), ); } ``` **KRITIK:** Asla raw Prisma entity döndürme. Her zaman Response DTO kullan. --- ## 4. Architecture Patterns ### Service Layer ```typescript @Injectable() export class UsersService extends BaseService< User, CreateUserDto, UpdateUserDto > { constructor(prisma: PrismaService) { super(prisma, 'User'); } // Custom methods... } ``` ### Controller Layer ```typescript @ApiTags('Users') @ApiBearerAuth() @Controller('users') export class UsersController extends BaseController< User, CreateUserDto, UpdateUserDto > { constructor(private readonly usersService: UsersService) { super(usersService, 'User'); } } ``` ### API Response Format ```typescript // All responses use this structure { "success": true, "status": 200, "message": "Success", "data": { ... }, "errors": [] } // Helper functions createSuccessResponse(data, 'Message') createErrorResponse('Message', 400, ['error1']) createPaginatedResponse(items, total, page, limit) ``` --- ## 5. Error Handling ### Throw NestJS HTTP Exceptions ```typescript // Correct throw new NotFoundException('User not found'); throw new ConflictException('EMAIL_ALREADY_EXISTS'); throw new UnauthorizedException('INVALID_CREDENTIALS'); // Wrong throw new Error('User not found'); // Don't use generic Error ``` ### i18n Error Keys ```typescript // Use translatable keys (check src/i18n/{lang}/errors.json) throw new ConflictException('EMAIL_ALREADY_EXISTS'); // Translates to: "Email already exists" (en) / "Email zaten kayıtlı" (tr) ``` ### Global Exception Filter - Tüm hatalar HTTP 200 ile döner (status body içinde) - `NODE_ENV=development` ise stack trace eklenir - Validation hataları otomatik formatlanır --- ## 6. Testing ### Unit Test Structure ```typescript import { Test, TestingModule } from '@nestjs/testing'; describe('UsersService', () => { let service: UsersService; let prisma: PrismaService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ UsersService, { provide: PrismaService, useValue: mockPrisma }, ], }).compile(); service = module.get(UsersService); }); it('should find user by id', async () => { // Arrange mockPrisma.user.findUnique.mockResolvedValue(mockUser); // Act const result = await service.findOne('id'); // Assert expect(result).toEqual(mockUser); }); }); ``` ### Mocking External Dependencies ```typescript jest.mock('axios'); const mockedAxios = axios as jest.Mocked; beforeEach(() => { jest.clearAllMocks(); mockedAxios.post.mockResolvedValue({ data: { ok: true } }); }); ``` --- ## 7. Module Registration Redis-enabled modüller için `app.module.ts`: ```typescript const redisEnabled = process.env.REDIS_ENABLED === 'true'; @Module({ imports: [ ...(redisEnabled ? [QueueModule, PredictionsModule] : []), // ... ], }) ``` --- ## 8. Environment Variables Zorunlu (`.env`): ```env NODE_ENV=development PORT=3005 DATABASE_URL=postgresql://postgres:password@localhost:15432/boilerplate_db JWT_SECRET=your-secret-key JWT_ACCESS_EXPIRATION=15m REDIS_ENABLED=false AI_ENGINE_URL=http://127.0.0.1:8000 ``` --- ## 9. Pre-commit Checklist 1. `npm run lint` - Lint errors fixed 2. `npm run build` - Build succeeds 3. `npm run test` - All tests pass 4. Response DTOs used for all API responses 5. No secrets/credentials in code