jiang 90b02057bc
Generic Container CI/CD / test-build-publish (push) Successful in 1m13s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 1m13s
feat(projects): automate project infrastructure provisioning
2026-09-11 10:57:51 +08:00
2025-10-26 08:54:35 +08:00

TJWaterServerBinary 内部后端

TJWaterServerBinary 是 TJWater 内部版 Python 后端,基于 FastAPI 提供认证、项目、管网、模拟、爆管、漏损、SCADA 和地图服务集成能力。该仓库用于内部开发和完整功能维护。

技术栈

  • Python 3.12
  • FastAPI / Uvicorn
  • Pydantic / SQLAlchemy / psycopg
  • PostgreSQL、PostGIS、TimescaleDB
  • WNTR、EPANET、Cython、科学计算与空间分析依赖
  • pytest

目录结构

app/main.py           FastAPI 入口
app/api/              HTTP API 路由
app/auth/             认证和权限上下文
app/core/             配置、日志和基础设施初始化
app/domain/           领域模型和 Pydantic schema
app/infra/            数据库、EPANET 和外部集成
app/services/         业务服务编排
app/algorithms/       管网算法、模拟、爆管、漏损、清洗和健康分析
app/native/           本地管网数据读写与转换
tests/                后端测试
resources/            SQL、模板和示例资源
infra/docker/         Docker Compose 编排

本地开发

推荐使用已有 conda 环境:

conda run -n server python -m pytest tests/unit tests/auth -q
conda run -n server uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

如需要进入环境:

conda activate server

常用命令

conda run -n server python -m pytest tests -q
conda run -n server python scripts/run_server.py
docker build -t tjwater-server:local .
docker compose -f infra/docker/docker-compose.yml config
  • pytest:运行自动化测试。
  • scripts/run_server.py:使用项目脚本启动服务。
  • docker build:构建后端镜像。
  • docker compose config:检查 compose 配置和变量展开。

开发规范

  • Python 文件、函数、变量、Pydantic 字段、JSON body 字段和 query 参数使用 snake_case
  • Python 类和 Pydantic 模型使用 PascalCase
  • 新 HTTP 路径使用 kebab-case,例如 /api/v1/pressure-status/analyze
  • 优先复用现有 FastAPI/service/repository 边界。
  • 不要把临时数据、数据库 dump、日志或本地运行产物纳入提交。

项目数据库路由

项目级 REST 请求通过 X-Project-Id 解析元数据中的数据库配置:

  • biz_data DSN 用于管网业务数据。每个物理业务库使用同名 _template 数据库,通过逻辑订阅只同步 network schema;模拟临时库从该项目模板克隆。WNDB_SCHEMA_TEMPLATE_DB_NAME(当前为 tjwater_v2_schema_template)仅用于创建空业务库和 INP 导入暂存库。
  • iot_data DSN 用于 TimescaleDB,始终使用元数据配置的完整 DSN,不再从项目代码推导数据库名。
  • 元数据、业务库和 TimescaleDB 可以部署在同一主机,也可以分别部署。

完整新建供水项目使用 POST /api/v1/admin/project-provisions,以 multipart/form-data 同时提交 name、小写 code、可选的 descriptiongs_workspacemap_zoom 和 INP file。工作流会按顺序完成:

  1. EPANET 校验 INP,并从空结构模板创建业务库、导入模型;
  2. 创建同名 _template,复制 32 张 network 表并建立逻辑订阅;
  3. TIMESCALEDB_SCHEMA_TEMPLATE_DB_NAME 创建空时序库;
  4. 创建 GeoServer 工作空间、PostGIS 数据存储和 7 个 GIS 图层,将客户端缓存设为 GEOSERVER_CLIENT_CACHE_SECONDS
  5. 最后在一个元数据事务中写入项目、两条加密数据库路由和创建者成员关系,并将项目设为 active

基础设施任一步失败时按 GeoServer、时序库、管网模板、业务库的逆序清理;元数据提交失败也执行同样清理。旧 POST /admin/projects 仅保留给已经由外部流程创建好的资源登记使用,并已标记为 deprecated。

使用模板复制或临时方案库的模拟功能时,biz_data 账号必须具备数据库创建和删除权限;只有显式删除项目时才会终止该项目的现有数据库会话,普通复制不会主动中断复制源会话。

测试与发布

提交前根据改动范围运行最小有效测试:

conda run -n server python -m pytest tests/unit tests/auth -q

发布镜像前建议运行:

docker build -t tjwater-server:local .

Gitea 包工作流位于 .gitea/workflows/package.yml,通常由 tag 触发构建、推送镜像并通知部署 webhook。

安全规则

不要提交 .env、客户数据、数据库 dump、日志、生成缓存、db_inp/temp/data/ 或本地密钥。CI/CD 凭据应放在 Gitea secrets 和仓库变量中。

S
Description
No description provided
Readme
346 MiB
Languages
Python 98.8%
CSS 0.6%
Shell 0.3%
PLpgSQL 0.1%
FreeMarker 0.1%