fix: 对照《财务处Skill002》验收整改并升版 v1.0.2
All checks were successful
技能自动化发布 / release (push) Successful in 9s

- 状态标签:C3 触发且 D 未判 → 待补录,优先级对齐需求 §6.2
- broadcast-monthly 逐项目增量 emit,任务中心可见进行中进度
- progress_reports 回填 project_id;新增 items_json/updated_at;旧库重建式安全迁移(含回归测试)
- 简报:TITLE 转义防注入、章节对齐 §10(独立「暂付款/结题提醒」)、页脚逐字统一
- 金标准测试 +17:±10%/20% 阈值恰界、C2 钳位、N2 反例、C3 逐字段、HTML 转义、async+cron 定位守护、迁移回归
- 文档 v1.1(开发文档 + REQUIREMENTS):ERROR:<CODE> <message>、reports_brief、--all-status、skill-detail 表外挂载、C1 level=warn
- 落盘验收报告 acceptance-reports/20260924-105401-acceptance.md(338 测试全绿)
- 版本 1.0.1 → 1.0.2(constants / SKILL.md / CHANGELOG 三处对齐)
This commit is contained in:
chenfuqiang
2026-09-24 17:19:30 +08:00
parent a91ead3862
commit f90f742c1e
12 changed files with 490 additions and 25 deletions

View File

@@ -37,6 +37,70 @@ class TestDbSmoke(unittest.TestCase):
finally:
conn.close()
def test_init_db_migrates_legacy_progress_reports(self) -> None:
"""v1.0.1 旧库(无 items_json/updated_at)→ init_db 重建迁移且数据不丢。"""
with IsolatedDataRoot():
from db.connection import get_conn, init_db
conn = get_conn()
try:
conn.execute(
"""
CREATE TABLE progress_reports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
batch_no TEXT NOT NULL,
project_id INTEGER,
project_no TEXT,
project_name TEXT,
pi_name TEXT,
as_of TEXT,
spend_rate REAL,
time_progress REAL,
deviation REAL,
status_tag TEXT NOT NULL,
summary TEXT,
suggestions_json TEXT,
report_file TEXT,
created_at INTEGER NOT NULL DEFAULT (unixepoch())
)
"""
)
conn.execute(
"INSERT INTO progress_reports (batch_no, project_no, status_tag) VALUES (?, ?, ?)",
("legacy-batch", "OLD001", "严重滞后"),
)
conn.commit()
finally:
conn.close()
init_db()
conn = get_conn()
try:
cur = conn.cursor()
cur.execute("PRAGMA table_info(progress_reports)")
cols = [str(row[1]) for row in cur.fetchall()]
self.assertIn("items_json", cols)
self.assertIn("updated_at", cols)
row = cur.execute(
"SELECT project_no, status_tag FROM progress_reports WHERE batch_no = ?",
("legacy-batch",),
).fetchone()
self.assertEqual(row, ("OLD001", "严重滞后"))
leftovers = cur.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '_progress%'"
).fetchall()
self.assertEqual(leftovers, [])
triggers = cur.execute(
"SELECT name FROM sqlite_master WHERE type='trigger' AND tbl_name='progress_reports'"
).fetchall()
self.assertTrue(any("set_updated_at" in str(t[0]) for t in triggers))
finally:
conn.close()
if __name__ == "__main__":
unittest.main()