unis_manager/.workbuddy/memory/2026-09-13.md

7.9 KiB
Raw Permalink Blame History

2026-09-13 周期错位修复

问题

系统里「2026年8月第4周」混进了「9月第1周」的内容(两块录到同一周期)。

根因

原始 Excel《周工作情况总结》最后一次导入时,表尾只有一个「8月第4周」标签,其内容里连着贴了两段。 scripts/import_excel.py 按 (项目, 子任务, 周期) 去重,同周期内重复出现就 append 到同一条记录 (见 import_excel.py:170-197),于是两周内容被揉在一起。Excel 文件后来(2026-09-13 16:08)被拆成了 「8月第4周」(行838-862) 和「9月第1周」(行863-890) 两个块。

修复

脚本 scripts/fix_period_split.py(--dry-run 预演,默认执行,自动备份 data/board.db) 按 Excel 现状把数据库对齐:

  • 2026年8月第4周 → 只留 8月第4周内容(9 常规 + 1 定制)
  • 2026年9月第1周 ← 从 8月第4周拆出的 9月第1周内容(10 常规 + 1 定制「金昌视综平台定制开发」)
  • 2026年9月第2周 ← 原误放在 9月第1周 的数据(用户手工录入的 NEX 云桌面 2 条)
  • 顺带重算受影响项目的进度/状态、受影响定制项目的入库时间

全量核查结论(内容级比对 Excel vs DB)

  • 无跨周污染残留(8月第4周/9月第1周 那个是唯一一起,已修)
  • 另有 7 条「DB 内容比 Excel 多」:
    • 2025年3月第1周 3 条(云桌面产品培训/公司内IT平台规划/云屏V1.2版)
    • 2026年5月第3周 2 条、5月第4周 1 条、6月第1周 1 条 → 同一周内同一子项在源表里占多行,导入时合并成一条;非跨周问题
  • Excel 里存在同标签重复块:2024年9月第二周(行143/160)、2025年5月第3周(行503/528), 导入必然合并,属源表歧义,未擅自拆分
  • 「智听云」→ 改名「iMeeting 语音智能体」、「智空无人机平台」→ 合并进「智飞无人机平台」, 在全量比对中表现为 Excel/DB 互不匹配,属正常

教训

导入脚本对「同周期同子项重复出现」采用 append 合并,源表一旦把两周内容贴在同一标签下就会静默串周。 后续若发现某周期记录数明显偏多,优先怀疑源表标签缺失。


重点项目 / 定制项目:多负责人 + 团队成员

需求

重点项目和定制项目都可以指定多个负责人,并新增「团队成员」。

兼容策略(关键决定)

  • owner 列语义不变 = 主负责人 = owners[0]。列表、看板、导出、人力负载、KPI 全部照旧读 owner,一行未改。
  • 不建关联表:两张项目表各加 other_owners(其他负责人,不含主)与 members(团队成员)两个 String(512) 列, 存首尾带逗号的 CSV:,张三,李四, 或 NULL。于是 LIKE '%,张三,%' 是精确整名匹配, 「张三」不会命中「张三丰」(已测)。
  • 新列靠 app/schema_patch.py: ensure_columns 启动时自动 ALTER TABLE,无需迁移脚本;真实库 data/board.db 本次未被写入。
  • API 字段:owners(= 主 + 其他,主在首位)、members。PATCH 整体替换:不传=不改,传 []=清空。 老调用方只传 owner 时 other_owners 保留 → owners 自动变成 [新主, ...其他],不会写出脏数据。
  • 工具函数集中在 app/models.py:split_people / dedupe_people / join_people / people_like / all_owners / set_people; set_people 同时负责「owners[0] 回写 owner」。

口径(容易误解,已和用户对齐的说法)

  • 「负责人」筛选(项目列表 / 定制列表 / 周看板)主负责人和其他负责人都算命中;团队成员不参与该筛选(有意)。
  • 列表、导出、人力负载、KPI 只按主负责人统计;列表负责人列只显示主负责人。
  • 人员改名(routers/staff.py)会同步改写 other_owners / members 里的名字。

