M1-T07: align docs to single-DB reality and re-export OpenAPI
Rewrite README (single app.db + one alembic_app chain, legacy data moved once via scripts.migrate_legacy_data, accurate test list) and remove the Grafana Provisioning section. Update architecture-overview to the unified data layer (one Base, app-DB engine with WAL) and retire the alembic_location / alembic_poo sections. Mark M1 done in the roadmap. Re-export openapi/, which catches the spec up to the already-existing /config/smtp/test and /public-ip/check endpoints (purely additive; M1's DB-session dependency swap produced no schema change). pytest 95 passed; ruff clean (pre-existing only); OpenAPI export idempotent.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
当前系统已经包含:
|
||||
|
||||
- FastAPI Web 应用与服务端模板页面
|
||||
- SQLite + SQLAlchemy + Alembic 的三库结构
|
||||
- SQLite + SQLAlchemy + Alembic 的单库结构
|
||||
- username/password + server-side session 鉴权
|
||||
- runtime config 页面与 app DB 持久化
|
||||
- public IPv4 monitor、历史持久化与定时检查
|
||||
@@ -23,41 +23,32 @@
|
||||
|
||||
## 当前配置现实
|
||||
|
||||
当前系统仍然是三个独立的 SQLite 数据库文件,而不是单一数据库:
|
||||
当前系统使用单一 SQLite 数据库文件(`app.db`),所有数据表都在其中:
|
||||
|
||||
- `app` 级共享数据使用自己的 DB 文件
|
||||
- `location` 模块使用自己的 DB 文件
|
||||
- `poo` 模块使用自己的 DB 文件
|
||||
- auth(单个 admin 用户、server-side session)
|
||||
- runtime config 持久化(`app_config` 表)
|
||||
- public IPv4 当前状态与变化历史
|
||||
- location 记录(`location` 表)
|
||||
- poo 记录(`poo_records` 表)
|
||||
|
||||
当前阶段明确不借这次重构把这些 DB 合并。配置层已经显式反映这一点:
|
||||
配置层只保留一个数据库环境变量:
|
||||
|
||||
- `APP_DATABASE_URL`
|
||||
- `LOCATION_DATABASE_URL`
|
||||
- `POO_DATABASE_URL`
|
||||
|
||||
目前 auth、`location` 和 `poo` 都已经接到各自独立的数据库文件。
|
||||
`app.db` 不会在应用启动时自动创建,需要先运行:
|
||||
|
||||
其中 `app` 级共享 DB 当前主要用于:
|
||||
```bash
|
||||
python -m scripts.run_migrations
|
||||
```
|
||||
|
||||
- 单个 admin 用户
|
||||
- server-side session
|
||||
- runtime config 持久化
|
||||
- public IPv4 当前状态与变化历史
|
||||
|
||||
这部分现在也使用 Alembic 管理:
|
||||
|
||||
- `app db` 不会在应用启动时自动创建
|
||||
- 需要先运行 `python scripts/app_db_adopt.py`
|
||||
- 这个脚本会创建新 DB 并建好 schema
|
||||
该命令会通过 Alembic 将 `app.db` 初始化或升级到最新 head(含 `location` / `poo_records` 表)。
|
||||
|
||||
## 当前目录
|
||||
|
||||
主要目录如下:
|
||||
|
||||
- `app/`: FastAPI 应用代码
|
||||
- `alembic_app/`: App DB 的 Alembic migration 环境
|
||||
- `alembic_location/`: Location DB 的 Alembic migration 环境
|
||||
- `alembic_poo/`: Poo DB 的 Alembic migration 环境
|
||||
- `alembic_app/`: App DB 的 Alembic migration 环境(同时管理 `location` / `poo_records` 表)
|
||||
- `tests/`: pytest 测试
|
||||
- `docs/`: 当前系统说明文档
|
||||
- `scripts/`: 辅助脚本,例如 OpenAPI 导出
|
||||
@@ -128,24 +119,22 @@ uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
|
||||
## 数据库与 Alembic
|
||||
|
||||
当前默认使用 SQLite,并区分三个数据库文件:
|
||||
当前使用单一 SQLite 数据库文件:
|
||||
|
||||
- App DB:`sqlite:///./data/app.db`
|
||||
- Location DB:`sqlite:///./data/locationRecorder.db`
|
||||
- Poo DB:`sqlite:///./data/pooRecorder.db`
|
||||
- 数据目录:`./data/`
|
||||
|
||||
初始化 migration 环境后,可继续添加模型并生成迁移:
|
||||
所有模型(auth / config / public_ip / location / poo)共用同一个 `Base`,均通过单一 Alembic 链管理:
|
||||
|
||||
当前 `app`、`location` 和 `poo` 都已经有各自独立的 Alembic 链路。
|
||||
|
||||
- App Alembic 环境:`alembic_app.ini` + `alembic_app/`
|
||||
- Location Alembic 环境:`alembic_location.ini` + `alembic_location/`
|
||||
- Poo Alembic 环境:`alembic_poo.ini` + `alembic_poo/`
|
||||
- Alembic 环境:`alembic_app.ini` + `alembic_app/`
|
||||
- 统一 migration job:`python -m scripts.run_migrations`
|
||||
- App DB 初始化:`python scripts/app_db_adopt.py`
|
||||
- Location DB 接管 / 初始化:`python scripts/location_db_adopt.py`
|
||||
- Poo DB 接管 / 初始化:`python scripts/poo_db_adopt.py`
|
||||
- App DB 接管 / 初始化:`python scripts/app_db_adopt.py`
|
||||
|
||||
历史 location / poo 数据(旧版本遗留的独立 DB 文件)已通过以下脚本一次性迁移至 `app.db`(幂等,不删除旧文件):
|
||||
|
||||
```bash
|
||||
python -m scripts.migrate_legacy_data
|
||||
```
|
||||
|
||||
## 基础鉴权
|
||||
|
||||
@@ -197,7 +186,7 @@ uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
|
||||
这意味着:
|
||||
|
||||
- location / poo / app DB 地址仍然属于 bootstrap 范畴
|
||||
- app DB 地址(`APP_DATABASE_URL`)仍然属于 bootstrap 范畴
|
||||
- 运行时可编辑配置主要通过 `app_config` 表持久化
|
||||
- token / secret 这类运行时必须可取回的配置,目前允许明文存储在 config 表中
|
||||
- 登录密码仍然单独使用 Argon2 哈希,不走 config 表明文存储
|
||||
@@ -318,55 +307,6 @@ docker compose -f docker-compose.yml up -d
|
||||
docker compose logs -f app
|
||||
```
|
||||
|
||||
## Grafana Provisioning
|
||||
|
||||
当前仓库支持通过 Grafana provisioning 自动加载 SQLite datasource 和 repo 内的 dashboard 导出文件。
|
||||
|
||||
需要保留的文件路径如下:
|
||||
|
||||
- `grafana/provisioning/datasources/locationrecorder.yaml`
|
||||
- `grafana/provisioning/datasources/poorecorder.yaml`
|
||||
- `grafana/provisioning/dashboards/provider.yaml`
|
||||
- `grafana/dashboards/locationrecorder.json`
|
||||
- `grafana/dashboards/poorecorder.json`
|
||||
|
||||
这些文件的职责分别是:
|
||||
|
||||
- `grafana/provisioning/datasources/locationrecorder.yaml`:声明 `locationrecorder` SQLite datasource,并指向 `/data/home-automation/locationRecorder.db`
|
||||
- `grafana/provisioning/datasources/poorecorder.yaml`:声明 `poorecorder` SQLite datasource,并指向 `/data/home-automation/pooRecorder.db`
|
||||
- `grafana/provisioning/dashboards/provider.yaml`:告诉 Grafana 从 `/var/lib/grafana/dashboards` 扫描并加载 dashboard JSON
|
||||
- `grafana/dashboards/locationrecorder.json`:location recorder dashboard 导出文件,内容本身不需要在 compose 中改写
|
||||
- `grafana/dashboards/poorecorder.json`:poo recorder dashboard 导出文件,内容本身不需要在 compose 中改写
|
||||
|
||||
当前 `docker-compose.yml` 中,Grafana service 需要挂载以下目录:
|
||||
|
||||
- `./grafana/provisioning -> /etc/grafana/provisioning:ro`
|
||||
- `./grafana/dashboards -> /var/lib/grafana/dashboards:ro`
|
||||
|
||||
同时保留现有 named volume `homeautomation_grafana_storage:/var/lib/grafana` 作为 Grafana 运行态数据存储。
|
||||
|
||||
一键启动前,至少需要以下文件已经存在:
|
||||
|
||||
- `grafana/provisioning/datasources/locationrecorder.yaml`
|
||||
- `grafana/provisioning/datasources/poorecorder.yaml`
|
||||
- `grafana/provisioning/dashboards/provider.yaml`
|
||||
- `grafana/dashboards/locationrecorder.json`
|
||||
- `grafana/dashboards/poorecorder.json`
|
||||
|
||||
启动方式:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
启动后会发生的事情:
|
||||
|
||||
- Grafana 容器会安装 `frser-sqlite-datasource` 插件
|
||||
- Grafana 会读取 `/etc/grafana/provisioning/datasources/` 下的 datasource YAML
|
||||
- Grafana 会读取 `/etc/grafana/provisioning/dashboards/provider.yaml`
|
||||
- Grafana 会从 `/var/lib/grafana/dashboards/` 自动导入两个 dashboard JSON
|
||||
- 现有 Grafana named volume 继续负责保存 Grafana 运行态数据,不会覆盖 repo 内的 dashboard 与 provisioning 文件
|
||||
|
||||
## Container Image CI
|
||||
|
||||
项目提供了一个 release image workflow:
|
||||
@@ -411,9 +351,16 @@ pytest
|
||||
|
||||
当前测试包含:
|
||||
|
||||
- app 基本启动测试
|
||||
- `/status` endpoint 测试
|
||||
- 登录 / session 基础流程测试
|
||||
- app 启动与 `/status` 检查
|
||||
- 登录 / session / 鉴权流程
|
||||
- runtime config 读写
|
||||
- public IPv4 monitor
|
||||
- SMTP 配置与测试发信
|
||||
- location / poo recorder 端点
|
||||
- Home Assistant inbound 集成
|
||||
- TickTick OAuth
|
||||
- 部署与迁移(`run_migrations`)
|
||||
- legacy 数据迁移脚本(`migrate_legacy_data`)
|
||||
|
||||
## OpenAPI 导出
|
||||
|
||||
|
||||
Reference in New Issue
Block a user