Use active work queue for weekly priorities
This commit is contained in:
+11
-2
@@ -193,6 +193,7 @@ def build_report(data_dir, snapshot=False, now=None):
|
|||||||
ledger = read_json(data_dir / 'ledger.json', {'entries': []})
|
ledger = read_json(data_dir / 'ledger.json', {'entries': []})
|
||||||
content = read_json(data_dir / 'content.json', {'items': []})
|
content = read_json(data_dir / 'content.json', {'items': []})
|
||||||
tasks = read_json(data_dir / 'tasks.json', {'items': []})
|
tasks = read_json(data_dir / 'tasks.json', {'items': []})
|
||||||
|
queue = read_json(data_dir / 'workqueue.json', None)
|
||||||
findings = read_json(data_dir / 'findings.json', {})
|
findings = read_json(data_dir / 'findings.json', {})
|
||||||
api = read_json(data_dir / 'deepseek-usage.json', {})
|
api = read_json(data_dir / 'deepseek-usage.json', {})
|
||||||
entries = []
|
entries = []
|
||||||
@@ -230,6 +231,14 @@ def build_report(data_dir, snapshot=False, now=None):
|
|||||||
if not observed_this_period(findings.get('checked_at')):
|
if not observed_this_period(findings.get('checked_at')):
|
||||||
risks.append('基础验收记录未在本周期更新,历史成果未重复计作本周完成。')
|
risks.append('基础验收记录未在本周期更新,历史成果未重复计作本周完成。')
|
||||||
current = next((i for i in tasks.get('items', []) if i.get('status') == 'in_progress'), None)
|
current = next((i for i in tasks.get('items', []) if i.get('status') == 'in_progress'), None)
|
||||||
|
next_actions = [i['title'] for i in tasks.get('items', []) if i.get('status') in ('todo', 'in_progress')][:8]
|
||||||
|
# A task queue is a current snapshot; it does not reconstruct the past reporting period.
|
||||||
|
if isinstance(queue, dict) and queue.get('schema') == 1 and isinstance(queue.get('tasks'), list):
|
||||||
|
safe = [i for i in queue['tasks'] if isinstance(i, dict) and i.get('status') in ('pending', 'running', 'blocked') and isinstance(i.get('title'), str) and isinstance(i.get('id'), str)]
|
||||||
|
safe.sort(key=lambda i: (0 if i['status'] == 'running' else 1 if i['status'] == 'pending' else 2, i.get('updated_at') or ''))
|
||||||
|
next_actions = [('核查新互动' if i['id'].startswith('interaction-') else i['title'][:100]) + ('(已阻塞)' if i['status'] == 'blocked' else '') for i in safe[:8]]
|
||||||
|
current = next(({'title': '核查新互动' if i['id'].startswith('interaction-') else i['title'][:100]} for i in safe if i['status'] == 'running'), None)
|
||||||
|
|
||||||
identifier = end.strftime('%G-W%V') + ('-snapshot-' + now.strftime('%Y%m%dT%H%M%S') if snapshot else '')
|
identifier = end.strftime('%G-W%V') + ('-snapshot-' + now.strftime('%Y%m%dT%H%M%S') if snapshot else '')
|
||||||
report = {
|
report = {
|
||||||
'id': identifier,
|
'id': identifier,
|
||||||
@@ -239,7 +248,7 @@ def build_report(data_dir, snapshot=False, now=None):
|
|||||||
'summary': ('当前推进:' + current['title']) if current else '根据已归档的项目记录汇总;缺失数据保留待核算。',
|
'summary': ('当前推进:' + current['title']) if current else '根据已归档的项目记录汇总;缺失数据保留待核算。',
|
||||||
'highlights': highlights,
|
'highlights': highlights,
|
||||||
'risks': risks,
|
'risks': risks,
|
||||||
'next_actions': [i['title'] for i in tasks.get('items', []) if i.get('status') in ('todo', 'in_progress')][:8],
|
'next_actions': next_actions,
|
||||||
'decisions': findings.get('decisions', []),
|
'decisions': findings.get('decisions', []),
|
||||||
'metrics': {
|
'metrics': {
|
||||||
'published_project_videos': len(published),
|
'published_project_videos': len(published),
|
||||||
@@ -260,7 +269,7 @@ def build_report(data_dir, snapshot=False, now=None):
|
|||||||
},
|
},
|
||||||
'revenue': {'settled_cny': round(sum(e['amount'] for e in incomes), 2) if incomes else None, 'estimated_cny': None,
|
'revenue': {'settled_cny': round(sum(e['amount'] for e in incomes), 2) if incomes else None, 'estimated_cny': None,
|
||||||
'notes': ['播放量不是结算收入,自有产品推广稿件是否纳入激励需单独验证。', '未结算或未归因到PawPlay的收益不算项目收入。']},
|
'notes': ['播放量不是结算收入,自有产品推广稿件是否纳入激励需单独验证。', '未结算或未归因到PawPlay的收益不算项目收入。']},
|
||||||
'sources': {'findings_checked_at': findings.get('checked_at'), 'ledger_entries_in_period': len(entries), 'content_ledger': 'content.json', 'usage_source': '本机会话计数(只保存汇总,不发布对话)'},
|
'sources': {'findings_checked_at': findings.get('checked_at'), 'ledger_entries_in_period': len(entries), 'content_ledger': 'content.json', 'next_actions_source': 'workqueue.json:报告生成时的任务快照' if isinstance(queue, dict) and queue.get('schema') == 1 and isinstance(queue.get('tasks'), list) else 'tasks.json:静态任务清单', 'usage_source': '本机会话计数(只保存汇总,不发布对话)'},
|
||||||
}
|
}
|
||||||
repo = collector.get('repository')
|
repo = collector.get('repository')
|
||||||
if repo:
|
if repo:
|
||||||
|
|||||||
@@ -76,5 +76,17 @@ class AccountingTests(unittest.TestCase):
|
|||||||
self.assertIsNone(value['cash_settlement_usd'])
|
self.assertIsNone(value['cash_settlement_usd'])
|
||||||
|
|
||||||
|
|
||||||
|
def test_report_uses_current_queue_and_redacts_interaction_titles(self):
|
||||||
|
import json
|
||||||
|
with tempfile.TemporaryDirectory() as directory:
|
||||||
|
root = Path(directory)
|
||||||
|
(root / 'tasks.json').write_text(json.dumps({'items':[{'title':'旧计划','status':'todo'}]}))
|
||||||
|
(root / 'workqueue.json').write_text(json.dumps({'schema':1,'tasks':[{'id':'interaction-private','title':'私人消息内容','status':'running'}, {'id':'video','title':'制作挑战视频','status':'pending'}, {'id':'done','title':'已完成','status':'done'}]}))
|
||||||
|
path,_ = report.build_report(root, now=dt.datetime(2026,11,6,20,tzinfo=report.TZ))
|
||||||
|
value=report.read_json(path)
|
||||||
|
self.assertEqual(value['next_actions'],['核查新互动','制作挑战视频'])
|
||||||
|
self.assertNotIn('私人消息内容',json.dumps(value,ensure_ascii=False))
|
||||||
|
self.assertIn('workqueue.json',value['sources']['next_actions_source'])
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user