# AGENTS.md - AI Coding Agent Guidelines This document provides guidelines for AI coding agents working on the BillAI project. ## Project Overview BillAI is a microservices-based personal bill analysis system supporting WeChat and Alipay bill parsing, intelligent categorization, and visualization. **Architecture:** - `web/` - Frontend (SvelteKit 5 + TailwindCSS 4.x + TypeScript) - `server/` - Backend API (Go 1.21 + Gin + MongoDB) - `analyzer/` - Python analysis service (Python 3.12 + FastAPI) ## Build, Lint, and Test Commands ### Frontend (web/) ```bash # Development npm run dev # Start dev server (Vite) # Build npm run build # Production build npm run preview # Preview production build # Type checking npm run check # svelte-check with TypeScript npm run check:watch # Watch mode # Linting and formatting npm run lint # Prettier check + ESLint npm run format # Format with Prettier # Testing npm run test # Run all tests once npm run test:unit # Run tests in watch mode npx vitest run src/demo.spec.ts # Run single test file npx vitest run -t "sum test" # Run tests matching name npx vitest run src/routes/page.svelte.spec.ts # Run component test ``` ### Backend (server/) ```bash # Run go run . # Start development server # Build go build . # Build binary # Dependencies go mod download # Install dependencies go mod tidy # Clean up dependencies # Testing (if tests exist) go test ./... # Run all tests go test ./handler/... # Run tests in specific package go test -run TestName # Run single test by name ``` ### Analyzer (analyzer/) ```bash # Setup python -m venv venv pip install -r requirements.txt # Run python server.py # Start FastAPI server # Testing (if tests exist) pytest # Run all tests pytest test_file.py # Run single test file pytest -k "test_name" # Run tests matching name ``` ### Docker ```bash docker-compose up -d --build # Start all services docker-compose ps # Check service status docker-compose down # Stop all services docker-compose logs -f web # Follow logs for specific service ``` ## Code Style Guidelines ### TypeScript/Svelte (Frontend) **Formatting (Prettier):** - Use tabs for indentation - Single quotes for strings - No trailing commas - Print width: 100 characters **Imports:** - Use `$lib/` alias for imports from `src/lib/` - Use `$app/` for SvelteKit internals - Group imports: external packages, then internal modules ```typescript import { browser } from '$app/environment'; import { auth } from '$lib/stores/auth'; import type { UIBill } from '$lib/models/bill'; ``` **Types:** - Define interfaces for API responses and requests - Use `type` for unions and simple type aliases - Export types from dedicated files in `$lib/types/` or alongside models ```typescript export interface UploadResponse { result: boolean; message: string; data?: UploadData; } ``` **Naming Conventions:** - PascalCase: Components, interfaces, types - camelCase: Functions, variables, properties - Use descriptive names: `fetchBills`, `UIBill`, `checkHealth` **Error Handling:** - Wrap API calls in try/catch - Throw `Error` with HTTP status for API failures - Handle 401 responses with logout redirect ```typescript if (!response.ok) { throw new Error(`HTTP ${response.status}`); } ``` ### Go (Backend) **Project Structure:** - `handler/` - HTTP request handlers - `service/` - Business logic - `repository/` - Data access layer - `model/` - Data structures - `adapter/` - External service integrations - `config/` - Configuration management - `middleware/` - Auth and other middleware **Naming Conventions:** - PascalCase: Exported types, functions, constants - camelCase: Unexported functions, variables - Use descriptive names: `UpdateBillRequest`, `parseBillTime` **Error Handling:** - Define sentinel errors in `repository/errors.go` - Return errors up the call stack - Use structured JSON responses for HTTP errors ```go if err == repository.ErrNotFound { c.JSON(http.StatusNotFound, Response{Result: false, Message: "not found"}) return } ``` **JSON Tags:** - Use snake_case for JSON field names - Use `omitempty` for optional fields - Match frontend API expectations ```go type UpdateBillRequest struct { Category *string `json:"category,omitempty"` Amount *float64 `json:"amount,omitempty"` } ``` **Response Format:** - All API responses use consistent structure: ```go type Response struct { Result bool `json:"result"` Message string `json:"message,omitempty"` Data interface{} `json:"data,omitempty"` } ``` ### Python (Analyzer) **Style:** - Follow PEP 8 - Use type hints for function signatures - Use Pydantic models for request/response validation ```python def do_clean( input_path: str, output_path: str, bill_type: str = "auto" ) -> tuple[bool, str, str]: ``` **Error Handling:** - Raise `HTTPException` for API errors - Use try/except for file operations - Return structured responses ```python if not success: raise HTTPException(status_code=400, detail=message) ``` ## Testing Guidelines **Frontend Tests:** - Use Vitest with Playwright for browser testing - Component tests: `*.svelte.spec.ts` - Unit tests: `*.spec.ts` - Tests require assertions: `expect.assertions()` or explicit expects ```typescript import { describe, it, expect } from 'vitest'; import { render } from 'vitest-browser-svelte'; describe('/+page.svelte', () => { it('should render h1', async () => { render(Page); await expect.element(page.getByRole('heading')).toBeInTheDocument(); }); }); ``` ## Important Patterns **API Communication:** - Frontend proxies API calls through SvelteKit to avoid CORS - Backend uses Gin framework with JSON responses - Analyzer communicates via HTTP (preferred) or subprocess **Data Flow:** - Frontend (SvelteKit) -> Backend (Go/Gin) -> MongoDB - Backend -> Analyzer (Python/FastAPI) for bill parsing **Authentication:** - JWT tokens stored in frontend auth store - Bearer token sent in Authorization header - 401 responses trigger logout and redirect ## File Locations - API types: `web/src/lib/api.ts` - UI models: `web/src/lib/models/` - Go handlers: `server/handler/` - Go models: `server/model/` - Python API: `analyzer/server.py`