14 KiB
财务后台定位与主导航减法
Goal
将 hyb-oa 的正式定位从“通用内部 OA”收敛为本公司 5–10 人使用的财务与低频台账后台:范围上只保留 OA 真正应主办的财务、台账和治理能力,采用力度上只要求团队在这些核心流程中真实使用,不与企业微信争夺请假、考勤和日常协作。随后利用现有运行时 feature flag,一次性、可逆地关闭公告、普通待办和周报;项目是否一并关闭,必须先通过本地跨域回归。
Background
08-11-internal-oa-usage-census-and-simplification的生产只读普查覆盖 20 个模块:聚合 70 行(其中系统配置 26),13 个模块零行,近 90 天只有 13 条真人归属/创建记录证据;唯一可证明的业务链是“报销 → 审批 → 付款/AP”。- 请假、考勤等日常员工流程按既有事实源由企业微信主办。零 OA 使用不代表这些业务没有发生,而是操作端在别处。
- 用户已正式选择“范围收缩 + 核心流程采用”的组合定位,不再沿用 A/B 二选一:
- OA 主办并推动真实使用:报销、票据/OCR、审批、付款批次、AP、必要财务交接。
- OA 保留冻结:合同、采购、资产等低频高失败成本台账,以及认证、权限、审计、备份恢复、离职撤权等治理底线。
- 企业微信主办:通讯录、请假、考勤及适合在企微完成的员工日常协作。
- 超出当前范围、仅列退役审查候选:绩效、薪资、ERP/集成、预算、Cutover 等;本任务不删除它们。
- 旧 R63–R66 产品排期中的通知中心、入职向导等扩建方向已被用户判定失效;不得再把它当后续产品主线。
Confirmed Technical Facts
server/src/services/workspaceSettings.js:79-82将周报、待办、公告、项目分别绑定到weekly_report_v1、todo_board_v1、announcements_v1、project_domain_v1;getSystemNavigation在 flag 非 effective 时过滤导航项(:310-357)。- 2026-08-11 生产快照中四个模块均为 0 行、近 90 天真人活动 0,且导航均为
main、effective flag 均为 on;执行前仍须现场复核,不能用该快照替代现场状态。 POST /api/system/feature-flags/batch使用单个数据库事务、逐项expectedVersion乐观锁、逐项FEATURE_FLAG_UPDATED审计;任一目标缺失或版本冲突会整批回滚(server/src/routes/featureFlags.js:586-665)。force_off不只是隐藏导航,还会使对应后端能力返回关闭状态:公告/api/announcements,周报/api/weekly-reports,普通待办/api/todos,项目主域/api/projects;Portal 和全局搜索会停止聚合相应内容。项目 flag 关闭后,报销、合同和采购页面中的“项目选项”查询也会不可用,但project_linking_v1不在目标清单,合同台账 API 本身不得被关闭。- 合同、采购、资产当前没有统一 feature flag 可单独变为“二级入口”;现有导航模型只有
main/admin/backupsection 和扁平 item,不具备业务二级分组。本轮不新增导航层级。
Scope
- 固化“财务与低频台账后台 + 核心流程真实采用”的正式产品定位,并纠正会继续驱动失效 R63–R66 扩建计划的当前前向口径。
- 在零产品代码、零部署前提下,先完成本地事实源与治理规则收敛。
- 在另获生产写入批准后,通过既有 batch feature flag 能力一次性关闭公告、普通待办和周报;
project_domain_v1只有本地证明报销详情项目关联不降级时才能加入同一批次。 - 合同、采购、资产二级入口及所有模块退役只登记延后条件,不实施、不创建子 task。
Requirements
R1. 固化正式产品定位
- 更新
docs/产品口径.md和.trellis/spec/hyb-oa/project-governance.md,用“财务与低频台账后台 + 核心流程真实采用”替换尚未决的 A/B 门。 - 明确 OA 主办、企微主办、低频保留和退役审查候选四个边界;强推报销走 OA 是管理动作,不实现强制提醒、渠道封堵、引导页或新通知功能。
- 只纠正仍会驱动未来工作的 R63–R66 前向引用;历史归档证据不批量改写。
R2. 定位阶段保持零产品代码;恢复后允许最小 QA harness 修复
- 定位固化、项目准入和首次生产尝试阶段不修改
client/src、server/src、scripts/、migration、依赖、构建或部署配置,也不新增 task-scoped 可执行脚本。 - 首次生产尝试安全恢复后,用户明确批准在再次申请生产前先修复本地观察机制并补五个失败分支。该局部例外只允许新增/修改
scripts/qa的纯状态机与对应本地单元测试;仍不得改产品运行代码、API、schema、依赖或部署配置。 - 允许修改当前 task、既有业务事实源、治理 spec,以及确有误导性的当前任务前向说明。
- 不构建、不部署、不改变 build SHA。生产只使用已部署的功能管理页面和既有 batch API。
R3. 三个固定 flag 与一个条件 flag 的精确原子关闭
- 固定目标是
announcements_v1、todo_board_v1、weekly_report_v1,目标集合至少且恰好包含这三项;不得包含project_linking_v1或任何其他 flag。 project_domain_v1是唯一条件目标。实施前必须在本地关闭它,分别验证未关联项目和已关联项目的报销详情:页面无可见查询错误,未关联控件具有明确且不误导的状态,已关联单据仍显示原项目名称/编号和关联事实。任一项不满足即从生产 target 剔除,项目入口本轮继续保留。- 本地准入结论已将目标固定为三项;生产变更方式固定为一次 batch mutation,将这三项
overrideMode设为force_off;保留各自既有rolloutType和departmentIds,填写统一、可审计的定位说明。 - 执行前读取现场 version、override、rollout、effective 状态和三个目标模块当前计数;任一目标不唯一、版本变化、已有真人/业务数据、影响范围超出本合同或生产身份不清楚即停止。
- 生产登录会产生认证 session/audit;除这类认证状态、三条 feature flag 更新及三条对应审计外,不允许业务写入、workspace PATCH、数据清理或其他配置变更。
R4. 分段批准与不确定性处理
- 当前批准只允许创建 task 和规划,不允许
task.py start、事实源改写或生产操作。 - 用户批准本规划并
task.py start后,只先实施本地文档/spec 收敛与只读门禁;本地准入完成后确定的生产 batch(现已固定为三个 flag)仍需再次明确批准。 - 生产批准合同最多包含一次前向 batch;只有批准文本明确包含预定义回滚分支时,才允许在 POST 检查失败时执行最多一次回滚 batch。
- 若请求通道中断、响应缺失或 JSON 不可解析,进入
APPLY_UNCERTAIN:只允许重新 GET flag、导航和审计定性,禁止盲目重试。 - 本地观察器计数与 batch 响应或现场状态矛盾同样属于
APPLY_UNCERTAIN。未通过只读 GET 三项目标的 version/override/effective 并以审计交叉定性前,不得重试、回滚或执行任何补偿写入;回滚预授权不改变该顺序。
R5. 写后验证与保留域保护
- 最终 target 均须满足
overrideMode=force_off、effectiveEnabled=false、effectiveReason=flag_force_off、version 相对 PRE 恰好+1,且新增审计条数恰好等于 target 数、每项各一条。 - 管理员导航必须不再出现
announcements、todos、weeklyReports;只有project_domain_v1通过本地门禁并进入生产 target 时才要求projects消失。对应直达只读入口应得到明确的 disabled/409,而不是登录失效或 5xx。 - Portal、报销、合同、采购、资产的既有只读入口必须仍可加载,不得出现被动业务 mutation。若
project_domain_v1入选,生产 POST 继续复核本地已证明的项目关联显示合同;“空下拉或隐藏错误”不算通过。 project_linking_v1、合同/采购/资产数据、回滚窗口和其他 feature flag 的 snapshot 必须保持不变。
R6. 阶段二明确延后
- 合同、采购、资产继续保留现有一级入口和最小能力,本轮不实现“二级入口”。
- 导航层级、分组或二级入口只有在核心财务流程出现更多真人用户、一级导航确有可观察摩擦时,才允许另建产品 task。
- 绩效、薪资、ERP/集成、预算、Cutover 本轮只标记退役审查候选,不关闭 flag、不删入口、不删代码、schema 或历史数据。
Acceptance Criteria
- AC1:产品口径和治理 spec 统一写明“财务与低频台账后台 + 核心流程真实采用”,不再保留 A/B 未决状态或 R63–R66 扩建主线。
- AC2:git diff 证明产品运行代码、migration、依赖和部署配置零改动;首次恢复后的唯一代码例外是
scripts/qa状态机及其 focused 单元测试,无构建、部署或 build SHA 变化。 - AC3:本地关闭
project_domain_v1后,分别验证未关联和已关联项目的报销详情;只有控件状态明确、已关联项目名称/编号仍正确且无可见错误才允许生产 target=4,否则固定 target=3。 - AC4:生产 PRE 现场确认三个最终目标模块仍为零数据/零真人活动,三项 flag 目标恰好、effective on、版本已冻结,且完整记录原始 snapshot 与影响范围。
- AC5:仅在生产写入另获批准后,通过既有页面/API 严格执行一次最终 target batch
force_off;无单项 PUT、无 workspace PATCH、无其他 flag 或业务数据写入。 - AC6:POST 证明最终 target 均 effective off、version 各
+1、审计增量等于 target 数;对应导航消失,直达得到可解释的 disabled 结果。 - AC7:Portal、报销、合同、采购、资产只读入口仍可加载;若项目 flag 入选,已关联项目显示仍正确;
project_linking_v1与其他 flag 不变,非认证业务 mutation 为 0。 - AC8:阶段二和退役动作均未实施;合同、采购、资产继续保持可用,二级入口只作为事件触发的后续候选。
- AC9:task validate、Trellis governance、process contract、docs registry、敏感扫描和
git diff --check通过;生产证据不含账号、Secret、token 或原始业务 payload。
Out of Scope
- 新功能、UI/导航层级代码、组件改造、路由删除、schema/data migration、模块物理退役。
- 用技术手段“强制”员工报销、禁用微信沟通、增加提醒/推送或制造生产业务记录。
- 关闭合同、采购、资产、付款、AP、票据、认证、权限、审计、备份恢复能力。
- 部署、公网候选发布、企业微信写入、真实付款或任何非本合同生产写入。
Test Plan
- 静态核对三个最终目标 flag、已排除的项目 flag、batch transaction、后端影响范围和保留域依赖。
- 本地文档阶段运行 task validate、governance、process contract、docs registry、敏感扫描和
git diff --check;用git diff --name-only断言零产品运行代码。恢复后的 QA harness 阶段另跑 Node 语法与五分支 focused test,并继续断言client/src、server/src、schema、依赖和部署配置零 diff。 - 本地先建立含项目关联和不含项目关联的报销样本,在
project_domain_v1=force_off下用真实浏览器验证控件与显示;不以组件单测或“页面未崩”代替。 - 生产批准后:身份与运行 SHA 只读 PRE → 现场最终 target 模块计数和 flag snapshot → 管理员登录 → 一次 batch → 只读 flag/audit/navigation/direct-route/保留域 POST。
- 任一生产状态不确定进入
APPLY_UNCERTAIN;先只读定性,不连续提交。
Approval State
用户已于 2026-08-11 完成只读复核并批准 task.py start,同时要求先本地验证 project_domain_v1 对报销项目关联的影响。该批准允许本地定位固化和合成数据验证,不包含生产 feature flag 写入。
Local Admission Result
2026-08-11 本地真实浏览器 on/off/restore 验证已完成:project_domain_v1=force_off 时,未关联报销的项目控件仍启用但没有关闭说明;已关联报销的事实卡保留项目信息,项目控件却丢失当前选项并回落到“不关联项目”。因此 AC3 的条件未满足,生产 target 已固定为三个:announcements_v1、todo_board_v1、weekly_report_v1。项目 flag 继续保持现状,不允许在本轮生产 batch 中出现。
Retry Admission After Restored Attempt
2026-08-12 获批的一次前向 batch 已成功落地,但本地页面观察器漏掉 APIRequestContext 写入并误触发预授权恢复;生产最终安全回到 force_on@49。下一次生产前向写入不是本次批准的延续:必须以现场 version 重新锁定、先在本地覆盖“写入成功但页面观察为 0”及全部不确定分支,并另获明确批准。本任务不得以修正文档为由自动再次写生产。
Lifecycle Closeout
本 task 于 2026-08-13 按用户决定停止继续生产尝试并归档。正式产品定位、项目 flag 排除、本地不确定性状态机、两轮生产事实和安全终态均已完成记录;三项导航保持关闭这一原目标没有达成,AC5–AC7 保持未勾选。两轮前向 batch 都成功,随后分别因观察器和 POST witness 的假失败恢复,生产终态为三项 force_on@51、业务 mutation=0、回滚窗口 OPEN/0。
停止原因是成本收益不再成立,而不是产品无法关闭:当前仅有极低真人使用,三个多余入口没有可观察摩擦;继续建设验证装置的成本已经超过导航减法的即时价值。导航减法只在“多名真人持续使用且出现明确导航摩擦”时重新评估,并须创建或更新当时的 Trellis task,不沿用本 task 的版本锁或生产批准。当前下一步是管理动作——下一轮真实报销要求走 OA,用真人摩擦决定后续工程工作;在此之前不创建猜测性产品任务。