# 模块协议 模块用于业务项目内的代码边界。 模块运行在同一个 Flask 进程内。 它不是独立服务。 ## 适用范围 适合做模块的能力: - 某个业务项目内部的业务域。 - 需要独立路由、service 和 model 目录的功能。 - 多人并行开发,但共享同一个部署单元和数据库。 不适合做模块的能力: - 需要被多个项目跨进程复用。 - 有独立数据源。 - 有独立发布节奏。 - 业务项目不应该理解其内部细节。 这类能力应拆成 HTTP JSON 服务。 ERP Service 属于服务候选。 ## 注册方式 业务项目在 `app.py` 传入模块实例: ```python from iti.applications import create_app from my_project.modules.example import ExampleModule app = create_app(modules=[ExampleModule()]) ``` 模块可以声明这些阶段: ```python class ExampleModule: name = "example" def init_app(self, app): ... def register_commands(self, app): ... def register_routes(self, app): ... def register_permissions(self, app): ... def register_menu_seed(self, app): ... ``` 执行顺序固定: 1. `init_app` 2. `register_commands` 3. `register_routes` 4. `register_permissions` 5. `register_menu_seed` ## 权限声明 模块通过注册表声明权限码: ```python from iti.modules import ModulePermission, get_module_registry def register_permissions(self, app): registry = get_module_registry(app) registry.register_permission( ModulePermission( code="example:item:list", name="示例列表", description="查看示例模块数据", ) ) ``` 权限码本身不单独落表。 实际授权仍然来自菜单 `auth_code`。 ## 菜单 Seed 模块可以声明菜单 seed: ```python from iti.applications.common.enums import MenuTypeEnum from iti.modules import ModuleMenuSeed, get_module_registry def register_menu_seed(self, app): registry = get_module_registry(app) registry.register_menu_seed( ModuleMenuSeed( id="example-menu-root", name="Example", type=MenuTypeEnum.MENU.value, path="/example", component="/example/list", auth_code="example:item:list", meta={"title": "示例模块", "icon": "carbon:application"}, sort=100, ) ) ``` 菜单 seed 只是模块元数据。 iTi-Flask 只负责收集,不负责写入系统表。 如果业务项目引入 `iti-system`,可以由 `iti-system` seed 把模块菜单写入 `sys_menu`,并默认绑定到 `ADMIN`。 ## 边界 模块可以: - 注册蓝图。 - 注册 CLI 命令。 - 声明权限。 - 声明菜单 seed。 - 使用业务项目自己的 model。 模块不应该: - 修改框架内部实现。 - 直接导入其它模块内部 model 或 service。 - 自建独立 migration 流。 - 在系统 seed 中写业务数据。 业务 model 仍然集中在业务项目 `models/` 下。 整个业务项目只保留一条 migration 流。