入口

只在详情抽屉的「修改」档(peopleEditorHtml / peopleValues / bindDrawerPeople,增删按钮一次性委托在 #drawerBody)。 第 0 行:负责人档标「主」不给删;成员档空占位行不给删,有值就能删。列表行仍然只有 详情/修改/归档。 新建弹窗(npOwner/ncOwner)保持单个负责人——假设:建好后进详情面板补名单。

并发提醒

web/app.js 同期被另一个任务改(人力资源表的星标计数),期间出现过一次模板串语法错误导致整站 JS 不解析(对方已自行修复)。 改这个文件前先 node --check web/app.js + shasum。


周工作 Focus:只显示当周 + 上周延期结转;录入期数 ≠ 预计完成时间

需求

周工作Focus的只显示当周和上周延期过来的。录入的时候也要注意这点,选择的结束时间并不是作为录入的期数。

老逻辑把 due_date 反查成 periods 里的一周存进 period_id,于是本周录一条「两周后交付」的活儿直接掉进「未来」堆,本周看不见。

语义变更(核心)

  • WeeklyFocus.period_id 语义由「预计完成时间所属周」改成录入周,和 Update.period_id(反馈所属周)一致。 字段名/to_dict 键名(period_id / period_label / period_full / sort_key)全部保留 → 前端与导出零连锁改动。
  • due_date 退化成纯目标日期:focus.py: _resolve_period() → _entry_period(db, period_id), 不再按日期反查周期;POST 传 period_id=顶栏当前周,没传(脚本/API 直调)按 constants.week_of_date(date.today()) 补; PATCH 只有显式传 period_id 才搬周,改 due_date 不再动归属。
  • 导出列「所属周」→「录入周」(export.py,排序仍按 period.sort_key desc)。

分堆口径(web/app.js: focusBuckets)

  • week = 录入周 == 基准周;overdue = 录入周 < 基准周 且 delayed 且未完成(上周及更早的结转);done 仍是交叉视图。
  • 删掉「未来」堆(chip 从 5 个变 4 个:本周/延期/已完成/全部);restoreUI 里把存量的 focusFilter==="later" 复位成 week,否则老会话进来会看到空表。
  • 取舍(已明确告知用户):更早周次录入、没标延期又没完成的条目不进当周视图,只能在「全部」里查 → 每周收尾要手动勾「延期」才会结转。
  • 抽屉:录入周只读一行(新增取顶栏周,编辑显示原周);预计完成时间与录入周在详情里拆成两行;#fdSave 只在 mode==="create" 时带 period_id。
  • 列表「预计完成时间」下的小字改为「录入 X月第N周」;看板左栏结转条目多挂一个「录入 …」标签。

顺带修的默认值问题(会导致本周看起来是空的)

/api/periods 里已预建了未来的周(库里已有 9月第3周),而 loadPeriods 的默认周取「列表最后一期」→ 顶栏会落在下周, 新的录入周口径下当周直接空掉。改为 /periods 多返回 today_id(constants.week_of_date(date.today()) 命中的周), 默认周取 today_id || 最后一期。仅在「存的 weekId 不在列表里」时生效,不覆盖用户手选的周。

数据

库里 3 条 focus(全是 2026-09-13 建的)period_id 本来就是 9月第2周 = 今天所在周 → 无需回填,语义切换后归属不变(已断言)。

验证

/tmp/umtest/t_focus.py(TestClient + data/board.db 副本):due=两周后仍归本周 / 不传 period_id 归今天所在周 / 改 due 不搬周 / 显式 period_id 才搬周 / 旧数据不漂移 / 导出 200。 UI(8791 + 副本库,插 5 条造结转场景):本周 3(含 due 9-20 那条)· 延期 3(9月第1周×2 + 8月第4周×1,未标延期与已完成的都不进来)· 已完成 2 · 全部 8;新增 due=09-27 立即进本周;改成 12-31 仍在本周;切到 9月第3周本周空态文案正确;dev.logs() 为空。

待办(历史遗留,未动)

scripts/import_excel.py 里旧台账 LedgerItem 的导入解析是否退役。