chore: bootstrap repo with AGENTS.md and .gitignore
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
||||
# ===== OS =====
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# ===== IDE =====
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*.iml
|
||||
.cursor/
|
||||
|
||||
# ===== Logs =====
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# ===== Env / Secrets =====
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
*.pem
|
||||
*.key
|
||||
secrets/
|
||||
|
||||
# ===== Backend (Go) =====
|
||||
fuellog-api/bin/
|
||||
fuellog-api/dist/
|
||||
fuellog-api/coverage.out
|
||||
fuellog-api/*.test
|
||||
fuellog-api/*.out
|
||||
fuellog-api/.air.toml.local
|
||||
|
||||
# ===== Database (SQLite) =====
|
||||
# Keep the data/ directory, but ignore runtime DB files
|
||||
data/*.db
|
||||
data/*.db-journal
|
||||
data/*.db-shm
|
||||
data/*.db-wal
|
||||
|
||||
# ===== Frontend (Node / Vue) =====
|
||||
fuellog-web/node_modules/
|
||||
fuellog-web/dist/
|
||||
fuellog-web/dist-ssr/
|
||||
fuellog-web/.vite/
|
||||
fuellog-web/*.local
|
||||
fuellog-web/.nuxt/
|
||||
fuellog-web/.next/
|
||||
fuellog-web/.cache/
|
||||
|
||||
# ===== Coverage =====
|
||||
coverage/
|
||||
.nyc_output/
|
||||
|
||||
# ===== Docker =====
|
||||
*.pid
|
||||
@@ -0,0 +1,330 @@
|
||||
# AGENTS.md
|
||||
|
||||
> 一个轻量、精美、移动端优先的个人加油记录与车辆燃油成本分析工具。
|
||||
>
|
||||
> 中英别名: FuelLog / 加油记
|
||||
|
||||
## 项目目标
|
||||
|
||||
10 秒完成一笔加油记录,自动算出实际油价、百公里油耗、每公里成本;移动端 + PWA 优先;架构简单、不堆中间件,后续可扩展到充电、保养、停车、保险等车辆综合成本。
|
||||
|
||||
完整产品/技术决策见 `FuelLog_PLAN.md`,本文件是给 Agent 的工程操作手册。
|
||||
|
||||
---
|
||||
|
||||
## 仓库结构(单仓双工程,推荐)
|
||||
|
||||
仓库根 = 整个项目,内含前端与后端两个 Go module 风格的子工程:
|
||||
|
||||
```
|
||||
FuelLog/
|
||||
├── fuellog-web/ # Vue 3 + TS + Vite 前端
|
||||
├── fuellog-api/ # Go + Gin + GORM 后端
|
||||
├── deploy/ # docker-compose / Nginx / PWA manifest 等
|
||||
├── docs/ # 设计稿、API 文档、截图
|
||||
├── data/ # SQLite 文件(开发期;部署期挂 volume)
|
||||
├── AGENTS.md # 本文件
|
||||
├── README.md
|
||||
└── .gitignore
|
||||
```
|
||||
|
||||
> 若 Agent 决定使用 `frontend/` `backend/` 之类的别名,在该子目录里再放一份本地 `AGENTS.md` 明确路径即可,根目录命令按本文件执行。
|
||||
|
||||
---
|
||||
|
||||
## Setup commands
|
||||
|
||||
### 准备环境
|
||||
|
||||
- Node.js ≥ 20,pnpm ≥ 9(优先 pnpm,无则 npm)
|
||||
- Go ≥ 1.22
|
||||
- Docker / Docker Compose(部署)
|
||||
- `git`、`make`(可选,`make help` 查看快捷命令)
|
||||
|
||||
### 后端
|
||||
|
||||
```bash
|
||||
cd fuellog-api
|
||||
go mod tidy
|
||||
cp .env.example .env # 本地 SQLite 默认 ./data/fuellog.db
|
||||
go run ./cmd/server # 监听 :8080
|
||||
go test ./... # 核心计算单测
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
### 前端
|
||||
|
||||
```bash
|
||||
cd fuellog-web
|
||||
pnpm install # 或 npm install
|
||||
pnpm dev # 启动 Vite,默认 :5173,自动代理 /api -> :8080
|
||||
pnpm build
|
||||
pnpm preview # 预览构建产物
|
||||
pnpm typecheck # vue-tsc
|
||||
pnpm lint # eslint + prettier
|
||||
```
|
||||
|
||||
### 整体(开发期)
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker-compose.dev.yml up # API + Web + 反代 一把起
|
||||
```
|
||||
|
||||
### 部署
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
`data/` 目录必须挂载 volume,SQLite 不可随容器删除。
|
||||
|
||||
---
|
||||
|
||||
## 技术栈(锁定,不要临时换)
|
||||
|
||||
### Frontend
|
||||
- Vue 3 + TypeScript + Vite
|
||||
- Vue Router / Pinia
|
||||
- Tailwind CSS(主题通过 CSS Variables / Tailwind Theme,不在组件里写死颜色)
|
||||
- Naive UI(优先,不适合时退到 Element Plus)
|
||||
- ECharts(统计图表)
|
||||
- vite-plugin-pwa(PWA: manifest + service worker + 添加到主屏)
|
||||
|
||||
### Backend
|
||||
- Go + Gin
|
||||
- GORM(默认;若团队更熟 sqlc 允许,需在 PR 写理由)
|
||||
- SQLite(默认,代码层用 GORM 抽象,后续能切 Postgres)
|
||||
- 金额:使用 `decimal` 库或按"分"为单位的整数,避免 float 累计误差
|
||||
|
||||
### Infra
|
||||
- Docker / Docker Compose
|
||||
- Nginx / Nginx Proxy Manager 反代
|
||||
- 单一 SQLite 文件 + volume 持久化
|
||||
|
||||
### MVP 禁止引入
|
||||
Kubernetes / 微服务 / Kafka / Redis / RabbitMQ / Elasticsearch / GraphQL / Service Mesh / CQRS / Event Sourcing —— 出现真实需求前不要上。
|
||||
|
||||
---
|
||||
|
||||
## 项目布局
|
||||
|
||||
### 后端 `fuellog-api/`
|
||||
|
||||
```
|
||||
fuellog-api/
|
||||
├── cmd/server/ # main.go
|
||||
├── internal/
|
||||
│ ├── handler/ # Gin handler,只做 HTTP
|
||||
│ ├── service/ # 业务逻辑(油价/油耗/成本/统计)
|
||||
│ ├── repository/ # 数据库访问
|
||||
│ ├── model/ # 实体
|
||||
│ ├── dto/ # 入参/出参
|
||||
│ ├── middleware/ # 日志/错误/恢复
|
||||
│ └── router/ # 路由注册
|
||||
├── migrations/ # GORM AutoMigrate 或 goose 脚本
|
||||
├── config/
|
||||
├── pkg/ # 通用工具(decimal 封装、错误码等)
|
||||
├── go.mod
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
硬性分层:**Handler 不允许写业务逻辑**。Service 持有 Repository 抽象,便于单测。
|
||||
|
||||
### 前端 `fuellog-web/`
|
||||
|
||||
```
|
||||
fuellog-web/
|
||||
├── src/
|
||||
│ ├── api/ # 类型化 API client(基于 openapi 后再生成)
|
||||
│ ├── assets/
|
||||
│ ├── components/
|
||||
│ ├── layouts/ # 移动端 Bottom Nav + 桌面侧栏
|
||||
│ ├── pages/
|
||||
│ │ ├── dashboard/
|
||||
│ │ ├── refuel/ # 列表 + 新增 + 编辑
|
||||
│ │ ├── statistics/
|
||||
│ │ └── vehicle/
|
||||
│ ├── router/
|
||||
│ ├── stores/ # Pinia
|
||||
│ ├── types/
|
||||
│ ├── utils/ # decimal 工具、单位转换
|
||||
│ ├── App.vue
|
||||
│ └── main.ts
|
||||
├── public/ # PWA manifest 图标
|
||||
├── package.json
|
||||
└── vite.config.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code style
|
||||
|
||||
### 通用
|
||||
|
||||
- 文件名、变量、commit 用英文;用户可见文案、注释、commit message 用简体中文。
|
||||
- Conventional Commits 强制:`feat:` `fix:` `docs:` `refactor:` `style:` `test:` `chore:` `perf:`。
|
||||
- 提交前 `pnpm lint` + `go vet` 必须 0 错 0 警。
|
||||
- 金额、加油量、里程统一用 decimal 或显式单位,严禁直接 `==` 比较 float。
|
||||
|
||||
### 前端
|
||||
|
||||
- TypeScript `strict: true`;不写 `any`,能用 `unknown` / 联合类型收口。
|
||||
- Vue SFC `<script setup lang="ts">`;组合式 API 优先。
|
||||
- Tailwind + 主题 token,不写死颜色/间距/字号。
|
||||
- 移动端 360 / 390 / 430 三档断点优先验证,再适配桌面。
|
||||
- 任何页面必须有 Loading / Empty / Error 三态。
|
||||
|
||||
### 后端
|
||||
|
||||
- `gofmt` + `goimports` 必跑。
|
||||
- 错误统一 `pkg/apperror`,返回 `{ "code": "INVALID_ARGUMENT", "message": "..." }`。
|
||||
- 参数校验在 Handler 入参后立即完成,失败立即 abort。
|
||||
- 业务时间统一 UTC 存库,展示按本地时区格式化。
|
||||
|
||||
---
|
||||
|
||||
## 数据库 & Migration
|
||||
|
||||
- MVP 使用 SQLite,文件路径从 env 读,默认 `./data/fuellog.db`。
|
||||
- 任何表结构变更必须新增 migration 文件,不允许 `AutoMigrate` 覆盖生产数据。
|
||||
- 核心表:`vehicle`、`refuel_record`,字段定义严格按 `FuelLog_PLAN.md §7`。
|
||||
- 后续扩展(`charging_record` / `maintenance_record` / `fuel_price_history`)要预留命名空间,不要把字段塞进 `refuel_record`。
|
||||
|
||||
---
|
||||
|
||||
## 核心计算规则(必须有单测)
|
||||
|
||||
公式见 `FuelLog_PLAN.md §6`,这里只列硬要求:
|
||||
|
||||
1. **实际油价** = `总金额 / 加油量` —— 服务端实时计算并落库,前端输入金额 + 升数后立刻展示。
|
||||
2. **行驶里程** = `本次里程 - 上一次有效里程`(同一车辆按时间顺序)。
|
||||
3. **百公里油耗** 仅在**连续两次 `is_full=true` 的记录之间**计算,半箱油记录不能进入标准油耗。
|
||||
4. **每公里燃油成本** = `本次燃油费用 / 行驶里程`。
|
||||
5. 单测必须覆盖:
|
||||
- 油价计算(`176.33 / 23.67 ≈ 7.45`)
|
||||
- 油耗计算(`(10500-10000) / 40 * 100 = 8.0`)
|
||||
- 半箱油不计入标准油耗
|
||||
- 删除/编辑记录后 Dashboard / 统计数据正确刷新
|
||||
|
||||
---
|
||||
|
||||
## API 设计
|
||||
|
||||
Base path `/api`,见 `FuelLog_PLAN.md §8`。最低端点集:
|
||||
|
||||
```
|
||||
GET/POST/PUT/DELETE /api/vehicles[/...]
|
||||
GET/POST/PUT/DELETE /api/refuels[?...filters]
|
||||
GET /api/dashboard
|
||||
GET /api/statistics/overview
|
||||
GET /api/statistics/fuel-consumption
|
||||
GET /api/statistics/fuel-price
|
||||
GET /api/statistics/monthly-cost
|
||||
GET /api/statistics/cost-per-km
|
||||
```
|
||||
|
||||
- 查询参数:`vehicle_id`、`start_date`、`end_date`、`fuel_type`、`station_name`、`page`、`page_size`。
|
||||
- 错误统一格式见上文 `apperror`。
|
||||
- 必须在 `docs/api.md` 或 Swagger 同步端点;前端类型与 DTO 保持一致。
|
||||
|
||||
---
|
||||
|
||||
## UI / UX 硬性要求
|
||||
|
||||
- **Mobile first**,卡片式 Dashboard,大字号主指标(本月花费最大,平均油价/平均油耗次之)。
|
||||
- **10 秒录入** 新增加油:加油时间 → 里程 → 加油量 → 总金额 → 油品 → 加油站 → 是否加满 → 备注,保存按钮固定在移动端底部。
|
||||
- **Light / Dark Mode** 必须支持,可跟随系统;通过 CSS Variables 切换,不在组件里堆 if-else。
|
||||
- **空数据 / 加载中 / 错误** 状态统一,不能一片白。
|
||||
- **删除** 任何记录/车辆都要二次确认。
|
||||
- 移动端文案要短(加油量 `23.67 L`、金额 `176.33 元`),实际油价 `¥7.45/L` 实时显示。
|
||||
|
||||
---
|
||||
|
||||
## PWA
|
||||
|
||||
MVP 必须包含:
|
||||
- `manifest.webmanifest`、app icon(192 / 512 / maskable)
|
||||
- service worker(由 vite-plugin-pwa 生成)
|
||||
- 添加到主屏可用
|
||||
- 离线时能打开基础 UI(空数据也 OK)
|
||||
- 真正的离线数据同步放后续版本
|
||||
|
||||
---
|
||||
|
||||
## 数据导入导出
|
||||
|
||||
`Phase 7` 必做,放在 MVP 后期,不要拖到最后:
|
||||
- 导出 JSON:含 `vehicles` + `refuel_records` 全量
|
||||
- 导入 JSON:覆盖或合并,UI 给出明确选项
|
||||
- 导出 CSV:加油记录(给 Excel 看)
|
||||
- 目的:用户数据任何时候可迁出,不被项目绑死
|
||||
|
||||
---
|
||||
|
||||
## 安全 & 数据完整性
|
||||
|
||||
- 金额 ≥ 0,加油量 > 0,里程 ≥ 0,加油时间为合法日期 —— 后端强校验。
|
||||
- `vehicle_id` 必须存在,跨车辆引用全部拒绝。
|
||||
- 删除操作必须显式确认。
|
||||
- `.env` 入 `.gitignore`,不提交密钥;生产敏感配置走环境变量。
|
||||
- 容器内 API 默认只监听内网,由 Nginx 反代对外。
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
- 后端:`go test ./...`,重点覆盖 `internal/service`(计算 + 统计)。
|
||||
- 前端:Vitest 覆盖 `utils/` 与关键组件;Playwright 跑核心流程(创建车 → 加油 → 看到 Dashboard 更新)。
|
||||
- 每完成一个 Phase,跑一次 `docker compose up -d`,确认整体可起。
|
||||
- CI 至少跑:`go vet` + `go test` + `pnpm typecheck` + `pnpm build`。
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
一个功能完成必须同时满足:
|
||||
|
||||
- [ ] 功能可用(API + 前后端闭环)
|
||||
- [ ] 移动端正常(360 / 390 / 430 三档目视)
|
||||
- [ ] 桌面端正常
|
||||
- [ ] 数据库 migration 同步
|
||||
- [ ] 错误处理完整(统一 `apperror` 格式)
|
||||
- [ ] Loading / Empty / Error 状态完整
|
||||
- [ ] 核心逻辑有单测
|
||||
- [ ] `docker compose up` 能起
|
||||
- [ ] README / `docs/api.md` 同步更新
|
||||
- [ ] commit message 走 Conventional Commits
|
||||
|
||||
---
|
||||
|
||||
## Agent 执行顺序(每步先验证,再下一步)
|
||||
|
||||
严格按 `FuelLog_PLAN.md §27` 推进。禁止跳步、禁止一次性生成全部代码:
|
||||
|
||||
1. 初始化项目骨架(本文件落盘后,创建 `fuellog-web/` + `fuellog-api/` + `deploy/` + `docker-compose.dev.yml`)
|
||||
2. 后端 Model / Repository / Service / Handler + SQLite + migration
|
||||
3. 核心计算单测
|
||||
4. 后端 API(车辆 / 加油 / Dashboard / 统计)
|
||||
5. 前端骨架(Vue Router + Pinia + Tailwind + Naive UI + 主题)
|
||||
6. Dashboard 页面
|
||||
7. 新增加油页面
|
||||
8. 加油记录列表
|
||||
9. 车辆管理
|
||||
10. 统计图表(ECharts)
|
||||
11. UI 精修 / 暗色模式 / Loading / Empty / Error
|
||||
12. PWA
|
||||
13. 导入导出
|
||||
14. Docker 完整部署测试
|
||||
15. README + 截图
|
||||
|
||||
每完成一步,回到 `Definition of Done` 自查,再开下一步。
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
- **不要提前加复杂设施**:MVP 不需要 Redis、不需要 K8s、不需要微服务。需要时再讨论。
|
||||
- **不要堆业务逻辑在 Handler**:所有计算走 Service,便于单测。
|
||||
- **不要写死颜色/间距/字号**:统一从 Tailwind theme / CSS Variables 读。
|
||||
- **不要为"显得高级"加没有实际价值的技术**。
|
||||
- 任何与本文件冲突的需求,先改本文件再改代码,保持文档先行。
|
||||
Reference in New Issue
Block a user