# AGENTS.md - Agent Coding Guidelines Monorepo: data engineering projects + WhatsApp CRM apps. --- ## Project Structure ``` workspace/ ├── apps/ │ ├── go-crm/ # Go CRM, Chi router (primary) │ ├── whatsapp-crm/ # Next.js CRM, Kanban board │ ├── whatsapp-sync/ # WhatsApp message sync │ ├── whatsapp-reader/ # WhatsApp message reader │ └── timesfm-forecast/ # Time series forecast (Python/uv) ├── data/ # SQLite files │ ├── go-crm.db │ └── whatsapp.db ├── data-engineering/ # Udacity DE portfolio └── skills/ # dbt reference templates ``` --- ## Build / Lint / Test Commands ### go-crm (primary) ```bash cd apps/go-crm go run main.go # dev go build -o go-crm main.go # build binary ./go-crm # run binary go mod download # deps go mod tidy # clean go.mod/go.sum # DB: /workspace/data/go-crm.db ``` ### whatsapp-crm (Next.js) ```bash cd apps/whatsapp-crm npm run dev # dev server 0.0.0.0:3000 npm run build # production build npm run start # production server npm run lint # ESLint npm run test # all Jest tests npm run test:watch # watch mode npm run test:coverage # coverage npm run test -- tests/kanban.test.ts npm run test -- --testPathPattern=kanban ``` ### whatsapp-sync ```bash cd apps/whatsapp-sync npm run start # node src/index.js npm run dev # node --watch src/index.js npm run sync # node src/sync.js npm run test # Jest npm run test:watch npm run test:coverage ``` ### whatsapp-reader ```bash cd apps/whatsapp-reader node index.js # main script node sync.js # sync script # no test script ``` ### timesfm-forecast ```bash cd apps/timesfm-forecast uv venv && source .venv/bin/activate # create + activate venv uv pip install -e . # install package timesfm-app # run Streamlit app ``` --- ## Code Style Guidelines ### TypeScript - `strict: true` in tsconfig.json - Explicit types for params + return values - `interface` for objects, `type` for unions/aliases ```typescript interface Contact { id: number name: string stage: Stage } function getContactById(id: number): Contact | null ``` ### Imports - Path alias `@/*` (tsconfig.json) - Order: external → internal → relative - Group: React imports → other imports → types → components ```typescript import { useState, useMemo } from 'react' import { Stage, STAGES, Contact } from '@/lib/types' import { ContactCard } from '@/components/ContactCard' ``` ### Naming - **Components**: PascalCase (`KanbanBoard`, `ContactCard`) - **Files**: PascalCase (`.tsx`), camelCase (`.ts`) - **Interfaces/Types**: PascalCase - **Constants**: UPPER_SNAKE_CASE - **Hooks**: camelCase + `use` prefix - **Booleans**: `is`/`has`/`should` prefix ### Error Handling - Zod for input validation + react-hook-form - Wrap async in try/catch - Return proper HTTP status codes ```typescript export async function POST(request: Request) { try { const body = await request.json() const validated = CreateContactInput.parse(body) } catch (error) { if (error instanceof ZodError) { return Response.json({ error: error.errors }, { status: 400 }) } return Response.json({ error: 'Internal server error' }, { status: 500 }) } } ``` ### Component Structure - `'use client'` directive for client-side - Destructure props, explicit typing - Keep components focused, small - Extract reusable logic to custom hooks ```typescript 'use client' interface Props { contacts: Contact[] onContactClick: (contact: Contact) => void } export default function ComponentName({ contacts, onContactClick }: Props) { const [state, setState] = useState(false) return