本文档供 AI 编码代理阅读。项目主要使用中文注释和文档,因此本文件以中文撰写。
本项目名为 shit,是一个基于 Go + Gin + ClickHouse 的个人拉屎健康记录与分析 Web 服务。
项目核心功能:
- 通过网页上的一个黄色圆形交互组件,记录每次排便的顺畅程度(4 级:blocked / hardly / normal / diarrhea)。
- 将记录写入 ClickHouse 数据库(
shit.toilet_log表)。 - 提供 REST API 进行数据查询与分析,包括:散点图数据、腹泻分析、便秘分析、周报、年报。
- 支持批量生成测试数据。
项目仓库:zeusro.com/shit(Go module 名)
| 层级 | 技术 |
|---|---|
| 编程语言 | Go 1.24.2 |
| Web 框架 | Gin (github.com/gin-gonic/gin) |
| 数据库 | ClickHouse (github.com/ClickHouse/clickhouse-go/v2) |
| 前端 | 原生 HTML + CSS + JavaScript(无外部框架) |
| 容器化 | Docker + Docker Compose |
| 构建工具 | Go 自带工具链 + Makefile |
.
├── main.go # 入口:初始化 ClickHouse、启动 Gin、注册中间件和路由
├── go.mod / go.sum # Go 模块依赖管理
├── Dockerfile # 多阶段构建:builder(golang:1.24-alpine)+ 运行镜像(alpine)
├── docker-compose.yml # 编排 clickhouse + gin-web 两个服务
├── Makefile # 常用快捷命令(run / build / bbuild / down / auto_commit)
├── api.md # REST API 接口文档(中文)
├── readme.md # 英文 README(极简,仅标题和截图)
├── readme.zh.md # 中文 README(详细,包含需求、SQL、设计过程、TODO)
│
├── api/
│ ├── routes.go # 路由注册(/shit, /api/generate, /api/scatter, /api/diarrhea, /api/constipation, /api/weekly, /api/yearly)
│ ├── handlers.go # 所有 HTTP Handler 实现
│ └── models.go # 请求/响应结构体定义
│
├── db/
│ └── clickhouse.go # ClickHouse 连接初始化 + 自动建库建表
│
├── static/
│ └── index.html # 单页前端:黄色圆形 + 滚动条 + 语言切换 + POST /shit
│
└── doc/
├── mac.png
└── shit.png
数据库:shit
表:shit.toilet_log
CREATE TABLE IF NOT EXISTS shit.toilet_log
(
id UInt64,
log_time DateTime,
smoothness Enum8(
'blocked' = 0, -- 完全拉不出
'hardly' = 1, -- 几乎拉不出
'normal' = 2, -- 正常拉屎
'diarrhea' = 3 -- 一泻千里
)
)
ENGINE = MergeTree
ORDER BY log_time;连接信息通过环境变量读取,无配置时默认连接本地 127.0.0.1:9000:
CLICKHOUSE_HOSTCLICKHOUSE_PORTCLICKHOUSE_USER(代码中硬编码为default)CLICKHOUSE_PASSWORD(代码中硬编码为123456)CLICKHOUSE_DB
# 构建 Go 二进制
make bbuild # 等价于 go build
# 运行(先确保本地 ClickHouse 在 127.0.0.1:9000 可访问)
go run main.go# 一键构建并启动 web + clickhouse
make run # 等价于 docker compose up --build
# 仅构建镜像
make build # 等价于 docker compose build --no-cache
# 停止并移除容器
make down # 等价于 docker compose down服务启动后:
- Web 服务:
http://localhost:8080 - ClickHouse HTTP 接口:
http://localhost:8123 - ClickHouse 原生协议:
localhost:9000
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /shit |
提交单条排便记录 |
| POST | /api/generate |
按日期范围批量生成测试数据 |
| GET | /api/scatter |
获取所有记录(散点图用) |
| GET | /api/diarrhea |
腹泻分析 |
| GET | /api/constipation |
便秘分析 |
| GET | /api/weekly |
周报统计 |
| GET | /api/yearly |
年报统计 |
| 静态文件 | / |
static/index.html |
详细接口定义、请求/响应格式参见根目录 api.md。
- 注释语言:所有代码注释使用中文。
- 包结构:
main包在根目录,负责服务组装(依赖注入风格:先db.InitClickHouse(),再api.SetClickHouseConn(db.Conn))。api包:HTTP 层,包含路由、Handler、模型结构体。db包:数据库连接层,暴露全局变量Conn。
- 错误处理:Handler 中使用
c.JSON()直接返回错误信息,同时用log.Println/log.Printf在服务端打印日志。 - TraceID:
main.go中的LoggerWithTraceID()中间件为每个请求生成 UUID 作为 traceID,并记录请求方法、路径、状态码、耗时。 - 日期时间格式:代码中统一使用 Go 的
"2006-01-02"和"2006-01-02 15:04:05"布局。 - 前端:单文件原生 HTML,硬编码 API 地址为
http://localhost:8080/shit,支持中英文切换。
当前项目没有单元测试或集成测试文件。
验证功能的主要方式:
- 启动后访问
http://localhost:8080,通过页面交互提交记录。 - 使用
api.md中的 cURL 示例直接调用 API。 - 使用 Tabix 或 ClickHouse Client 直接查询
shit.toilet_log表验证数据写入。
如需新增测试,建议引入标准库 testing + httptest 对 Gin Handler 进行单元测试,或引入 testcontainers-go 做 ClickHouse 集成测试。
- 硬编码凭据:
db/clickhouse.go中数据库用户名和密码(default/123456)为硬编码,生产环境需改为从环境变量或密钥管理服务读取。 - 无认证授权:所有 API 均为公开接口,无任何身份验证机制。
- SQL 注入风险:
GetYearlyReport中使用了fmt.Sprintf拼接年份到 SQL 查询,虽然年份来自uint16类型扫描结果,但仍建议改用参数化查询。 - CORS:未配置跨域,前端在本地直接访问无问题,若部署到不同域名需添加 CORS 中间件。
- 随机数种子:
GenerateData中使用了已弃用的rand.Seed(Go 1.20+ 已自动处理全局随机源),不影响功能但建议后续使用rand.New(rand.NewSource(...))。
- 集成周报、月报图表,提供相应的数据可视化接口(目前主要用 Tabix 做离线分析)。
| 文件 | 用途 |
|---|---|
main.go |
服务入口、中间件、启动逻辑 |
api/routes.go |
路由注册 |
api/handlers.go |
业务逻辑 Handler |
api/models.go |
请求/响应结构体 |
db/clickhouse.go |
ClickHouse 连接与表初始化 |
static/index.html |
前端单页应用 |
api.md |
完整 API 文档 |
docker-compose.yml |
容器编排 |
Dockerfile |
多阶段构建镜像 |
Makefile |
快捷命令 |