ag
This commit is contained in:
parent
f20842b3ab
commit
83c60ce40d
257
AGENTS.md
257
AGENTS.md
@ -1,218 +1,169 @@
|
||||
# Agent Guidelines for placebo.mk
|
||||
|
||||
## Project Overview
|
||||
News site in Macedonia with sarcastic tone. Minimalistic design using TanStack stack.
|
||||
Macedonian satirical news site using TanStack stack + NestJS backend.
|
||||
|
||||
## Tech Stack
|
||||
- **Frontend**: TanStack (React 19, Query, Router) + Vite + Tailwind CSS + shadcn/ui
|
||||
- **Frontend**: React 19 + TanStack (Query, Router) + Vite + Tailwind CSS + shadcn/ui
|
||||
- **Backend**: NestJS + TypeORM + SQLite
|
||||
- **CMS**: Strapi (in /cms)
|
||||
|
||||
## Root-Level Commands
|
||||
## Commands
|
||||
|
||||
### Root Level
|
||||
```bash
|
||||
# Docker development
|
||||
npm run docker:up # Start all services
|
||||
npm run docker:down # Stop all services
|
||||
npm run docker:build # Rebuild containers
|
||||
npm run docker:logs # View logs
|
||||
npm run dev:docker # Start docker dev (alias)
|
||||
|
||||
# Local development
|
||||
npm run dev:local # Start backend & frontend locally
|
||||
npm run dev:backend:local # Backend only (local env)
|
||||
npm run dev:frontend:local # Frontend only (local env)
|
||||
|
||||
# Code quality
|
||||
npm run dev:docker # Start via docker-compose
|
||||
npm run lint # Lint both projects
|
||||
npm run lint:fix # Auto-fix lint issues
|
||||
npm run type-check # Type check both projects
|
||||
|
||||
# Database operations
|
||||
npm run db:backup # Backup database
|
||||
npm run db:restore # Restore database
|
||||
npm run db:reset # Reset database
|
||||
|
||||
# Environment
|
||||
npm run reset:env # Reset to docker environment
|
||||
```
|
||||
|
||||
## Build Commands
|
||||
|
||||
### Backend (NestJS)
|
||||
### Backend (cd backend)
|
||||
```bash
|
||||
cd backend
|
||||
npm install
|
||||
npm run start:dev # Watch mode
|
||||
npm run start:debug # Debug mode
|
||||
npm run build
|
||||
npm run start:prod
|
||||
npm run lint # Lint
|
||||
npm run lint:fix # Auto-fix
|
||||
npm run lint / lint:fix # ESLint
|
||||
npm run type-check # TypeScript check
|
||||
npm test # All tests
|
||||
npm test:watch # Watch mode tests
|
||||
npm test app.service.spec # Single file (omit .ts)
|
||||
npm test -t "should return" # By pattern
|
||||
npm test:cov # Coverage
|
||||
npm test:e2e # E2E tests
|
||||
npm test app.service.spec.ts # Single file
|
||||
npm test -t "should return" # By test name pattern
|
||||
npm run format # Format with Prettier
|
||||
npm run dev:local # Local env with .env.local
|
||||
npm run dev:docker # Docker env with .env.docker
|
||||
```
|
||||
|
||||
### Frontend (TanStack)
|
||||
### Frontend (cd frontend)
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev # Vite dev server
|
||||
npm run build
|
||||
npm run preview
|
||||
npm run lint # Lint
|
||||
npm run lint:fix # Auto-fix
|
||||
npm run lint / lint:fix # ESLint
|
||||
npm run type-check # TypeScript check
|
||||
npm test # All tests (Vitest)
|
||||
npm test Header.test # Single file (omit .tsx)
|
||||
npm test -t "renders" # By pattern
|
||||
npm test:ui # Vitest UI
|
||||
npm test:coverage # Test coverage
|
||||
npm test Header.test.tsx # Single file
|
||||
npm test -t "renders" # By test name pattern
|
||||
npm run dev:local # Local env with .env.local
|
||||
npm run dev:docker # Docker env with .env.docker
|
||||
npm test:coverage # Coverage
|
||||
```
|
||||
|
||||
## Code Style
|
||||
|
||||
### Formatting & TypeScript
|
||||
- Use Prettier (2 spaces, single quotes, trailing commas, 100 char max)
|
||||
- Strict TypeScript - no implicit `any`, avoid `any`, use `unknown`
|
||||
### TypeScript
|
||||
- Strict mode: `noImplicitAny`, `strictNullChecks`, `noFallthroughCasesInSwitch`
|
||||
- No implicit `any` - use `unknown` when type uncertain
|
||||
- Explicit return types for public methods
|
||||
- Prefer interfaces over types for objects
|
||||
- Prefer `interface` over `type` for objects
|
||||
- Use `readonly` for immutable properties
|
||||
- Backend: `noImplicitAny: true`, `strictNullChecks: true`
|
||||
- Frontend: Path alias `@/*` maps to `./src/*`
|
||||
|
||||
### Naming Conventions
|
||||
- **Files**: kebab-case (`user-profile.ts`, `auth.service.ts`)
|
||||
- **Classes**: PascalCase (`UserService`, `AuthGuard`)
|
||||
- **Functions/Variables**: camelCase (`getUser`, `isLoading`)
|
||||
- **Constants**: UPPER_SNAKE_CASE (`MAX_RETRIES`)
|
||||
- **Private members**: underscore prefix (`_cache`, `_validate()`)
|
||||
- **Interfaces**: PascalCase, no 'I' prefix (`User`, `ApiResponse`)
|
||||
### Formatting (Prettier)
|
||||
- Single quotes, trailing commas, 2-space indent
|
||||
- No semicolons in comments
|
||||
|
||||
### Import Order
|
||||
- External libraries first, then internal modules, then relative imports
|
||||
- Group imports with blank lines between groups
|
||||
- Example:
|
||||
### Naming
|
||||
| Element | Convention | Example |
|
||||
|---------|------------|---------|
|
||||
| Files | kebab-case | `user-profile.ts`, `auth.service.ts` |
|
||||
| Classes | PascalCase | `UserService`, `AuthGuard` |
|
||||
| Functions/Variables | camelCase | `getUser`, `isLoading` |
|
||||
| Constants | UPPER_SNAKE_CASE | `MAX_RETRIES` |
|
||||
| Private members | underscore prefix | `_cache`, `_validate()` |
|
||||
| Interfaces | PascalCase (no I prefix) | `User`, `ApiResponse` |
|
||||
|
||||
### Imports
|
||||
Group with blank lines: External → Internal → Relative
|
||||
```typescript
|
||||
// External
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
// Internal modules
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
import { UserService } from '../users/user.service';
|
||||
|
||||
// Relative imports
|
||||
import { UserService } from './user.service';
|
||||
import { UserController } from './user.controller';
|
||||
// Relative
|
||||
import { AuthResponse } from './types';
|
||||
```
|
||||
|
||||
|
||||
### File Structure
|
||||
```
|
||||
backend/src/
|
||||
modules/feature-name/
|
||||
feature-name.module.ts
|
||||
feature-name.controller.ts
|
||||
feature-name.service.ts
|
||||
feature-name.entity.ts
|
||||
feature-name.dto.ts
|
||||
modules/{feature}/
|
||||
{feature}.module.ts
|
||||
{feature}.controller.ts
|
||||
{feature}.service.ts
|
||||
{feature}.dto.ts
|
||||
common/{decorators,filters,guards,interceptors,pipes}
|
||||
config/
|
||||
entities.ts # All TypeORM entities
|
||||
|
||||
frontend/src/
|
||||
components/{ui,layout,features}/
|
||||
hooks/
|
||||
lib/
|
||||
queries/
|
||||
routes/
|
||||
types/
|
||||
utils/
|
||||
components/{ui,layout,features,admin,routes}/
|
||||
hooks/ # Custom React hooks
|
||||
queries/ # TanStack Query hooks
|
||||
lib/ # Utilities, API client
|
||||
routes/ # TanStack Router routes
|
||||
types/ # TypeScript types
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
- **Backend**: Use NestJS exceptions (`NotFoundException`, `BadRequestException`), custom exceptions, Logger
|
||||
- **Frontend**: Error boundaries, try-catch with user-friendly messages
|
||||
### Path Aliases
|
||||
- Frontend: `@/*` maps to `./src/*`
|
||||
- Import UI components: `import { Button } from '@/components/ui/button'`
|
||||
|
||||
### API Conventions
|
||||
- REST endpoints: `/api/v1/resources`
|
||||
- JSON fields: snake_case
|
||||
- Pagination: `page`, `limit` query params
|
||||
- Response format:
|
||||
## Patterns
|
||||
|
||||
### Backend Services (NestJS)
|
||||
```typescript
|
||||
{
|
||||
data: T,
|
||||
meta: { total, page, limit },
|
||||
error?: { code, message }
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private jwtService: JwtService,
|
||||
) {}
|
||||
|
||||
async login(dto: LoginUserDto): Promise<AuthResponse> {
|
||||
// Implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Testing
|
||||
- **Backend**: Jest with ts-jest transformer
|
||||
- **Frontend**: Vitest with React Testing Library patterns
|
||||
- Unit tests for services/hooks (AAA pattern: Arrange-Act-Assert)
|
||||
- Integration tests for API endpoints
|
||||
- E2E tests for critical user flows
|
||||
- Descriptive test names that explain what is tested (e.g., `should return user data when valid ID provided`)
|
||||
- Mock external dependencies (use Jest for backend, Vitest for frontend)
|
||||
- Run `npm test` for all tests or target specific files/names
|
||||
- Test files: `*.spec.ts` (backend), `*.test.tsx` (frontend)
|
||||
- Coverage reports: `npm test:cov` (backend), `npm test:coverage` (frontend)
|
||||
### Frontend Hooks (TanStack Query)
|
||||
```typescript
|
||||
export function useArticles(params: FindArticlesParams = {}) {
|
||||
return useQuery({
|
||||
queryKey: ['articles', params],
|
||||
queryFn: () => api.fetchArticles(params),
|
||||
});
|
||||
}
|
||||
|
||||
### Git Workflow
|
||||
- Conventional commits: `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`
|
||||
- Keep commits atomic and focused
|
||||
- Write clear commit messages in imperative mood
|
||||
export function useCreateArticle() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: api.createArticle,
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['articles'] }),
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Component Guidelines
|
||||
- Keep components small and focused (< 200 lines)
|
||||
- Use functional components with hooks
|
||||
- Prefer composition over inheritance
|
||||
- Extract complex logic into custom hooks
|
||||
- Use TanStack Query for server state management
|
||||
- Use TanStack Router for routing
|
||||
- Validate props with TypeScript
|
||||
### Error Handling
|
||||
- **Backend**: NestJS exceptions (`NotFoundException`, `BadRequestException`)
|
||||
- **Frontend**: Error boundaries, try-catch with user-friendly messages
|
||||
|
||||
### Database
|
||||
- Use TypeORM for SQLite
|
||||
- Define entities with proper relationships
|
||||
- Use migrations for schema changes
|
||||
- Seed data with factory functions
|
||||
- Use TypeORM repositories for data access
|
||||
### API Response Format
|
||||
```typescript
|
||||
{ data: T, meta: { total, page, limit }, error?: { code, message } }
|
||||
```
|
||||
|
||||
### UI Components
|
||||
- Use shadcn/ui components from `components/ui/`
|
||||
- Use class-variance-authority (CVA) for component variants
|
||||
- Use clsx and tailwind-merge for class composition
|
||||
- Follow shadcn patterns for new component creation
|
||||
## Testing
|
||||
- **Backend**: Jest (`*.spec.ts`), AAA pattern, mock dependencies
|
||||
- **Frontend**: Vitest + React Testing Library (`*.test.tsx`)
|
||||
- Descriptive names: `should return user data when valid ID provided`
|
||||
|
||||
## Git Commits
|
||||
- Conventional: `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`
|
||||
- Atomic, imperative mood
|
||||
|
||||
## Environment Variables
|
||||
- Backend: `@nestjs/config` with `.env` files
|
||||
- Frontend: Vite env vars (`VITE_API_URL`)
|
||||
- Never commit secrets to the repository.
|
||||
- Example frontend env: `VITE_API_URL=http://localhost:3000`
|
||||
- Example backend env: `DATABASE_PATH=./data.db`
|
||||
- Store sensitive config in `.env` files
|
||||
- Use `DATABASE_PATH` for SQLite location
|
||||
- Use `@nestjs/config` for backend environment management
|
||||
- Frontend env vars must be prefixed with `VITE_`
|
||||
## UI Components
|
||||
- Use shadcn/ui from `components/ui/`
|
||||
- CVA for variants, clsx + tailwind-merge for classes
|
||||
|
||||
## Agent-Specific Instructions
|
||||
- **ALWAYS** run `npm run lint` and `npm run type-check` after making changes
|
||||
- **NEVER** commit changes without explicit user request
|
||||
- **ALWAYS** follow existing code patterns and conventions
|
||||
## Agent Instructions
|
||||
- **ALWAYS** run `npm run lint` and `npm run type-check` after changes
|
||||
- **NEVER** commit without explicit request
|
||||
- **PREFER** editing existing files over creating new ones
|
||||
- **VERIFY** tests pass before considering work complete
|
||||
- **USE** the root-level commands for common operations
|
||||
- **CHECK** both backend and frontend when making API changes
|
||||
|
||||
|
||||
- **CHECK** both backend/frontend when making API changes
|
||||
|
||||
Loading…
Reference in New Issue
Block a user