Add project template sync workflow

main
NoahLan 2 weeks ago
parent 49a0a491e8
commit 15fa544bca

@ -0,0 +1,79 @@
---
name: iti-flask-framework
description: iTi-Flask 框架 skill。用于当前 iTi-Flask 框架仓库内的框架代码、框架文档、Copier 模板行为、应用工厂、配置、模块协议、鉴权、响应 envelope、服务客户端、任务、迁移、审计、存储、日志、测试和发布打包。不要用于 iTi-System 系统域业务修改,也不要用于模板生成项目的具体业务逻辑。
---
# iTi-Flask 框架
只用于 iTi-Flask 框架仓库。
iTi-Flask 是 FastAPI 后端框架基座。
## 边界
- iTi-Flask 只写框架能力。
- 不把系统域业务放进框架。
- 不把具体模板生成项目写成框架行为。
- `iti-system` 是外部可选系统业务包。
- Copier 模板会为生成项目渲染独立项目 skill。
## 代码入口
- `iti/app.py``create_app`、中间件、错误处理、自动 envelope、生命周期。
- `iti/config.py`dataclass 配置、`.env` 加载、MySQL 默认值。
- `iti/db/*`SQLAlchemy 2 base/session、Alembic metadata。
- `iti/auth/*`JWT、Principal、Actor、权限依赖、服务 token 依赖。
- `iti/modules/*`:模块协议、权限元数据、菜单 seed 元数据。
- `iti/responses/*`envelope、raw response 逃逸。
- `iti/service_client/*`:同步 HTTP JSON 客户端和注册表。
- `iti/tasks/*`:单进程任务注册和 runner。
- `iti/audit.py`:审计事件发送器,不拥有系统日志表。
- `iti/storage/*`:存储后端接口和实现。
- `copier-template/`:业务项目模板。
- `docs/`:人类阅读的精简参考。
## 修改规则
- 先读现有代码,再改文档或行为。
- 配置继续使用当前 dataclass 风格。
- JSON API 默认兼容 envelope除非路由明确 raw。
- 保留 raw 默认值:`/health`、`/ready`、`/docs`、`/openapi.json`、`/redoc`。
- 模块元数据使用 `ModulePermission``ModuleMenuSeed`
- migration 归生成项目所有。框架不要静默接管业务项目 migration 流。
- 审计保持异步、非阻塞。框架只发事件,接收方在框架外。
- 不为未发生的需求加宽泛兼容层。
## 模板规则
- 模板变更在 `copier-template/`
- Copier 模板源入口是仓库根目录 `copier.yml`,实际模板目录由 `_subdirectory: copier-template` 指定。
- 模板输出保持通用 FastAPI 业务后端骨架。
- 模板内不要写具体业务域知识。
- 模板结构、命令或生成文件变化时,同步更新:
- `copier.yml`
- `copier-template/README.md.jinja`
- `docs/COPIER_TEMPLATE.md`
- `copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md.jinja`
- 需要保持一致的已生成项目 skill 副本
- 生成项目必须保留 `.copier-answers.yml`,否则不能用 `copier update` 同步模板。
- 已生成项目同步框架依赖用 `./app.sh framework-sync`
- 已生成项目检查和同步模板用 `./app.sh template-check`、`./app.sh template-update`。
## 命令
- 安装框架开发依赖:`./scripts/iti.sh install`
- 运行框架测试:`./scripts/iti.sh test`
- 运行检查:`./scripts/iti.sh check`
- 启动最小应用:`./scripts/iti.sh serve 8000`
- 生成业务项目:`./scripts/iti.sh make-app ../my-business-app my_business_app`
- 生成带系统包的业务项目:`./scripts/iti.sh make-system-app ../my-system-app my_system_app`
Windows 使用 `scripts\iti.cmd`
## 文档
人类文档保持短。
文档只放稳定事实和命令入口。
细节优先从代码确认。
代码、架构、命令、模块协议、模板输出或验证流程变化时,同步更新这个 skill。

@ -0,0 +1,4 @@
interface:
display_name: "iTi-Flask 框架"
short_description: "iTi-Flask 框架开发指南"
default_prompt: "使用 $iti-flask-framework 修改或审查 iTi-Flask 框架代码。"

@ -1,7 +1,12 @@
# iTi-Flask
iTi-Flask 是 FastAPI 后端框架基座。
名称保留历史包名,运行时已经不依赖 Flask/APIFlask。
AI 修改框架代码或文档时优先读:
```text
.codex/skills/iti-flask-framework/SKILL.md
```
它提供业务项目常用的通用能力:
@ -75,6 +80,14 @@ cd ../my-business-app
./app.sh serve 8000
```
同步框架依赖和模板骨架:
```bash
./app.sh framework-sync
./app.sh template-check
./app.sh template-update
```
`iti-system`
```bash

