<!-- generated-by: gsd-doc-writer -->
# 第一个业务模块：从分类定义走通 Core

本教程以现有 `ineed-config-category` 为可编译参考，重点学习分类定义及其简单/树形分类值。每层都链接到实际源码，避免维护一套与产品 API 脱节的教程代码。完成阅读后，可按第 8 步创建自己的模块。

前提：[环境准备](prerequisites.md)。先理解[架构](../concepts/architecture.md)和[对象模型](../concepts/object-model.md)。

## 1. 先跑通框架链路

在 Core 根目录运行：

```bash
mvn -pl ineed-core-tests/ineed-core-test-webmvc -am \
  -Dtest=WebMvcJdbcBusinessChainTest,WebMvcJdbcSearchBusinessChainTest \
  -Dsurefire.failIfNoSpecifiedTests=false test
```

观察 Surefire 报告，确认匹配用例确实执行。打开 [WebMvcJdbcBusinessChainTest](../../ineed-core-tests/ineed-core-test-webmvc/src/test/java/com/ineed/core/webmvc/support/WebMvcJdbcBusinessChainTest.java)，沿 `newHarness()` 找到 Controller → Service → Manager → TestRepository。

这个示例使用内存仓储，证明能力组合与生命周期；尚未启动 HTTP，也不访问真实 MySQL。先能解释这条链，再进入真实持久化实现。

## 2. 读需求与 SQL

真实输入：[分类需求](../../../../design/ineed-config/requirements/ineed_category.md)、[分类 SQL](../../../../design/ineed-config/sql/mysql/ineed_category.sql)。这里是分类定义、简单值、树形值和使用记录等对象，不能将所有表机械生成为一套同能力 CRUD。

先列出对象、业务键、父子关系、租户模式、状态开关、删除约束和公开动作。SQL 定义存储约束，需求定义用户可执行的行为，两者需要一致。

## 3. 理解 Maven 骨架

[分类聚合 POM](../../../ineed-modules/ineed-config/ineed-config-category/pom.xml)包含 `core/engine/jpa/jdbc/mybatis-flex/webmvc/engine-reactive/r2dbc/webflux` 对应子模块。

`core` 共享契约；同步 Service 和 Manager 接口在 `engine`；JDBC 实体与持久化实现在 `jdbc`；Web 入口在 `webmvc`。响应式独立装配，复用业务 `core`。

新增能力时首先决定需要哪些接口，不从九个目录复制九套相同业务代码。目录规则见[业务骨架](../project-development/business-module-layout-guide.md)。

## 4. 从入参到持久化

| 层 | 打开实际文件 | 重点看什么 |
| --- | --- | --- |
| AO | [CategoryDefinitionAO](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-core/src/main/java/com/ineed/config/category/contract/ao/CategoryDefinitionAO.java) | applicationKey/categoryType/categoryKey/categoryName 必填；类型限制 SIMPLE/TREE |
| Entity | [JDBC CategoryDefinition](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-jdbc/src/main/java/com/ineed/config/category/jdbc/entity/CategoryDefinition.java) | 基类、表列、GLOBAL_ONLY 全局定义与状态能力 |
| Repository | [CategoryDefinitionRepository](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-jdbc/src/main/java/com/ineed/config/category/jdbc/repository/CategoryDefinitionRepository.java) | fragment 组合、getEntityClass、业务键查询 |
| Converter | [CategoryDefinitionConverter](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-jdbc/src/main/java/com/ineed/config/category/jdbc/converter/CategoryDefinitionConverter.java) | AO/Entity/VO 的转换与定制 |
| Manager | [CategoryDefinitionManager](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-jdbc/src/main/java/com/ineed/config/category/jdbc/manager/CategoryDefinitionManager.java) | operation、converter、Q 表、查询过滤、业务生命周期 |
| Service | [CategoryDefinitionService](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-engine/src/main/java/com/ineed/config/category/service/CategoryDefinitionService.java) | 能力组合、Manager 桥接、读写事务 |
| Controller | [CategoryDefinitionController](../../../ineed-modules/ineed-config/ineed-config-category/ineed-config-category-webmvc/src/main/java/com/ineed/config/category/controller/CategoryDefinitionController.java) | 请求路径、标准能力、权限和自定义接口 |

学习样例中的能力组合与已核实行为；样例仓库也会持续演进，历史格式或个别旧写法不覆盖[现行规范](../standards/README.md)。

## 5. 增加查询条件的练习

以现有 `categoryName` 条件为参照：定位 Query 字段 → JDBC Manager 的 `appendWhereOfQuery` → Q 类型字段 → 查询结果 VO。复制到自己的模块时，用自己的字段和规则。

至少验证空条件、部分匹配、分页、逻辑删除过滤和租户可见范围。分类定义是全局数据，不能套用租户私有数据的不可见断言；自己的模块应按实体模式补齐越界读写测试。只新增 Query 属性而不添加持久化条件，会出现接口接收参数但结果不变的问题。

## 6. 业务动作的练习

先阅读 Service 中已有的自定义方法，标记它调用了哪些 Manager、何处开启事务、失败如何传播。为自己的模块增加需要同时修改主表和关系表的动作时：

1. 需求定义允许状态、权限、重复执行和失败结果。
2. AO 表达动作输入，Service 组织用例，Manager 实现对象规则。
3. 仓储封装关系写入/查询，不能在 Controller 或 Service 拼 SQL。
4. 制造第二步失败，验证第一步回滚；同时验证成功结果和越权拒绝。

详见[事务](../guides/transaction-and-concurrency.md)与[分层](../project-development/custom-business-layering-guide.md)。

## 7. 验证真实业务代码与其他技术栈

在 config 仓库运行选定业务测试，需已解析到匹配版本的 Core 依赖：

```bash
mvn -f "$INEED_JAVA_ROOT/ineed-modules/ineed-config/pom.xml" \
  -pl ineed-config-category/ineed-config-category-engine,ineed-config-category/ineed-config-category-engine-reactive,ineed-config-category/ineed-config-category-webflux \
  -am '-Dtest=Phase61*Category*,PersistenceConverterBoundaryTest' \
  -Dsurefire.failIfNoSpecifiedTests=false test
```

必须选择具体代码子模块；仅 `-pl ineed-config-category` 选中聚合 POM，不能据此认为所有子模块测试已运行。

然后对照 JPA、MyBatis-Flex、R2DBC 中同名业务对象，比较持久化实现与响应式链；业务目标和断言保持一致。可从[例子索引](../examples/README.md)跳转各栈框架测试。

最后进入[应用运行与验证](run-and-verify.md)，核对真实数据库、Spring 装配、HTTP 和身份权限。这与前面的框架/业务测试分别报告。

## 8. 创建自己的模块

按[需求模板](../project-development/module-requirements-template.md)完成对象表与行为表，按[模块骨架](../project-development/business-module-layout-guide.md)建立 POM/目录，先实现一个对象的端到端路径，再添加关系和业务动作。

逐项替换域名、包名、资源 key、表名、错误码和语言资源。错误码从[全局登记](../../../../design/standards/error-code-registry.md)取得。聚合/BOM、启动器依赖、组件/仓储扫描都要纳入接入检查。

完成标准：能够解释每层职责，并独立完成字段、查询、业务动作的修改和相应验证。不是只把样例类名替换后编译成功。
