- 后端新增 /api/bills/export 接口,支持当前筛选条件导出全部记录 - 使用 excelize 库生成 xlsx 格式文件 - 前端账单管理页面添加导出按钮 - 更新 Go 版本到 1.24 以支持 excelize 依赖
115 lines
4.9 KiB
Markdown
115 lines
4.9 KiB
Markdown
# AGENTS.md - AI Coding Agent Guidelines
|
|
|
|
Guidelines for AI coding agents working on BillAI - a microservices bill analysis system.
|
|
|
|
## Architecture
|
|
- `web/` - SvelteKit 5 + TailwindCSS 4 + TypeScript (Frontend, port 3000)
|
|
- `server/` - Go 1.21 + Gin + MongoDB (API, port 8080)
|
|
- `analyzer/` - Python 3.12 + FastAPI (Data cleaning, port 8001)
|
|
|
|
SvelteKit proxies `/api/*` requests to Go backend via `web/src/routes/api/[...path]/+server.ts`.
|
|
|
|
## Build/Lint/Test Commands
|
|
|
|
### Frontend (web/)
|
|
```bash
|
|
npm run dev # Start dev server
|
|
npm run build # Production build
|
|
npm run check # TypeScript check
|
|
npm run lint # Prettier + ESLint
|
|
npm run format # Format with Prettier
|
|
npm run test # Run all tests (CI mode)
|
|
npx vitest run src/xxx.spec.ts # Run single test file
|
|
npx vitest run -t "pattern" # Run by name pattern
|
|
```
|
|
|
|
### Backend (server/)
|
|
```bash
|
|
go run . # Start server
|
|
go build -o server . # Build binary
|
|
go test ./... # Run all tests
|
|
go test ./handler/... # Run handler tests
|
|
go test -run TestName ./... # Run single test
|
|
go test -v ./handler/... # Verbose output
|
|
```
|
|
|
|
### Analyzer (analyzer/)
|
|
```bash
|
|
python server.py # Start FastAPI
|
|
uvicorn server:app --reload # Hot reload
|
|
pytest # Run all tests
|
|
pytest test_jd_cleaner.py # Single test file
|
|
pytest -k "pattern" # Run by pattern
|
|
```
|
|
|
|
### Docker
|
|
```bash
|
|
docker-compose up -d --build # Start/rebuild all services
|
|
docker-compose logs -f server # Follow logs
|
|
docker-compose down # Stop services
|
|
```
|
|
|
|
## Code Style
|
|
|
|
### General
|
|
- **Comments:** Chinese common for business logic; English for technical.
|
|
- **Conventions:** Follow existing patterns. Check `package.json`/`go.mod`/`requirements.txt` before adding dependencies.
|
|
|
|
### TypeScript/Svelte (web/)
|
|
- **Formatting:** Prettier (tabs, single quotes, printWidth 100)
|
|
- **Naming:** `PascalCase` for types/components, `camelCase` for variables
|
|
- **Imports:** Use `$lib` alias, `$app/*` for SvelteKit builtins. No relative paths for lib modules.
|
|
- **Svelte 5:** Use runes (`$state`, `$derived`, `$effect`, `$props`). Event: `onclick={fn}`.
|
|
- **Types:** `export interface` for models. Frontend `camelCase`, API `snake_case`. Converters in `$lib/models/bill.ts`.
|
|
- **Error Handling:** Check `response.ok`, throw `Error(\`HTTP ${status}\`)`. On 401: `auth.logout()` + redirect.
|
|
- **Auth:** `createAuthStore()` in `$lib/stores/auth.ts`. Token in `localStorage` key `auth`. Use `apiFetch()` in `$lib/api.ts`.
|
|
|
|
### Go Backend (server/)
|
|
- **Layer:** `handler` → `service` → `adapter`/`repository` → `model`. No business logic in handlers.
|
|
- **Struct tags:** JSON `snake_case`, `omitempty` optional. Pointer for optional patch fields. Sensitive: `json:"-"`.
|
|
- **Error handling:** 500 for DB errors, 400 for bad requests, 404 not found. Wrap with `fmt.Errorf("context: %w", err)`.
|
|
- **Response:** `Result bool`, `Message`, `Data *T`. Auth: `success bool`, `error`, `data`.
|
|
- **Time:** Use custom `LocalTime` type (serializes as `2006-01-02 15:04:05`).
|
|
- **Soft delete:** Never hard-delete. Filter `is_deleted: false` in queries.
|
|
|
|
### Python Analyzer (analyzer/)
|
|
- **Style:** PEP 8. `snake_case` variables, `UPPER_CASE` constants. Prefix private globals with `_`.
|
|
- **Type hints:** Mandatory. Use `Optional[str]` or `str | None`.
|
|
- **Models:** `pydantic.BaseModel` for API schemas.
|
|
- **Cleaners:** Extend `BaseCleaner(ABC)` from `cleaners/base.py`. Category rules in `config/category.yaml`.
|
|
|
|
## Key Patterns
|
|
|
|
### API Flow
|
|
```
|
|
Browser → SvelteKit proxy → Go (Gin) → handler → service → adapter → Python FastAPI
|
|
└→ repository → MongoDB
|
|
```
|
|
|
|
### Authentication
|
|
- JWT (HS256). Token in `localStorage` key `auth`. Header: `Authorization: Bearer <token>`.
|
|
- `middleware.AuthRequired()` wraps `/api/*` (except `/api/auth/*`).
|
|
- 401 anywhere → `auth.logout()` + redirect `/login`.
|
|
|
|
### File Processing
|
|
Upload: ZIP/XLSX → Extract → Convert UTF-8 CSV → Detect bill type → Deduplicate → Clean → Save to MongoDB.
|
|
|
|
### Adapter (Go ↔ Python)
|
|
`adapter.Cleaner` interface: HTTP (`adapter/http`, default) or subprocess (`adapter/python`). Set via `ANALYZER_MODE` env var.
|
|
|
|
## Important Files
|
|
| File | Role |
|
|
|---|---|
|
|
| `web/src/lib/api.ts` | Central API client, auth injection |
|
|
| `web/src/lib/stores/auth.ts` | Auth state, JWT handling |
|
|
| `web/src/lib/models/bill.ts` | UIBill model + converters |
|
|
| `server/main.go` | Entry point |
|
|
| `server/handler/upload.go` | Full upload pipeline |
|
|
| `server/handler/bills.go` | List/filter bills |
|
|
| `server/model/bill.go` | Bill models, LocalTime type |
|
|
| `server/adapter/adapter.go` | Cleaner interface |
|
|
| `server/repository/mongo/repository.go` | MongoDB implementation |
|
|
| `analyzer/server.py` | FastAPI entry |
|
|
| `analyzer/cleaners/base.py` | BaseCleaner ABC |
|
|
| `analyzer/category.py` | Category inference |
|