7.0 KiB
7.0 KiB
Agent Guidelines for placebo.mk
Project Overview
News site in Macedonia with sarcastic tone. Minimalistic design using TanStack stack.
Tech Stack
- Frontend: TanStack (React 19, Query, Router) + Vite + Tailwind CSS + shadcn/ui
- Backend: NestJS + TypeORM + SQLite
- CMS: Strapi (in /cms)
Root-Level Commands
# 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 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)
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 type-check # TypeScript check
npm test # All tests
npm test:watch # Watch mode tests
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)
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 type-check # TypeScript check
npm test # All tests (Vitest)
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
Code Style
Formatting & TypeScript
- Use Prettier (2 spaces, single quotes, trailing commas, 100 char max)
- Strict TypeScript - no implicit
any, avoidany, useunknown - Explicit return types for public methods
- Prefer interfaces over types for objects
- Use
readonlyfor 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)
Import Order
- External libraries first, then internal modules, then relative imports
- Group imports with blank lines between groups
- Example:
// External import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; // Internal modules import { AuthModule } from '../auth/auth.module'; // Relative imports import { UserService } from './user.service'; import { UserController } from './user.controller';
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
common/{decorators,filters,guards,interceptors,pipes}
config/
frontend/src/
components/{ui,layout,features}/
hooks/
lib/
queries/
routes/
types/
utils/
Error Handling
- Backend: Use NestJS exceptions (
NotFoundException,BadRequestException), custom exceptions, Logger - Frontend: Error boundaries, try-catch with user-friendly messages
API Conventions
- REST endpoints:
/api/v1/resources - JSON fields: snake_case
- Pagination:
page,limitquery params - Response format:
{ data: T, meta: { total, page, limit }, error?: { code, message } }
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 testfor 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)
Git Workflow
- Conventional commits:
feat:,fix:,refactor:,test:,docs:,chore: - Keep commits atomic and focused
- Write clear commit messages in imperative mood
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
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
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
Environment Variables
- Backend:
@nestjs/configwith.envfiles - 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
.envfiles - Use
DATABASE_PATHfor SQLite location - Use
@nestjs/configfor backend environment management - Frontend env vars must be prefixed with
VITE_
Agent-Specific Instructions
- ALWAYS run
npm run lintandnpm run type-checkafter making changes - NEVER commit changes without explicit user request
- ALWAYS follow existing code patterns and conventions
- 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