关键改动: - 支持需求覆盖和调研方向开始工作记录 - 日报按计划记录开始时间和进度下次开始时间计算证据 - 更新版本编辑校验、项目展示和 workflow 说明 Co-Authored-By: Codex GPT-5 <codex@openai.com>
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
export type WorkActivitySourceType = 'version_plan' | 'dev_task' | 'test_case' | 'bug' | 'manual';
|
|
|
|
export type WorkActivityCategory = 'delivery' | 'progress' | 'creation' | 'risk' | 'note';
|
|
|
|
export type WorkActivityAction =
|
|
| 'version_plan_created'
|
|
| 'version_plan_started'
|
|
| 'version_plan_completed'
|
|
| 'version_plan_requirement_progress'
|
|
| 'version_plan_research_direction_progress'
|
|
| 'dev_task_created'
|
|
| 'dev_task_started'
|
|
| 'dev_task_self_testing'
|
|
| 'dev_task_submitted'
|
|
| 'dev_task_blocked'
|
|
| 'dev_task_unblocked'
|
|
| 'dev_task_transferred'
|
|
| 'test_case_created'
|
|
| 'test_case_started'
|
|
| 'test_case_passed'
|
|
| 'test_case_failed'
|
|
| 'test_case_blocked'
|
|
| 'bug_created'
|
|
| 'bug_fixing'
|
|
| 'bug_fixed'
|
|
| 'bug_closed'
|
|
| 'bug_blocked'
|
|
| 'bug_transferred'
|
|
| 'progress_note_added';
|
|
|
|
export interface WorkActivity {
|
|
id: string;
|
|
actorId: string;
|
|
date: string;
|
|
occurredAt: string;
|
|
sourceType: WorkActivitySourceType;
|
|
sourceId: string;
|
|
action: WorkActivityAction;
|
|
category: WorkActivityCategory;
|
|
title: string;
|
|
summary: string;
|
|
metadata?: {
|
|
fromStatus?: string;
|
|
toStatus?: string;
|
|
note?: string;
|
|
blocker?: string;
|
|
helperId?: string;
|
|
delayRisk?: string;
|
|
nextStartAt?: string;
|
|
[key: string]: unknown;
|
|
};
|
|
}
|
|
|
|
export type WorkActivityDraft = Omit<WorkActivity, 'id' | 'date' | 'occurredAt'> & {
|
|
date?: string;
|
|
occurredAt?: string;
|
|
};
|
|
|
|
export const WORK_ACTIVITY_CATEGORY_LABEL: Record<WorkActivityCategory, string> = {
|
|
delivery: '今日交付',
|
|
progress: '今日推进',
|
|
creation: '今日新增',
|
|
risk: '风险/阻塞',
|
|
note: '进展说明',
|
|
};
|
|
|
|
export function mergeWorkActivities(remote: WorkActivity[] = [], local: WorkActivity[] = []): WorkActivity[] {
|
|
const byId = new Map<string, WorkActivity>();
|
|
for (const item of remote) byId.set(item.id, item);
|
|
for (const item of local) byId.set(item.id, item);
|
|
return Array.from(byId.values()).sort((a, b) => a.occurredAt.localeCompare(b.occurredAt));
|
|
}
|