Type: research Status: resolved Blocked by: ## Question crm-opportunity/crm-customer/crm-rule 里所有指向"项目"的桩(`ConvertToProjectCmd`、`ProjectOwnerSyncPort`、`NoopProjectOwnerSyncPortImpl`、`ProjectUserTransferPortImpl`、`ProjectRule` 及其 Initializer/Constants)各自期望 crm-project 提供什么?把每个桩的方法签名、入参出参、调用时机整理成一张"接缝契约清单",作为 crm-project 对外 inbound/outbound 端口的硬约束。 这是 AFK 研究:只读代码,不做决策。产出一份 markdown 清单,从 ticket 链接指向。 ## Answer ### 接缝契约清单 #### 1. `ConvertToProjectCmd`(crm-opportunity → crm-project 入站) ``` record ConvertToProjectCmd(Long opportunityId, Long schemeCardId, Long projectId) ``` - **调用时机**:商机转项目时,crm-opportunity 向 crm-project 发起回调 - **语义**:opportunityId 是幂等主键;schemeCardId 选填(哪张方案卡触发);projectId 由 **crm-project 先建项目、再回调商机** 的方式传入 - **crm-project 必须实现**:接收回调后写状态快照 + 操作日志,并把 opportunity 的 `opp_status` 置为 5(STATUS_CONVERTED) #### 2. `ProjectOwnerSyncPort`(crm-customer → crm-project 出站) ```java int syncOwnerByCustomer(Long customerId, Long newOwnerId) ``` - **调用时机**:客户交割/分配时,crm-customer 调用此 port 同步关联项目的 owner - **现状**:Noop 实现已装配(返回 0),项目模块落地后由 crm-project 提供真实 Bean 覆盖 - **crm-project 必须实现**:查出所有 `customer_id = customerId` 的项目行,批量更新 ownerUserId #### 3. `ProjectUserTransferPortImpl`(crm-opportunity/project 共表,用户移交) - **关键结论**:**项目与商机同表 `crm_opportunity`**,以 `opp_status = 5` 区分"项目域" - 用户移交时批量刷 `owner_user_id / owner_name_snapshot / owner_dept_id` 三列 - crm-project **不需要独立实体表**,直接在 Opportunity 表上 `WHERE opp_status=5` 切域 #### 4. `ProjectRule`(crm-rule → crm-project 消费方向) - **ProjectRule 是配置表**(crm-rule 负责 CRUD),crm-project 是**读取方** - 5 区块 JSON 列:阶段别名、拉群人员(7 角色)、冲突拉群规则(5 行)、阶段提醒规则、标底认定规则(9 类型) - crm-project 在以下时机读取:①冲突检测拉群时读 `conflictPullJson`;②阶段流转提醒时读 `stageRemindJson`;③赢单/输单登记时读 `bidConfigJson` #### 总结:crm-project 对外端口 | 方向 | Port | 调用方 | crm-project 角色 | |---|---|---|---| | 入站 | `ConvertToProjectCmd` | crm-opportunity | **实现者**(接收回调,建项目记录) | | 出站被调 | `ProjectOwnerSyncPort` | crm-customer | **实现者**(替换 Noop Bean) | | 共表 | `ProjectUserTransferPortImpl` | crm-auth 用户移交 | **已实现**(无需新增,status=5 切域) | | 读配置 | `ProjectRule` (crm-rule) | — | **消费方**(HTTP 读 or Service 直注入) |