|
| 1 | +# AGENTS.md - Leadminer Development Guide |
| 2 | + |
| 3 | +This file provides guidance for AI coding agents working in this repository. |
| 4 | + |
| 5 | +## Project Structure |
| 6 | + |
| 7 | +``` |
| 8 | +leadminer/ |
| 9 | +├── backend/ # Node.js/Express API (TypeScript) |
| 10 | +├── frontend/ # Nuxt.js Vue frontend (TypeScript) |
| 11 | +├── supabase/functions/ # Supabase Edge Functions (Deno/TypeScript) |
| 12 | +├── micro-services/ |
| 13 | +│ └── emails-fetcher/ # Email fetching microservice (TypeScript/Bun) |
| 14 | +├── docker-compose*.yml |
| 15 | +└── generate_env.sh # Environment file generator |
| 16 | +``` |
| 17 | + |
| 18 | +## Build, Lint, and Test Commands |
| 19 | + |
| 20 | +### Root Commands |
| 21 | + |
| 22 | +```bash |
| 23 | +npm run install-deps # Install all dependencies |
| 24 | +npm run dev:all # Start all services |
| 25 | +npm run dev:generate-env # Generate .env files from .env.dev templates |
| 26 | +npm run dev:supabase # Start local Supabase |
| 27 | +npm run prettier:fix # Format all code |
| 28 | +``` |
| 29 | + |
| 30 | +### Backend (Node.js/Express) |
| 31 | + |
| 32 | +```bash |
| 33 | +cd backend |
| 34 | + |
| 35 | +# Development |
| 36 | +npm run dev:api # Start API server |
| 37 | +npm run dev:worker # Start message worker |
| 38 | +npm run dev:email-worker # Start email verification worker |
| 39 | +npm run dev:email-signature-worker # Start signature extraction worker |
| 40 | + |
| 41 | +# Testing |
| 42 | +npm run test:unit # Run unit tests |
| 43 | +npm run test:unit -- --testPathPattern=<file> # Run single test file |
| 44 | +npm run test:unit -- --testNamePattern=<name> # Run tests matching name |
| 45 | +npm run test:integration # Run integration tests |
| 46 | + |
| 47 | +# Linting & Formatting |
| 48 | +npm run lint # Lint code |
| 49 | +npm run lint:fix # Fix lint issues |
| 50 | +npm run prettier:fix # Format code |
| 51 | +npm run build # Compile TypeScript |
| 52 | +``` |
| 53 | + |
| 54 | +### Frontend (Nuxt.js) |
| 55 | + |
| 56 | +```bash |
| 57 | +cd frontend |
| 58 | + |
| 59 | +npm run dev # Start dev server |
| 60 | +npm run test # Run Vitest tests |
| 61 | +npm run test -- --run # Run tests once (not watch mode) |
| 62 | +npm run test <file> # Run single test file |
| 63 | +npm run lint # Lint code |
| 64 | +npm run lint:fix # Fix lint issues |
| 65 | +npm run prettier:fix # Format code |
| 66 | +npm run build # Build for production |
| 67 | +``` |
| 68 | + |
| 69 | +### Emails Fetcher Microservice (Bun) |
| 70 | + |
| 71 | +```bash |
| 72 | +cd micro-services/emails-fetcher |
| 73 | + |
| 74 | +bun run dev # Start dev server |
| 75 | +npm run test:unit # Run unit tests |
| 76 | +npm run lint # Lint code |
| 77 | +npm run prettier:fix # Format code |
| 78 | +npm run build # Compile TypeScript |
| 79 | +``` |
| 80 | + |
| 81 | +### Supabase Edge Functions (Deno) |
| 82 | + |
| 83 | +```bash |
| 84 | +npm run dev:supabase-functions # Serve functions locally |
| 85 | +``` |
| 86 | + |
| 87 | +## Code Style Guidelines |
| 88 | + |
| 89 | +### TypeScript Configuration |
| 90 | + |
| 91 | +- **Backend**: Uses `tsconfig.json` with `strict: true`, `noImplicitAny: true` |
| 92 | +- **Frontend**: Uses Nuxt's built-in TypeScript |
| 93 | +- **Supabase Functions**: Deno with strict mode |
| 94 | + |
| 95 | +### Naming Conventions |
| 96 | + |
| 97 | +- **Files**: kebab-case (e.g., `mining-controller.ts`, `email-campaigns/`) |
| 98 | +- **Classes**: PascalCase (e.g., `TasksManager`, `RedisPublisher`) |
| 99 | +- **Functions**: camelCase (e.g., `getValidImapLogin`, `extractContacts`) |
| 100 | +- **Constants**: SCREAMING_SNAKE_CASE (e.g., `DEFAULT_SENDER_DAILY_LIMIT`) |
| 101 | +- **Interfaces/Types**: PascalCase (e.g., `MiningSource`, `ContactSnapshot`) |
| 102 | + |
| 103 | +### Imports |
| 104 | + |
| 105 | +**Backend/Emails Fetcher (absolute imports via paths):** |
| 106 | + |
| 107 | +```typescript |
| 108 | +// Preferred - from package.json "paths" config |
| 109 | +import Contacts from "../db/interfaces/Contacts"; |
| 110 | +import logger from "../utils/logger"; |
| 111 | +import ENV from "../config"; |
| 112 | + |
| 113 | +// External packages |
| 114 | +import { NextFunction, Request, Response } from "express"; |
| 115 | +import { User } from "@supabase/supabase-js"; |
| 116 | +``` |
| 117 | + |
| 118 | +**Frontend:** |
| 119 | + |
| 120 | +```typescript |
| 121 | +// Vue/Nuxt patterns |
| 122 | +import { useLeadminerStore } from "~/stores/leadminer"; |
| 123 | +import { useRuntimeConfig } from "#imports"; |
| 124 | +``` |
| 125 | + |
| 126 | +**Supabase Edge Functions:** |
| 127 | + |
| 128 | +```typescript |
| 129 | +import { Context, Hono } from "hono"; |
| 130 | +import { createSupabaseAdmin } from "../_shared/supabase.ts"; |
| 131 | +``` |
| 132 | + |
| 133 | +### Error Handling |
| 134 | + |
| 135 | +**Backend Express:** |
| 136 | + |
| 137 | +```typescript |
| 138 | +// Use custom error classes from utils/errors |
| 139 | +import { ImapAuthError, ValidationError } from "../utils/errors"; |
| 140 | + |
| 141 | +// Controller pattern |
| 142 | +async function controllerMethod( |
| 143 | + req: Request, |
| 144 | + res: Response, |
| 145 | + next: NextFunction, |
| 146 | +) { |
| 147 | + try { |
| 148 | + // ... logic |
| 149 | + } catch (error) { |
| 150 | + next(error); // Pass to error middleware |
| 151 | + } |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +**Supabase Edge Functions:** |
| 156 | + |
| 157 | +```typescript |
| 158 | +// Return proper HTTP errors |
| 159 | +return c.json({ error: "Failed to process campaign" }, 500); |
| 160 | + |
| 161 | +// Use error boundaries in Edge Functions |
| 162 | +try { |
| 163 | + // ... logic |
| 164 | +} catch (error) { |
| 165 | + console.error("Error processing campaign:", error); |
| 166 | + throw new Error(`Unable to fetch contacts for campaign: ${error.message}`); |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +### Validation |
| 171 | + |
| 172 | +- Use **Zod** for runtime validation (backend, emails-fetcher, frontend config) |
| 173 | +- Validate env vars at startup using schema.ts |
| 174 | +- Use `validateType` helper for runtime type checks |
| 175 | + |
| 176 | +### Database |
| 177 | + |
| 178 | +- **Supabase**: Use admin client (`createSupabaseAdmin`) for privileged operations |
| 179 | +- **PostgreSQL**: Use parameterized queries, never string concatenation for SQL |
| 180 | +- **Redis**: Use ioredis with connection pooling |
| 181 | + |
| 182 | +### Logging |
| 183 | + |
| 184 | +- Use **winston** logger in backend/microservices |
| 185 | +- Include context (user ID, operation) in log messages |
| 186 | +- Use appropriate levels: `error`, `warn`, `info`, `debug` |
| 187 | + |
| 188 | +### Testing |
| 189 | + |
| 190 | +- **Jest** for backend and emails-fetcher |
| 191 | +- **Vitest** for frontend |
| 192 | +- Place tests in `test/unit` or `test/integration` directories |
| 193 | +- Match test file name: `controller.ts` → `controller.test.ts` |
| 194 | + |
| 195 | +### Git Conventions |
| 196 | + |
| 197 | +- Branch naming: `feat/`, `fix/`, `docs/` prefixes |
| 198 | +- Commit messages: imperative mood, lowercase first letter |
| 199 | +- Run `npm run precommit:check` before committing (husky + lint-staged) |
| 200 | + |
| 201 | +### Vue/Frontend Patterns |
| 202 | + |
| 203 | +- Use Composition API with `<script setup>` |
| 204 | +- Follow Nuxt 3 conventions (auto-imports in `composables/`, `utils/`) |
| 205 | +- Use Pinia for state management |
| 206 | +- Use PrimeVue components |
| 207 | + |
| 208 | +### Supabase Edge Functions |
| 209 | + |
| 210 | +- Use Hono framework |
| 211 | +- Import shared code from `../_shared/` directory |
| 212 | +- Always verify service role key for admin operations |
| 213 | +- Handle CORS properly using shared cors headers |
| 214 | + |
| 215 | +## Environment Variables |
| 216 | + |
| 217 | +- All services read from `.env` files |
| 218 | +- Use `.env.dev` as template (copied by `npm run dev:generate-env`) |
| 219 | +- **Important**: Set `SUPABASE_PROJECT_URL` to your public Supabase URL for self-hosted deployments |
| 220 | + |
| 221 | +## Additional Notes |
| 222 | + |
| 223 | +- Node.js >= 20.0.0 required |
| 224 | +- Bun >= 1.1.0 required for emails-fetcher |
| 225 | +- Docker and Docker Compose required for local dev |
0 commit comments