@ -0,0 +1,77 @@
---
name: {{ project_slug | lower | replace('_', '-') }}-project
description: "{{ project_name }} 业务项目 skill。用于当前由 iTi-Flask Copier 模板生成的业务后端项目,包括 app.py、config.py、app.sh/app.cmd、pyproject.toml、migrations、tests、modules、models、服务客户端、iTi-Flask 集成{% if include_system %}、iTi-System 注册{% endif %}和项目本地文档。不要写入具体业务域知识。"
---
# {{ project_name }} 业务项目
用于当前业务项目。
本项目由 iTi-Flask Copier 模板生成。
这个 skill 只描述当前项目的通用工程结构。
具体业务知识写在项目 README/docs 或对应业务模块文档里。
## 边界
- 保持为当前业务后端项目的工程规则。
- 不加入具体业务域或客户专属业务知识。
- 框架行为看 iTi-Flask 依赖和项目当前代码。
{% if include_system -%}
- 系统域能力来自 iTi-System当前项目已注册系统包。
{% else -%}
- 当前项目未默认注册 iTi-System。需要系统域能力时再显式引入。
{% endif -%}
- 修改代码、架构、目录结构、脚本命令或测试方式后,同步更新这个 skill。
- 同步框架依赖用 `./app.sh framework-sync`。
- 检查和同步框架模板用 `./app.sh template-check`、`./app.sh template-update`。
## 项目结构
- `app.py`:导入 `config`,注册模块,创建 FastAPI app。
- `config.py`:项目本地配置映射。
- `{{ project_slug }}/modules/`:业务模块。
- `{{ project_slug }}/models/`:项目 SQLAlchemy 模型。
- `migrations/`:项目自己的 Alembic migration 流。
- `tests/`pytest 路由和行为测试。
- `app.sh`Linux/macOS/Git Bash 命令入口。
- `app.cmd`Windows CMD 命令入口。
- `pyproject.toml`:包信息和依赖。
- `.copier-answers.yml`Copier 模板更新锚点。
## 模块模式
业务模块通过 iTi 模块协议注册:
- `register_routes(app)`:挂载 FastAPI router。
- `register_permissions(app)`:用 `ModulePermission` 声明权限元数据。
- `register_menu_seed(app)`:用 `ModuleMenuSeed` 声明后台菜单 seed 元数据。
- `register_tasks(app)`:按需注册本地任务。
- `init_app(app)`:按需接入配置或服务客户端。
业务模块优先放在 `{{ project_slug }}/modules/<module_name>/`。
## 运行规则
- 业务路由放在项目模块内。
- 项目表和 migration 留在当前项目。
- 默认使用框架 envelope除非路由明确 raw。
- 服务间内部 API 使用 service token。
- 项目级测试使用 `fastapi.testclient.TestClient`。
{{ "- seed 前先同步 iTi-System migration。\n" if include_system else "" }}
## 命令
- 安装开发依赖:`./app.sh install`
- 同步框架依赖:`./app.sh framework-sync`
- 检查模板更新:`./app.sh template-check`
- 同步模板骨架:`./app.sh template-update`
- 运行测试:`./app.sh test`
- 本地启动:`./app.sh serve 8000`
- 创建 migration`./app.sh migration "alice add order table"`
- 执行 migration`./app.sh migrate`
- 查看 Alembic heads`./app.sh heads`
- 查看当前 Alembic 版本:`./app.sh current`
- 初始化项目:`./app.sh init`
{{ "系统包相关命令:\n\n- 同步系统 migration`./app.sh system-sync`\n- 初始化或更新系统 seed`./app.sh system-seed`\n- 初始化系统项目:`./app.sh init-system`\n\n" if include_system else "" -}}
Windows 使用 `app.cmd`。

@ -0,0 +1,4 @@
interface:
display_name: "{{ project_name }} 项目"
short_description: "{{ project_name }} 业务项目指南"
default_prompt: "使用 ${{ project_slug | lower | replace('_', '-') }}-project 修改或审查 {{ project_name }} 业务项目。"

@ -3,6 +3,15 @@
FastAPI 业务后端项目。
由 iTi-Flask Copier 模板生成。
AI 修改本项目时优先读:
```text
.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md
```
该 skill 只描述本项目的通用工程规则。
具体业务知识写在本项目自己的 README/docs。
## 依赖
默认使用私有 Git 依赖。
@ -42,6 +51,30 @@ app.cmd init-system
./app.sh test
```
## 同步更新
同步框架包:
```bash
./app.sh framework-sync
```
检查模板:
```bash
./app.sh template-check
```
按模板更新项目骨架:
```bash
./app.sh template-update
```
模板更新会改 `app.py`、`config.py`、`app.sh`、`app.cmd`、示例模块、测试和项目 skill 等模板拥有的文件。
该命令跟随模板仓库 `HEAD`。
执行前先提交或暂存当前项目改动,执行后检查 diff。
## 数据库迁移
```bash

