|
1 | | -# Repository Guidelines |
| 1 | +# Evolution API - AI Agent Guidelines |
| 2 | + |
| 3 | +This document provides comprehensive guidelines for AI agents (Claude, GPT, Cursor, etc.) working with the Evolution API codebase. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**Evolution API** is a production-ready, multi-tenant WhatsApp API platform built with Node.js, TypeScript, and Express.js. It supports multiple WhatsApp providers and extensive integrations with chatbots, CRM systems, and messaging platforms. |
2 | 8 |
|
3 | 9 | ## Project Structure & Module Organization |
4 | | -- `src/` – TypeScript source. Key areas: `api/controllers`, `api/routes`, `api/services`, `api/integrations/{channel,chatbot,event,storage}`, `config`, `utils`, `exceptions`. |
5 | | -- `prisma/` – Prisma schema and migrations. Provider folders: `postgresql-migrations/`, `mysql-migrations/`. Use `DATABASE_PROVIDER` to target the provider. |
6 | | -- `dist/` – Build output; do not edit. |
7 | | -- `public/` – Static assets. |
8 | | -- `Docker*`, `docker-compose*.yaml` – Local stack and deployment helpers. |
| 10 | + |
| 11 | +### Core Directories |
| 12 | +- **`src/`** – TypeScript source code with modular architecture |
| 13 | + - `api/controllers/` – HTTP route handlers (thin layer) |
| 14 | + - `api/services/` – Business logic (core functionality) |
| 15 | + - `api/routes/` – Express route definitions (RouterBroker pattern) |
| 16 | + - `api/integrations/` – External service integrations |
| 17 | + - `channel/` – WhatsApp providers (Baileys, Business API, Evolution) |
| 18 | + - `chatbot/` – AI/Bot integrations (OpenAI, Dify, Typebot, Chatwoot) |
| 19 | + - `event/` – Event systems (WebSocket, RabbitMQ, SQS, NATS, Pusher) |
| 20 | + - `storage/` – File storage (S3, MinIO) |
| 21 | + - `dto/` – Data Transfer Objects (simple classes, no decorators) |
| 22 | + - `guards/` – Authentication/authorization middleware |
| 23 | + - `types/` – TypeScript type definitions |
| 24 | + - `repository/` – Data access layer (Prisma) |
| 25 | +- **`prisma/`** – Database schemas and migrations |
| 26 | + - `postgresql-schema.prisma` / `mysql-schema.prisma` – Provider-specific schemas |
| 27 | + - `postgresql-migrations/` / `mysql-migrations/` – Provider-specific migrations |
| 28 | +- **`config/`** – Environment and application configuration |
| 29 | +- **`utils/`** – Shared utilities and helper functions |
| 30 | +- **`validate/`** – JSONSchema7 validation schemas |
| 31 | +- **`exceptions/`** – Custom HTTP exception classes |
| 32 | +- **`cache/`** – Redis and local cache implementations |
| 33 | + |
| 34 | +### Build & Deployment |
| 35 | +- **`dist/`** – Build output (do not edit directly) |
| 36 | +- **`public/`** – Static assets and media files |
| 37 | +- **`Docker*`**, **`docker-compose*.yaml`** – Containerization and local development stack |
9 | 38 |
|
10 | 39 | ## Build, Test, and Development Commands |
11 | | -- `npm run build` – Type-check (tsc) and bundle with `tsup` to `dist/`. |
12 | | -- `npm run start` – Run dev server via `tsx src/main.ts`. |
13 | | -- `npm run dev:server` – Watch mode for local development. |
14 | | -- `npm run start:prod` – Run compiled app from `dist/`. |
15 | | -- `npm run lint` / `npm run lint:check` – Auto-fix and check linting. |
16 | | -- Database (choose provider): `export DATABASE_PROVIDER=postgresql` (or `mysql`), then: |
17 | | - - `npm run db:generate` – Generate Prisma client. |
18 | | - - `npm run db:migrate:dev` – Apply dev migrations and sync provider folder. |
19 | | - - `npm run db:deploy` – Apply migrations in non-dev environments. |
20 | | - - `npm run db:studio` – Open Prisma Studio. |
21 | | -- Docker: `docker-compose up -d` to start local services. |
22 | | - |
23 | | -## Coding Style & Naming Conventions |
24 | | -- TypeScript, 2-space indent, single quotes, trailing commas, 120-char max (Prettier). |
25 | | -- Enforced by ESLint + Prettier; import order via `simple-import-sort`. |
26 | | -- File names follow `feature.kind.ts` (e.g., `chat.router.ts`, `whatsapp.baileys.service.ts`). |
27 | | -- Classes: PascalCase; functions/variables: camelCase; constants: UPPER_SNAKE_CASE. |
| 40 | + |
| 41 | +### Development Workflow |
| 42 | +```bash |
| 43 | +# Development server with hot reload |
| 44 | +npm run dev:server |
| 45 | + |
| 46 | +# Direct execution for testing |
| 47 | +npm start |
| 48 | + |
| 49 | +# Production build and run |
| 50 | +npm run build |
| 51 | +npm run start:prod |
| 52 | +``` |
| 53 | + |
| 54 | +### Code Quality |
| 55 | +```bash |
| 56 | +# Linting and formatting |
| 57 | +npm run lint # ESLint with auto-fix |
| 58 | +npm run lint:check # ESLint check only |
| 59 | + |
| 60 | +# Commit with conventional commits |
| 61 | +npm run commit # Interactive commit with Commitizen |
| 62 | +``` |
| 63 | + |
| 64 | +### Database Management |
| 65 | +```bash |
| 66 | +# Set database provider first (CRITICAL) |
| 67 | +export DATABASE_PROVIDER=postgresql # or mysql |
| 68 | + |
| 69 | +# Generate Prisma client |
| 70 | +npm run db:generate |
| 71 | + |
| 72 | +# Development migrations (with provider sync) |
| 73 | +npm run db:migrate:dev # Unix/Mac |
| 74 | +npm run db:migrate:dev:win # Windows |
| 75 | + |
| 76 | +# Production deployment |
| 77 | +npm run db:deploy # Unix/Mac |
| 78 | +npm run db:deploy:win # Windows |
| 79 | + |
| 80 | +# Database tools |
| 81 | +npm run db:studio # Open Prisma Studio |
| 82 | +``` |
| 83 | + |
| 84 | +### Docker Development |
| 85 | +```bash |
| 86 | +# Start local services (Redis, PostgreSQL, etc.) |
| 87 | +docker-compose up -d |
| 88 | + |
| 89 | +# Full development stack |
| 90 | +docker-compose -f docker-compose.dev.yaml up -d |
| 91 | +``` |
| 92 | + |
| 93 | +## Coding Standards & Architecture Patterns |
| 94 | + |
| 95 | +### Code Style (Enforced by ESLint + Prettier) |
| 96 | +- **TypeScript strict mode** with full type coverage |
| 97 | +- **2-space indentation**, single quotes, trailing commas |
| 98 | +- **120-character line limit** |
| 99 | +- **Import order** via `simple-import-sort` |
| 100 | +- **File naming**: `feature.kind.ts` (e.g., `whatsapp.baileys.service.ts`) |
| 101 | +- **Naming conventions**: |
| 102 | + - Classes: `PascalCase` |
| 103 | + - Functions/variables: `camelCase` |
| 104 | + - Constants: `UPPER_SNAKE_CASE` |
| 105 | + - Files: `kebab-case.type.ts` |
| 106 | + |
| 107 | +### Architecture Patterns |
| 108 | + |
| 109 | +#### Service Layer Pattern |
| 110 | +```typescript |
| 111 | +export class ExampleService { |
| 112 | + constructor(private readonly waMonitor: WAMonitoringService) {} |
| 113 | + |
| 114 | + private readonly logger = new Logger('ExampleService'); |
| 115 | + |
| 116 | + public async create(instance: InstanceDto, data: ExampleDto) { |
| 117 | + // Business logic here |
| 118 | + return { example: { ...instance, data } }; |
| 119 | + } |
| 120 | + |
| 121 | + public async find(instance: InstanceDto): Promise<ExampleDto | null> { |
| 122 | + try { |
| 123 | + const result = await this.waMonitor.waInstances[instance.instanceName].findData(); |
| 124 | + return result || null; // Return null on not found (Evolution pattern) |
| 125 | + } catch (error) { |
| 126 | + this.logger.error('Error finding data:', error); |
| 127 | + return null; // Return null on error (Evolution pattern) |
| 128 | + } |
| 129 | + } |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +#### Controller Pattern (Thin Layer) |
| 134 | +```typescript |
| 135 | +export class ExampleController { |
| 136 | + constructor(private readonly exampleService: ExampleService) {} |
| 137 | + |
| 138 | + public async createExample(instance: InstanceDto, data: ExampleDto) { |
| 139 | + return this.exampleService.create(instance, data); |
| 140 | + } |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +#### RouterBroker Pattern |
| 145 | +```typescript |
| 146 | +export class ExampleRouter extends RouterBroker { |
| 147 | + constructor(...guards: any[]) { |
| 148 | + super(); |
| 149 | + this.router.post(this.routerPath('create'), ...guards, async (req, res) => { |
| 150 | + const response = await this.dataValidate<ExampleDto>({ |
| 151 | + request: req, |
| 152 | + schema: exampleSchema, // JSONSchema7 |
| 153 | + ClassRef: ExampleDto, |
| 154 | + execute: (instance, data) => controller.createExample(instance, data), |
| 155 | + }); |
| 156 | + res.status(201).json(response); |
| 157 | + }); |
| 158 | + } |
| 159 | +} |
| 160 | +``` |
| 161 | + |
| 162 | +#### DTO Pattern (Simple Classes) |
| 163 | +```typescript |
| 164 | +// CORRECT - Evolution API pattern (no decorators) |
| 165 | +export class ExampleDto { |
| 166 | + name: string; |
| 167 | + description?: string; |
| 168 | + enabled: boolean; |
| 169 | +} |
| 170 | + |
| 171 | +// INCORRECT - Don't use class-validator decorators |
| 172 | +export class BadExampleDto { |
| 173 | + @IsString() // ❌ Evolution API doesn't use decorators |
| 174 | + name: string; |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +#### Validation Pattern (JSONSchema7) |
| 179 | +```typescript |
| 180 | +import { JSONSchema7 } from 'json-schema'; |
| 181 | +import { v4 } from 'uuid'; |
| 182 | + |
| 183 | +export const exampleSchema: JSONSchema7 = { |
| 184 | + $id: v4(), |
| 185 | + type: 'object', |
| 186 | + properties: { |
| 187 | + name: { type: 'string' }, |
| 188 | + description: { type: 'string' }, |
| 189 | + enabled: { type: 'boolean' }, |
| 190 | + }, |
| 191 | + required: ['name', 'enabled'], |
| 192 | +}; |
| 193 | +``` |
| 194 | + |
| 195 | +## Multi-Tenant Architecture |
| 196 | + |
| 197 | +### Instance Isolation |
| 198 | +- **CRITICAL**: All operations must be scoped by `instanceName` or `instanceId` |
| 199 | +- **Database queries**: Always include `where: { instanceId: ... }` |
| 200 | +- **Authentication**: Validate instance ownership before operations |
| 201 | +- **Data isolation**: Complete separation between tenant instances |
| 202 | + |
| 203 | +### WhatsApp Instance Management |
| 204 | +```typescript |
| 205 | +// Access instance via WAMonitoringService |
| 206 | +const waInstance = this.waMonitor.waInstances[instance.instanceName]; |
| 207 | +if (!waInstance) { |
| 208 | + throw new NotFoundException(`Instance ${instance.instanceName} not found`); |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +## Database Patterns |
| 213 | + |
| 214 | +### Multi-Provider Support |
| 215 | +- **PostgreSQL**: Uses `@db.Integer`, `@db.JsonB`, `@default(now())` |
| 216 | +- **MySQL**: Uses `@db.Int`, `@db.Json`, `@default(now())` |
| 217 | +- **Environment**: Set `DATABASE_PROVIDER=postgresql` or `mysql` |
| 218 | +- **Migrations**: Provider-specific folders auto-selected |
| 219 | + |
| 220 | +### Prisma Repository Pattern |
| 221 | +```typescript |
| 222 | +// Always use PrismaRepository for database operations |
| 223 | +const result = await this.prismaRepository.instance.findUnique({ |
| 224 | + where: { name: instanceName }, |
| 225 | +}); |
| 226 | +``` |
| 227 | + |
| 228 | +## Integration Patterns |
| 229 | + |
| 230 | +### Channel Integration (WhatsApp Providers) |
| 231 | +- **Baileys**: WhatsApp Web with QR code authentication |
| 232 | +- **Business API**: Official Meta WhatsApp Business API |
| 233 | +- **Evolution API**: Custom WhatsApp integration |
| 234 | +- **Pattern**: Extend base channel service classes |
| 235 | + |
| 236 | +### Chatbot Integration |
| 237 | +- **Base classes**: Extend `BaseChatbotService` and `BaseChatbotController` |
| 238 | +- **Trigger system**: Support keyword, regex, and advanced triggers |
| 239 | +- **Session management**: Handle conversation state per user |
| 240 | +- **Available integrations**: EvolutionBot, OpenAI, Dify, Typebot, Chatwoot, Flowise, N8N, EvoAI |
| 241 | + |
| 242 | +### Event Integration |
| 243 | +- **Internal events**: EventEmitter2 for application events |
| 244 | +- **External events**: WebSocket, RabbitMQ, SQS, NATS, Pusher |
| 245 | +- **Webhook delivery**: Reliable delivery with retry logic |
28 | 246 |
|
29 | 247 | ## Testing Guidelines |
30 | | -- No formal suite yet. Place tests under `test/` as `*.test.ts`. |
31 | | -- Run `npm test` (watches `test/all.test.ts` if present). Prefer fast, isolated unit tests. |
| 248 | + |
| 249 | +### Current State |
| 250 | +- **No formal test suite** currently implemented |
| 251 | +- **Manual testing** is the primary approach |
| 252 | +- **Integration testing** in development environment |
| 253 | + |
| 254 | +### Testing Strategy |
| 255 | +```typescript |
| 256 | +// Place tests in test/ directory as *.test.ts |
| 257 | +// Run: npm test (watches test/all.test.ts) |
| 258 | + |
| 259 | +describe('ExampleService', () => { |
| 260 | + it('should create example', async () => { |
| 261 | + // Mock external dependencies |
| 262 | + // Test business logic |
| 263 | + // Assert expected behavior |
| 264 | + }); |
| 265 | +}); |
| 266 | +``` |
| 267 | + |
| 268 | +### Recommended Approach |
| 269 | +- Focus on **critical business logic** in services |
| 270 | +- **Mock external dependencies** (WhatsApp APIs, databases) |
| 271 | +- **Integration tests** for API endpoints |
| 272 | +- **Manual testing** for WhatsApp connection flows |
32 | 273 |
|
33 | 274 | ## Commit & Pull Request Guidelines |
34 | | -- Conventional Commits enforced by commitlint. Use `npm run commit` (Commitizen). |
35 | | - - Examples: `feat(api): add message status`, `fix(route): handle 404 on send`. |
36 | | -- PRs: include clear description, linked issues, migration impact (provider), local run steps, and screenshots/logs where relevant. |
| 275 | + |
| 276 | +### Conventional Commits (Enforced by commitlint) |
| 277 | +```bash |
| 278 | +# Use interactive commit tool |
| 279 | +npm run commit |
| 280 | + |
| 281 | +# Commit format: type(scope): subject (max 100 chars) |
| 282 | +# Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert, security |
| 283 | +``` |
| 284 | + |
| 285 | +### Examples |
| 286 | +- `feat(api): add WhatsApp message status endpoint` |
| 287 | +- `fix(baileys): resolve connection timeout issue` |
| 288 | +- `docs(readme): update installation instructions` |
| 289 | +- `refactor(service): extract common message validation logic` |
| 290 | + |
| 291 | +### Pull Request Requirements |
| 292 | +- **Clear description** of changes and motivation |
| 293 | +- **Linked issues** if applicable |
| 294 | +- **Migration impact** (specify database provider) |
| 295 | +- **Local testing steps** with screenshots/logs |
| 296 | +- **Breaking changes** clearly documented |
37 | 297 |
|
38 | 298 | ## Security & Configuration |
39 | | -- Copy `.env.example` to `.env`; never commit secrets. |
40 | | -- Set `DATABASE_PROVIDER` before DB commands; see `SECURITY.md` for reporting vulnerabilities. |
| 299 | + |
| 300 | +### Environment Setup |
| 301 | +```bash |
| 302 | +# Copy example environment file |
| 303 | +cp .env.example .env |
| 304 | + |
| 305 | +# NEVER commit secrets to version control |
| 306 | +# Set DATABASE_PROVIDER before database commands |
| 307 | +export DATABASE_PROVIDER=postgresql # or mysql |
| 308 | +``` |
| 309 | + |
| 310 | +### Security Best Practices |
| 311 | +- **API key authentication** via `apikey` header |
| 312 | +- **Input validation** with JSONSchema7 |
| 313 | +- **Rate limiting** on all endpoints |
| 314 | +- **Webhook signature validation** |
| 315 | +- **Instance-based access control** |
| 316 | +- **Secure defaults** for all configurations |
| 317 | + |
| 318 | +### Vulnerability Reporting |
| 319 | +- See `SECURITY.md` for security vulnerability reporting process |
| 320 | + |
| 321 | + |
| 322 | +## Communication Standards |
| 323 | + |
| 324 | +### Language Requirements |
| 325 | +- **User communication**: Always respond in Portuguese (PT-BR) |
| 326 | +- **Code/comments**: English for technical documentation |
| 327 | +- **API responses**: English for consistency |
| 328 | +- **Error messages**: Portuguese for user-facing errors |
| 329 | + |
| 330 | +### Documentation Standards |
| 331 | +- **Inline comments**: Document complex business logic |
| 332 | +- **API documentation**: Document all public endpoints |
| 333 | +- **Integration guides**: Document new integration patterns |
| 334 | +- **Migration guides**: Document database schema changes |
| 335 | + |
| 336 | +## Performance & Scalability |
| 337 | + |
| 338 | +### Caching Strategy |
| 339 | +- **Redis primary**: Distributed caching for production |
| 340 | +- **Node-cache fallback**: Local caching when Redis unavailable |
| 341 | +- **TTL strategy**: Appropriate cache expiration per data type |
| 342 | +- **Cache invalidation**: Proper invalidation on data changes |
| 343 | + |
| 344 | +### Connection Management |
| 345 | +- **Database**: Prisma connection pooling |
| 346 | +- **WhatsApp**: One connection per instance with lifecycle management |
| 347 | +- **Redis**: Connection pooling and retry logic |
| 348 | +- **External APIs**: Rate limiting and retry with exponential backoff |
| 349 | + |
| 350 | +### Monitoring & Observability |
| 351 | +- **Structured logging**: Pino logger with correlation IDs |
| 352 | +- **Error tracking**: Comprehensive error scenarios |
| 353 | +- **Health checks**: Instance status and connection monitoring |
| 354 | +- **Telemetry**: Usage analytics (non-sensitive data only) |
41 | 355 |
|
0 commit comments