luoweijian
b48fbb8beb
commit
4 days ago
luoweijian
a61031512c
commit
4 days ago
luoweijian
2329f8cf14
commit
5 days ago
luoweijian
acd0d944c7
商机新建接口补齐字段(opp-create-fields 票 01-05)
- 实体加 address + 商机关键联系人快照三列;CreateOpportunityRequest 补 7 字段(项目金额/地址/客户角色/是否主要/关键联系人 id+姓名+公司),remark 展示名改「项目概况」、cityCode 注释放宽(市码或区/县码均可)
- OpportunityIntakeSpec 扩 7 组件;OpportunityIntakeImpl 建档透传落主表,linkPrimaryCustomer 按 isPrimaryIntended 分支(=1 刷主客户冗余并回写 / =0 留空不回写,无空转 UPDATE),customerRole/isPrimaryIntended 空回退 ROLE_INTENDED/1 保持线索转入路径兼容
- OpportunityCreateServiceImpl 翻译 7 新字段进 spec,补 customerId 非空时校验(isPrimaryIntended 必填且仅 1/0、customerRole 必填;customerId 空则忽略);OpportunityCreationPortImpl 显式传 null,LEAD_CONVERT 行为不变(线索转入映射另票)
- 测试:恢复并按新契约更新 OpportunityIntakeImplTest(分支/透传断言),CreateServiceImplTest 补 4 校验用例,OpportunityTest 字段契约同步 4 新列;crm-opportunity 233 测试全绿
- 文档:CONTEXT.md 放宽「关联客户」不变式(创建允许零主要意向客户)+ 新增项目概况/项目详细地址/商机关键联系人词条;api-docs 仓 新建商机.bru 参数表/示例同步
6 days ago
luoweijian
915edfdb9a
feat(opportunity-board): group board by stage display name, drop status filter
- rule: validate display-name uniqueness within a template version on publish (64017)
- rule: add describeStageNames / resolveStageIdsByDisplayName batch contracts
- opportunity: board stops filtering by advancing(2), rows with current_stage_id go on board
- opportunity: boardStageSummary groups by display name, ordered full/empty viewport columns
- opportunity: boardCards takes stageName and returns oppStatus
- tests: rule unit tests + opportunity service tests + H2 board integration test
- docs: sync board Bruno collection (stageName param, oppStatus field, drop stageId)
6 days ago
luoweijian
0d2f74c4ff
解决日志文件的合并冲突
6 days ago
luoweijian
530e3f15d1
stoptrackinglog
6 days ago
luoweijian
d8cd74b0d6
commit
6 days ago
luoweijian
9b136de2c2
commit
6 days ago
luoweijian
32ac2926bf
chore: stop tracking crm-app.log
7 days ago
luoweijian
3149f0d57e
commit
7 days ago
luoweijian
1b1e4ef945
commit
1 week ago
luoweijian
9233a5b32a
commit
1 week ago
luoweijian
5ac7aba65a
commit
1 week ago
luoweijian
3504604b0d
commit
1 week ago
luoweijian
938aed922e
fix(opportunity): 修复新建商机 500 并保护系统预设阶段模板
新建商机因 current_stage_id/stage_template_id/stage_template_version
三列 NOT NULL 无默认值、而无发布中默认阶段模板时静默 return 而崩(500)。
- OpportunityIntakeImpl.applyInitialStage 改 fail-fast:无发布中默认模板
或版本无节点时抛 OpportunityIntakeException(经 seam 译为 HTTP 友好
BusinessErrorException),不再静默产出无阶段脏商机
- 后台阶段配置保护系统预设模板(SEED_STAGE_TPL_CODE=OPP_STAGE_TPL_01):
deleteDraft/disableTemplate 拒绝删除/停用,保证始终有发布中默认模板
- 新增错误码 CODE_STAGE_TPL_SEED_PROTECTED=64018
2 weeks ago
luoweijian
feb8144c19
fix(opportunity): code review 修复5处问题
- PageResult: Sub/Collab 分页接口从 Page<T> 改为 PageResult<T>(硬违规)
- addFollow: 新增后刷新 last_valid_follow_time 回收锚点(Spec Bug)
- deleteFollow: 软删后写 ROW_DELETE oplog(Spec缺失)
- addAttachment: FOLLOW_UP bizType 加10个附件上限校验(Spec缺失)
- OpportunityCollabServiceImpl: 魔法数字2改为 OpportunityStatus.STATUS_ADVANCING(smell)
- OpportunityPoolRuleController: import 分组排序修正(规范)
2 weeks ago
luoweijian
0d5ee62812
feat(opportunity): 商机模块接口整改(票01-06)
- 票01: 修 W-02 NOT NULL 字段默认值 + 补 GET /detail + POST /edit
- 票02: 状态机 11 个 HTTP 接口(claim/assign/pause/resume/release-pool/close/reopen/handover)
- 票03: 详情 Tab 6 子域接口(客户/跟进/勘察/附件/团队/日志)
- 票04: 协作+看板+访问上报 6 个接口
- 票05: 规则族 /versions 端点(阶段模板/方案卡模板/公海规则)
- 票06: 回归验证 33 条接口全通
2 weeks ago
luoweijian
51902312fc
commit
2 weeks ago
luoweijian
7417b835e2
docs(adr): 架构审查候选 #3/#4/#5 重评结论(均不做)
/improve-codebase-architecture 报告余下三候选,#1/#2 落地后逐一重评(/grilling):
- #5 oplog recorder:已被 #1 (ADR-0030) 吸收——两处手搓 writeInitialOplog
随建档机制收敛,现仅 OpportunityIntakeImpl 一处;ADR-0030 记闭环,不立票
- #4 LeadOpportunityConverter:仍不抽——port 侧已瘦成薄 adapter,预期的
事务/补偿复杂度未现,依旧单调用者无杠杆;两处手搓守卫是转商机两阶段时序
的刻意前置拦截、非坏味道;ADR-0022 §4 记重评
- #3 DisplayNameEnricher:不抽——真孪生仅 dictNames 10 行,三源 enricher
会是宽接口+薄实现的 shallow module,与深模块目标相悖;ADR-0022 §4 记重评
2 weeks ago
luoweijian
77cc18bffe
chore: tmp/ 移出版本库 + .gitignore + AGENTS 记录中转链路报错
- git rm --cached tmp/(含误提交的 maven 发行版/数据集/临时日志/脚本),
工作区文件保留;.gitignore 加 tmp/ 防再次误入
- AGENTS.md:中转 provider(127.0.0.1)链路三种同源报错的诊断记录——
Stream ended without finish_reason / HTTP客户端等待超时 / DNS解析异常,
按链路位置与处置差异分列(DNS 拆 turn 无效、只能重试查网络)
2 weeks ago
luoweijian
7415f1e209
docs(adr): 补 ADR-0031 ConvertibleLeadCatalogPort seam + crm-lead CONTEXT 术语
Candidate #2 代码审查(/code-review)收尾:实现(8329911)已落且双轴通过,
但通篇引用的 ADR-0031 从未写下(悬空引用,5+ 文件)。本次补齐:
- docs/adr/0031:记录 crm-lead 声明并自实现的窄 inbound port(收窄 ADR-0029
的 ILeadService 泄漏),与 ADR-0025 PoolLeadOccupationPort 方向相反的同型 seam
- crm-lead/CONTEXT.md:新增「可转商机候选线索目录端口」术语
2 weeks ago
luoweijian
2990484f01
commit
2 weeks ago
luoweijian
83299113e7
refactor(lead/opportunity): ConvertibleLeadCatalogPort 收窄跨域契约(架构审查候选2)
- crm-lead 新增 port/inbound:ConvertibleLeadCatalogPort(单方法)+
ConvertibleLeadView(随端口同包)+ ConvertibleLeadCatalogPortImpl
(逻辑自 LeadServiceImpl 原样迁入,票 12 口径不变)
- 删 ILeadService.listConvertibleLeads + LeadServiceImpl 实现 +
domain/dto/ConvertibleLeadView + LeadConvertibleQueryTest
(宽服务接口不再挂为外域服务的方法,商机侧不再 import ILeadService)
- 商机侧 4 处改注入端口:CreateServiceImpl / IOpportunityCreateService /
CreateController / 测试;占用过滤(查 opportunity.source_lead_id)留商机侧
- 验证:crm-lead 119 + crm-opportunity 165 全绿
2 weeks ago
luoweijian
4b1ec8c9b3
docs(opportunity): ADR-0030 商机建档深模块 + CONTEXT.md 术语同步(Candidate #1 收官)
- ADR-0030:OpportunityIntake 收敛两条建档入口的决策记录
(spec 内部契约 / 事务落 open / 异常不跨 seam / IntakeSource 承载差异)
含转商机路径漏填 oppSource 的 BUG 修正记录
- CONTEXT.md 新增术语「商机建档」(OpportunityIntake)「进入方式」(IntakeSource),
首段补深模块指引
2 weeks ago
luoweijian
13ebebd23f
refactor(opportunity): 直接新建 service 改为 OpportunityIntake 薄 adapter(Candidate #1 步4)
- CreateOpportunityRequest -> OpportunityIntakeSpec 翻译(source=DIRECT,
oppSource 用户所选,ownerDeptId=null 走默认模板兜底,与收敛前一致)
- 保留入口特有校验:oppSource=线索转入时 sourceLeadId 必填(常量取自 IntakeSource)
- 保留 listConvertibleLeads(属 Candidate #2 范围,维持原状)
- OpportunityIntakeException -> BusinessErrorException seam 翻译
- 移除建档五步机制与自带 @Transactional(收敛于 OpportunityIntakeImpl)
- 测试瘦身为翻译层断言:删 leadTaken/directCreate_ok/appliesStageOplogTeam
机制用例,新增 spec 全字段映射 + 异常翻译用例
2 weeks ago
luoweijian
29db6a8ce4
refactor(opportunity): 转商机 port 改为 OpportunityIntake 薄 adapter(Candidate #1 步3)
- CreateOpportunityCmd -> OpportunityIntakeSpec 翻译(source=LEAD_CONVERT,
oppSource 恒 opp_source_01,修正原实现漏填 opp_source 的缺陷)
- OpportunityIntakeException -> OpportunityCreationException seam 翻译
- 建档五步机制与唯一性防护移除(收敛于 OpportunityIntakeImpl)
- adapter 不再自带 @Transactional(crm-lead 外层事务 + open REQUIRED)
- 测试瘦身为翻译层断言,机制断言由 OpportunityIntakeImplTest 覆盖
2 weeks ago
luoweijian
fd5e9f0ccf
commit
2 weeks ago
luoweijian
58a5a211b4
docs(opportunity): 票11/12 标 resolved + 回写 map(PRD 后端收官,仅剩前端+A4)
- 票12 底稿补后端落地清单(架构甲)+ 前误判纠正说明,标 resolved
- 票11 后端全链路已通(ConvertOpportunityParam→Cmd→port 消费),标 resolved
- map 前沿小结记录纠偏 + PRD 后端收官结论:16 票后端全落,
整体上线仅差前端下拉交互 + A4 客户数据源(均在本仓库外)
2 weeks ago
luoweijian
70e2e35f68
feat(opportunity): 票12 商机侧直接新建入口(A3-1-1-2-1)后端补齐
前误判纠正:此前 map 将票12标已落,实为仅验了转商机 port 路径;
本轮补齐商机侧独立新建入口后端(此前一行未写):
- crm-lead: ILeadService.listConvertibleLeads(ownerUserId) 返 status IN(3,4)
候选线索轻量视图 ConvertibleLeadView(准入规则留线索域,架构甲)
- crm-opportunity: CreateOpportunityRequest + IOpportunityCreateService + Impl
+ OpportunityCreateController(POST /api/opportunity, GET /convertible-leads)
- oppSource=opp_source_01(线索转入) → sourceLeadId 必填校验
- source_lead_id 唯一性预检 + DB uk 并发防线(转译业务异常)
- 建商机核心(主表+阶段落位+初始日志+团队成员)两条入口对称,
日志描述「直接创建商机」/opSource=USER 区别于转商机
- 候选下拉商机侧补「未被占用」过滤(剔除已在 opp 表占用的 lead)
crm-lead 119 + crm-opportunity 161 全绿,无 BOM。
前端【关联线索/客户】下拉交互 + A4 客户数据源仍在本仓库外。
2 weeks ago
luoweijian
39ccc37519
docs(opportunity): 票16 已落 resolved 回写 map(票02簇D 5步齐全)
2 weeks ago
luoweijian
218b68af28
feat(opportunity): 票16 转商机同步事务补齐(阶段落位+初始日志+团队成员)
票02簇D同步事务5步补齐剩余3步(均与主表同事务):
- 阶段落位:按负责人部门解析发布中模板版本,current_stage_id=首节点,
锁 stage_template_id/version;resolveBindingVersion 返 null 时三字段留空
(容忍空/走法A,票15默认模板兜底使其常态不触发)
- 初始操作日志:ROW_ADD/ROW_CHANGE/SYSTEM「由线索转入创建」
- 团队成员:领取人=商机负责人 project_role_01/READ_WRITE
扩 OpportunityCreationPortImplTest 3 用例(命中/容忍空/日志/团队)。
crm-opportunity 156 全绿。
2 weeks ago
luoweijian
458ee623c2
docs(dict): 票09 两级树实现落地收尾, 标 done + map.md 行业口径落地
- 票 09 Status resolved→done, 追加 5 步实现落地记录 + item 168→220 演进 + 种子对 builtin 权威语义注记
- map.md: 行业口径从挂起/立票→已落地(全系统通用两级树, 商机存一级/客户到二级), 字典清单 22 组 item 220, 回显改查 industry 分组
2 weeks ago
luoweijian
49cbab687c
docs(opportunity): 拆票15/16 并回写 map(票15 已落 resolved)
票15 全局默认阶段模板兜底 seed 已实现落地;票16 转商机同步事务补齐
(阶段落位+初始日志+团队成员)blocked by 15 现已解除,待开工。
2 weeks ago
luoweijian
319539282b
feat(opportunity): 票09 步5 行业回显改查 industry 分组一级 code (Q7)
- fillDictNames industry_code 分组(从不存在) → industry 两级树分组; 商机存/查一级 code
- 测试 mock industry_code/it → industry/gov(政府机关), 断言回显政府机关
- crm-dict/lead/opportunity 全回归绿 (dict 51 / lead 116 / opportunity 152)
2 weeks ago
luoweijian
8ddc54143c
feat(rule): 票15 全局默认阶段模板兜底 seed(StageTemplateInitializer)
植入一条全公司通用发布中默认阶段模板作转商机阶段落位兜底:
客户圈定→关系摸排→资料采集→方案卡→已转项目(引用 opp_stage 字典 01-05),
末节点已转项目固定(is_fixed=1,票06契约)。对称方案卡 SchemeFieldDefInitializer
兜底范式,幂等按 code 判存(含已停用不复活)。零 A4/零字典改动。crm-rule 131 全绿。
2 weeks ago
luoweijian
68b62e6e33
feat(dict): 票09 步4 industry 重种两级树 60 项 + 种子对内置项权威(剪除旧8)
- ItemSeed 加 parentCode (兼容旧6参构造); upsertItem 按 parentCode 同组解析 parentId (一级先入库故可查到)
- run 增 pruneStaleBuiltinItems: 种子对 builtin 项权威, 不在种子的旧内置项连 ref_count 一并剪除; 用户项(builtin=false)绝不触碰 (US-41)
- industry 8旧扁平项(manufacturing/it/...) → 全系统通用两级树 9一级+51二级 (产品 20260825 全树)
- 测试: 首装/幂等 168→220, 用户跳过 130→182; 加 industry 树结构断言(9一级/51二级); removedFromSeed 语义翻转为剪除 + 新增用户项不剪除测试; 51 全绿
2 weeks ago
luoweijian
08d95df19a
feat(dict): 票09 步3 DictQueryService 加 listTree/listChildren 树形读
- listTree(groupCode): 复用扁平启用列表内存组两级树, 一级为根带 children(仅启用子项), 不新建缓存key (Q4)
- listChildren(groupCode, parentCode): 取一级项直接启用子项, 父不存在返空
- DictItemDTO 加 children (仅 listTree 填充); getItem/listEnabledItems 扁平接口不变, 现存消费方零改动
- 测试助手 newChildItem; 新增2测试 listTree_twoLevel/listChildren_byParentCode; 50 全绿 (+2)
2 weeks ago
luoweijian
94effd1ce5
feat(dict): 票09 步2 字典项两级树父子校验+删除拦截+子项随父停用
- saveItem 父项校验 (Q2): parentId 非空须同组+父为一级(parentId=null)+禁自引用, 父不存在63012/跨组或超两级63001
- doDeleteItem 拦截 (Q3-b): 删一级项若有存活子项则拒 (对齐删分组需组内无项)
- enrich effectiveSelectable 回溯父状态 (Q3-a): 二级项父停用则不可选, 批量取父状态无N+1
- 新增3测试: 父子校验/删除拦截/子随父停用; 48 全绿 (+3)
2 weeks ago
luoweijian
d0856e18a0
feat(dict): 票09 步1 DictItem 加 parent_id 两级树字段
- DictItem + DictItemDTO 加 parentId (nullable, 顶层=null, 二级指向同组一级)
- H2 测试 schema dict_item 加 parent_id 列
- grill 拍板结论写入票 Answer 并 resolved (Q1两级封顶/Q2父子约束/Q3停用连带+删除拦截/Q4 getItem不变+listTree/Q5无存量直接覆盖/Q6客户到二级商机到一级/Q7商机存一级)
- 45 全绿 (纯加字段, 无行为变更)
2 weeks ago
luoweijian
610081c4e2
docs(map): 省市地区 TODO 划掉,实为已修的契约丢字段 bug
2 weeks ago
luoweijian
e4e4cc2347
fix(opportunity): 转商机契约补省市两级地区,修丢字段脏数据
根因:转商机命令 CreateOpportunityCmd 只带单个 regionCode,而源头线索与
目的地商机主表都存 provinceCode+cityCode 两级(均 not null)。命令丢了一
级信息,商机侧被迫两列同填一个 code → 省份列存市/区 code,列表区划回显错。
这是命令契约丢信息,非缺拆分算法(两级值源头本就都有)。
修(补契约字段,非拆分):
- CreateOpportunityCmd:regionCode → provinceCode + cityCode
- ConvertOpportunityParam:同拆两字段(转商机弹窗地区选择器本就省市两级)
- LeadServiceImpl:必填校验拆两字段 + 组装 cmd 透传 param 的省/市
- OpportunityCreationPortImpl:分别 set 两列,删同填占位与「省市拆分待专票」TODO
- 单测:断言省/市两级分别落库(110000/110100);既有 LeadServiceImplTest 同步拆
mvn -pl crm-opportunity -am test 152 全绿 + crm-lead 116 全绿。
2 weeks ago
luoweijian
33efce85f9
docs(dict): 立票 09 字典项两级树形能力 (DictItem 加 parent_id)
- 行业改全系统通用两级树 (产品 20260825), 商机选一级, 需扩 crm-dict 模型
- 票列 7 个待 grill 不变式: 层级上限/父子约束/停用删除级联/树形查询API/存量安全/客户侧选几级/商机落库形态
- 附产品给定行业全树 (9 一级 + 全二级) 待拍板后种
- opportunity map.md 同步: industry 挂起改为已立票
2 weeks ago
luoweijian
042401c57b
feat(opportunity): 票11/12/13 线索转商机新建端口实现 + ADR-0029 技术债
实现 crm-lead 的 outbound port OpportunityCreationPort(此前定义未实现,
根因是 crm-opportunity 未依赖 crm-lead):
- OpportunityCreationPortImpl(同库同事务,ADR-0020):
· 票12 source_lead_id 唯一性预检(应用层友好报错 + DB uk 并发最终防线,
DuplicateKeyException 转译为 OpportunityCreationException)
· 票11 建商机主表:初始推进中(2) + 落归属/来源快照 + claimTime
· 票13 customerId 非空 → 建 is_primary_intended=1 主要意向客户子表 +
刷主表冗余 primary_customer_id/name(走法甲:customerId 可空则跳过,
不倒退现有自由文本转商机)
- 5 单测:唯一性命中/带客户建子表刷冗余/无客户跳过/初始态快照/并发uk转译
- crm-opportunity/pom.xml 依赖 crm-lead
- ADR-0029 记技术债:下游反向依赖上游,埋循环依赖雷(crm-lead 将来读商机即死循环),
当前同库单体阶段可接受,触发条件出现时改抽共享 port 契约模块并 supersede
省市 TODO:cmd 单 regionCode → 主表 province/city 两列 not null,暂同填占位,
待省市拆分专票。mvn -pl crm-opportunity -am test 152 全绿。
2 weeks ago
luoweijian
cd7dadec3a
feat(dict): 种 attachment_type 商机资料类型 (产品录入 20260825)
- attachment_type 5 项: 现场资料/涉及清单图纸/客户需求资料/招投标相关资料/其他 (票09 附件分类)
- 分组 21→22, item 163→168; 种子测试断言同步, 全绿
行业树形仍挂起: 路② (DictItem 加 parent_id 建两级树) = crm-dict 基础模型扩展, 待立 spec 票 + grill 拍板不变式后单独 implement
2 weeks ago
luoweijian
0e4449d75b
feat(lead): 票11 转商机契约加 customerId(可空占位,待A4收紧必填)
票11 步骤1-2 契约变更(走法甲:customerId 暂可空,不倒退现有自由文本转商机):
- CreateOpportunityCmd 新增 customerId(Long,暂可空);intendedCustomer 降为
客户名快照,与 customerId 并存(引用+快照,同票13走法)
- ConvertOpportunityParam 新增 customerId(前端下拉选客户得到;A4 下拉未就绪
前前端传 null)
- LeadServiceImpl 组装 cmd 时透传 param.getCustomerId()
A4 客户下拉就绪后把 customerId 收紧为必填(终态契约,一处校验)。
mvn -pl crm-lead -am test 116 全绿。
2 weeks ago
luoweijian
3e99a07a0e
docs: 追踪「自定义检索推广到其他菜单」,不建空 ticket
产品诉求「每个菜单都应支持自定义检索」——平台能力已就绪(user_saved_view
+ SavedViewService + /api/preference/view 按 scope 分组,crm-preference 不
校验字段),无需新建模块或空 ticket,只记追踪:
- crm-preference/CONTEXT.md 自定义视图段补「责任边界」:crm-preference 只
存/取 filter_json,翻译成查询归业务方(字段池/操作符语义在业务方,商机侧
例=OpportunitySavedViewFilter);新菜单接入=复用契约+自备翻译器,本模块不改
- map.md Not yet specified 加追踪条目:新菜单接入三步手册 + 建带验收 ticket
的时机(第二个真实菜单要上时) + 不提前抽共享翻译器缝(rule of three,
现仅商机1个样本)
2 weeks ago
luoweijian
1e453a1b92
docs(map): 票14 spin-out 措辞纠偏 + 排序标已实现
- spin-out 去掉误导性 AND/OR:本期只 1 组条件、组内纯 AND,需求无 OR;
真正 spin-out = 多组条件(demo「+添加更多条件」后续迭代)+ 高级公式
- sortField 排序从 spin-out 移出,标 ✅ 已实现(底稿定义2漏项已补)
2 weeks ago
luoweijian
911511d8f5
feat(opportunity): 票14 自定义视图排序接线(补底稿定义2漏项)
底稿 issues/14 定义2 把「排序字段+方向」列为自定义视图组成部分,实体/DTO
已存 sortField/sortDirection,但上一版查询未接排序(列表恒按 createTime)。补齐:
- OpportunitySavedViewFilter.orderByClause(field,direction):字段走同一字段池
白名单→主表列名,方向只认 asc/desc(大小写无关,其余/空→DESC);字段不在池/空→null
- ViewQueryImpl.applySavedView 返回排序片段,pageOpportunities 有则
wrapper.last(ORDER BY ...) 替代默认 createTime 倒序,无则回落默认;
RECENT 路径为时间序不接排序(时间序优先)
- 移除不再直接引用的 SavedView import
- 补 3 排序单测(asc/desc默认/未知字段回落)
mvn -pl crm-opportunity -am test 147 全绿。
2 weeks ago
luoweijian
8c44433ce4
docs(opportunity): 字典清单更新 14 组已种, 仅剩 attachment_type 缺值 + 行业挂起
2 weeks ago