@ -20,6 +20,9 @@ if "%COMMAND%"=="help" goto help
if "%COMMAND%"=="-h" goto help
if "%COMMAND%"=="--help" goto help
if "%COMMAND%"=="install" goto install
if "%COMMAND%"=="framework-sync" goto framework_sync
if "%COMMAND%"=="template-check" goto template_check
if "%COMMAND%"=="template-update" goto template_update
if "%COMMAND%"=="test" goto test
if "%COMMAND%"=="serve" goto serve
if "%COMMAND%"=="migrate" goto migrate
@ -44,6 +47,9 @@ echo.
echo 常用命令:
echo help 显示帮助
echo install 安装开发依赖uv sync --extra dev
echo framework-sync 同步 iTi-Flask{% if include_system %} / iTi-System{% endif %} 依赖
echo template-check 检查 Copier 模板是否有更新
echo template-update 按 Copier 模板更新项目骨架
echo test 运行测试uv run pytest -q
echo serve [端口] 本地启动,默认 8000
echo migrate 执行 Alembic upgrade head
@ -71,6 +77,18 @@ exit /b 2
uv sync --extra dev
goto end
:framework_sync
uv sync --extra dev --upgrade-package iti-flask{% if include_system %} --upgrade-package iti-system{% endif %}
goto end
:template_check
uvx copier update --defaults --pretend --vcs-ref HEAD "%ROOT_DIR%"
goto end
:template_update
uvx copier update --defaults --vcs-ref HEAD "%ROOT_DIR%"
goto end
:test
uv run pytest -q
goto end

@ -23,6 +23,9 @@ show_help() {
常用命令:
help 显示帮助
install 安装开发依赖uv sync --extra dev
framework-sync 同步 iTi-Flask{% if include_system %} / iTi-System{% endif %} 依赖
template-check 检查 Copier 模板是否有更新
template-update 按 Copier 模板更新项目骨架
test 运行测试uv run pytest -q
serve [端口] 本地启动,默认 8000
migrate 执行 Alembic upgrade head
@ -53,6 +56,15 @@ case "$command" in
install)
uv sync --extra dev
;;
framework-sync)
uv sync --extra dev --upgrade-package iti-flask{% if include_system %} --upgrade-package iti-system{% endif %}
;;
template-check)
uvx copier update --defaults --pretend --vcs-ref HEAD "$ROOT_DIR"
;;
template-update)
uvx copier update --defaults --vcs-ref HEAD "$ROOT_DIR"
;;
test)
uv run pytest -q
;;

@ -0,0 +1 @@
{{ _copier_answers|to_nice_yaml -}}

@ -1,3 +1,13 @@
_subdirectory: copier-template
_exclude:
- copier.yml
- "~*"
- "*.py[co]"
- __pycache__
- .git
- .DS_Store
- .svn
project_name:
type: str
help: 业务项目显示名称

@ -15,7 +15,7 @@ class DevConfig(BaseDevConfig):
self.audit_service_name = "audit"
self.services = {
"audit": {
"base_url": "http://hsyh-mes-phase2.local",
"base_url": "http://business-app.local",
"token": "change-me",
}
}
@ -24,7 +24,7 @@ class DevConfig(BaseDevConfig):
接收方需要把同一个 token 配进 `service_tokens`
```python
self.service_tokens = {"hsyh-erp": "change-me"}
self.service_tokens = {"internal": "change-me"}
```
## 操作日志

