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

107 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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` 的导入解析是否退役。