diff --git a/.codex/skills/iti-flask-framework/SKILL.md b/.codex/skills/iti-flask-framework/SKILL.md new file mode 100644 index 0000000..5455223 --- /dev/null +++ b/.codex/skills/iti-flask-framework/SKILL.md @@ -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。 diff --git a/.codex/skills/iti-flask-framework/agents/openai.yaml b/.codex/skills/iti-flask-framework/agents/openai.yaml new file mode 100644 index 0000000..76510f4 --- /dev/null +++ b/.codex/skills/iti-flask-framework/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "iTi-Flask 框架" + short_description: "iTi-Flask 框架开发指南" + default_prompt: "使用 $iti-flask-framework 修改或审查 iTi-Flask 框架代码。" diff --git a/README.md b/README.md index 99e019a..4b7ae8f 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md.jinja b/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md.jinja new file mode 100644 index 0000000..2abed3e --- /dev/null +++ b/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/SKILL.md.jinja @@ -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//`。 + +## 运行规则 + +- 业务路由放在项目模块内。 +- 项目表和 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`。 diff --git a/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/agents/openai.yaml.jinja b/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/agents/openai.yaml.jinja new file mode 100644 index 0000000..3e0a23f --- /dev/null +++ b/copier-template/.codex/skills/{{ project_slug | lower | replace('_', '-') }}-project/agents/openai.yaml.jinja @@ -0,0 +1,4 @@ +interface: + display_name: "{{ project_name }} 项目" + short_description: "{{ project_name }} 业务项目指南" + default_prompt: "使用 ${{ project_slug | lower | replace('_', '-') }}-project 修改或审查 {{ project_name }} 业务项目。" diff --git a/copier-template/README.md.jinja b/copier-template/README.md.jinja index 9824a31..ada470f 100644 --- a/copier-template/README.md.jinja +++ b/copier-template/README.md.jinja @@ -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 diff --git a/copier-template/app.cmd.jinja b/copier-template/app.cmd.jinja index 3fb1484..83386c7 100644 --- a/copier-template/app.cmd.jinja +++ b/copier-template/app.cmd.jinja @@ -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 diff --git a/copier-template/app.sh.jinja b/copier-template/app.sh.jinja index 6526721..fe213c7 100644 --- a/copier-template/app.sh.jinja +++ b/copier-template/app.sh.jinja @@ -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 ;; diff --git a/copier-template/{{ _copier_conf.answers_file }}.jinja b/copier-template/{{ _copier_conf.answers_file }}.jinja new file mode 100644 index 0000000..d0f5d97 --- /dev/null +++ b/copier-template/{{ _copier_conf.answers_file }}.jinja @@ -0,0 +1 @@ +{{ _copier_answers|to_nice_yaml -}} diff --git a/copier-template/copier.yml b/copier.yml similarity index 83% rename from copier-template/copier.yml rename to copier.yml index bd71896..e408170 100644 --- a/copier-template/copier.yml +++ b/copier.yml @@ -1,3 +1,13 @@ +_subdirectory: copier-template +_exclude: + - copier.yml + - "~*" + - "*.py[co]" + - __pycache__ + - .git + - .DS_Store + - .svn + project_name: type: str help: 业务项目显示名称 diff --git a/docs/AUDIT.md b/docs/AUDIT.md index 5d7f8a7..4eab929 100644 --- a/docs/AUDIT.md +++ b/docs/AUDIT.md @@ -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"} ``` ## 操作日志 diff --git a/docs/COPIER_TEMPLATE.md b/docs/COPIER_TEMPLATE.md index ae4c0c6..faf2dc6 100644 --- a/docs/COPIER_TEMPLATE.md +++ b/docs/COPIER_TEMPLATE.md @@ -1,7 +1,24 @@ # Copier 模板 +当前框架仓库根目录是 Copier 模板源。 +`copier.yml` 通过 `_subdirectory: copier-template` 指向实际模板目录。 `copier-template` 生成 FastAPI 业务后端骨架。 模板只引用框架包,不复制框架源码。 +模板会为生成项目渲染项目 skill。 +生成后的路径是: + +```text +.codex/skills/-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 由业务项目维护。 diff --git a/docs/MIGRATIONS.md b/docs/MIGRATIONS.md index aaf491a..1b34ad9 100644 --- a/docs/MIGRATIONS.md +++ b/docs/MIGRATIONS.md @@ -1,7 +1,6 @@ # 数据库迁移 -使用原生 Alembic。 -不再使用 Flask-Migrate。 +iTi-Flask 使用 Alembic 管理数据库 schema。 ## 规则 diff --git a/docs/README.md b/docs/README.md index ebc95da..5310a17 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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`。 diff --git a/docs/TESTING_DEPLOYMENT.md b/docs/TESTING_DEPLOYMENT.md index 9c375d6..23893ee 100644 --- a/docs/TESTING_DEPLOYMENT.md +++ b/docs/TESTING_DEPLOYMENT.md @@ -6,13 +6,13 @@ ## 本地轻量验证 ```bash -cd /root/Projects/iTi/iTi-Flask +cd /iTi-Flask uv run pytest -q -cd /root/Projects/iTi/iTi-System +cd /iTi-System uv run pytest -q -cd /root/Projects/iTi/hsyh-erp +cd /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; ``` 执行: diff --git a/scripts/iti.cmd b/scripts/iti.cmd index 166b68a..ceda3f8 100644 --- a/scripts/iti.cmd +++ b/scripts/iti.cmd @@ -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 diff --git a/scripts/iti.sh b/scripts/iti.sh index 37be132..1f19c7b 100644 --- a/scripts/iti.sh +++ b/scripts/iti.sh @@ -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"