@ -1,7 +1,24 @@
# Copier 模板
当前框架仓库根目录是 Copier 模板源。
`copier.yml` 通过 `_subdirectory: copier-template` 指向实际模板目录。
`copier-template` 生成 FastAPI 业务后端骨架。
模板只引用框架包,不复制框架源码。
模板会为生成项目渲染项目 skill。
生成后的路径是:
```text
.codex/skills/<project-slug>-project/SKILL.md
```
模板源文件是:
```text
copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md.jinja
```
模板结构、脚本命令或模块约定变化时,同步更新该模板 skill。
现有模板生成项目需要按当前项目名刷新自己的 skill。
## 生成
@ -88,3 +105,36 @@ app.cmd init-system
./app.sh system-seed
./app.sh init-system
```
## 同步更新
业务项目同步框架依赖:
```bash
./app.sh framework-sync
```
该命令执行 `uv sync --upgrade-package iti-flask`
`iti-system` 的模板项目会同时升级 `iti-system`
业务项目检查模板版本:
```bash
./app.sh template-check
```
该命令执行 `uvx copier update --defaults --pretend --vcs-ref HEAD`
业务项目按模板更新项目骨架:
```bash
./app.sh template-update
```
该命令执行 `uvx copier update --defaults --vcs-ref HEAD`
它依赖 `.copier-answers.yml` 里的 `_src_path``_commit`
模板更新前,业务项目工作区必须干净。
执行后检查 diff再运行测试。
模板拥有的文件包括 `app.py`、`config.py`、`app.sh`、`app.cmd`、`pyproject.toml`、`migrations/`、示例模块、示例测试、README 和项目 skill。
业务项目自己的模块、模型、API 文档和业务 README 由业务项目维护。

@ -1,7 +1,6 @@
# 数据库迁移
使用原生 Alembic。
不再使用 Flask-Migrate。
iTi-Flask 使用 Alembic 管理数据库 schema。
## 规则

@ -1,33 +1,23 @@
# iTi-Flask 文档
iTi-Flask 文档只描述框架自身。
AI 修改框架时优先读 `.codex/skills/iti-flask-framework/SKILL.md`
## 人类入口
- [README](../README.md)
- [架构](ARCHITECTURE.md)
- [配置](CONFIGURATION.md)
- [模块协议](MODULES.md)
- [服务客户端](SERVICE_CLIENT.md)
- [审计](AUDIT.md)
- [任务运行器](TASKS.md)
- [数据库迁移](MIGRATIONS.md)
- [种子数据](SEEDS.md)
- [Copier 模板](COPIER_TEMPLATE.md)
- [前端管理端接口契约](FRONTEND_ADMIN_API_CONTRACT.md)
- [测试与部署方案](TESTING_DEPLOYMENT.md)
- [测试与部署](TESTING_DEPLOYMENT.md)
## 常用命令
## 命令
```bash
./scripts/iti.sh help
./scripts/iti.sh install
./scripts/iti.sh test
./scripts/iti.sh check
```
生成业务项目:
```bash
./scripts/iti.sh make-app ../my-business-app my_business_app
./scripts/iti.sh make-system-app ../my-system-app my_system_app
```
Windows 使用 `scripts\iti.cmd`

@ -6,13 +6,13 @@
## 本地轻量验证
```bash
cd /root/Projects/iTi/iTi-Flask
cd <workspace>/iTi-Flask
uv run pytest -q
cd /root/Projects/iTi/iTi-System
cd <workspace>/iTi-System
uv run pytest -q
cd /root/Projects/iTi/hsyh-erp
cd <workspace>/my-business-app
uv run pytest -q
```
@ -24,7 +24,7 @@ uv run pytest -q
```sql
CREATE DATABASE iti_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE hsyh_erp_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE my_business_app_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
执行:

@ -51,7 +51,7 @@ echo migrate 执行当前仓库 Alembic upgrade head
echo migration ^<说明^> 生成 migration说明建议以作者名开头
echo heads 查看 Alembic heads
echo current 查看当前 Alembic 版本
echo make-app ^<目录^> [包名] 从 copier-template 生成业务项目
echo make-app ^<目录^> [包名] 从当前框架仓库模板生成业务项目
echo make-system-app ^<目录^> [包名] 生成带 iti-system 的业务项目
echo.
echo 示例:
@ -128,7 +128,7 @@ if "%PACKAGE%"=="" (
set "PACKAGE=!PACKAGE:-=_!"
)
for %%I in ("%TARGET%") do set "PROJECT_NAME=%%~nxI"
uvx copier copy --defaults "%CD%\copier-template" "%TARGET%" -d project_name="!PROJECT_NAME!" -d project_slug="!PACKAGE!" -d include_system="%INCLUDE_SYSTEM%"
uvx copier copy --defaults --vcs-ref HEAD "%CD%" "%TARGET%" -d project_name="!PROJECT_NAME!" -d project_slug="!PACKAGE!" -d include_system="%INCLUDE_SYSTEM%"
goto end
:end

@ -30,7 +30,7 @@ iTi-Flask 开发脚本
migration <说明> 生成 migration说明建议以作者名开头
heads 查看 Alembic heads
current 查看当前 Alembic 版本
make-app <目录> [包名] copier-template 生成业务项目
make-app <目录> [包名]当前框架仓库模板生成业务项目
make-system-app <目录> [包名] 生成带 iti-system 的业务项目
示例:
@ -98,7 +98,7 @@ case "$command" in
if [ "$command" = "make-system-app" ]; then
include_system=true
fi
uvx copier copy --defaults "$ROOT_DIR/copier-template" "$target" \
uvx copier copy --defaults --vcs-ref HEAD "$ROOT_DIR" "$target" \
-d project_name="$(basename "$target")" \
-d project_slug="$package" \
-d include_system="$include_system"

Loading…
Cancel
Save