import type { Bug, BugStatus } from './bug'; import type { DevTask, DevTaskStatus } from './dev-task'; import type { TestCase, TestCaseStatus } from './test-case'; import { REQUIREMENT_COVERAGE_LABEL, type VersionPlan, type VersionPlanLog } from './version-plan'; import type { WorkActivityDraft } from './work-activity'; const PLAN_TYPE_LABEL: Record = { research: '调研', product: '产品方案', ui: 'UI设计', }; export function makeVersionPlanCreatedActivity(plan: VersionPlan, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'version_plan', sourceId: plan.id, action: 'version_plan_created', category: 'creation', title: plan.title, summary: `新建${PLAN_TYPE_LABEL[plan.type]}:${plan.title}`, }; } export function makeVersionPlanStartedActivity(plan: VersionPlan, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'version_plan', sourceId: plan.id, action: 'version_plan_started', category: 'progress', title: plan.title, summary: `开始${PLAN_TYPE_LABEL[plan.type]}:${plan.title}`, }; } export function makeVersionPlanCompletedActivity(plan: VersionPlan, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'version_plan', sourceId: plan.id, action: 'version_plan_completed', category: 'delivery', title: plan.title, summary: `完成${PLAN_TYPE_LABEL[plan.type]}:${plan.title}`, }; } export function makeVersionPlanRequirementProgressActivity(plan: VersionPlan, log: VersionPlanLog): WorkActivityDraft | undefined { if (log.type !== 'requirement_progress') return undefined; if (plan.type !== 'product' && plan.type !== 'ui') return undefined; const requirementLabel = [log.requirementCode, log.requirementTitle].filter(Boolean).join(' ') || '需求'; const statusLabel = log.coverageStatus ? REQUIREMENT_COVERAGE_LABEL[log.coverageStatus] : '进度更新'; return { actorId: log.actor, sourceType: 'version_plan', sourceId: plan.id, action: 'version_plan_requirement_progress', category: 'progress', title: plan.title, summary: `推进${PLAN_TYPE_LABEL[plan.type]}需求:${requirementLabel}(${statusLabel})`, occurredAt: log.createdAt, metadata: { requirementId: log.requirementId, requirementCode: log.requirementCode, requirementTitle: log.requirementTitle, coverageStatus: log.coverageStatus, completedContent: log.completedContent, remainingContent: log.remainingContent, }, }; } export function makeDevTaskCreatedActivity(task: DevTask, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'dev_task', sourceId: task.id, action: 'dev_task_created', category: 'creation', title: task.title, summary: `新建开发任务:${task.title}`, }; } export function makeDevTaskStatusActivity( task: DevTask, fromStatus: DevTaskStatus, toStatus: DevTaskStatus, actorId: string, ): WorkActivityDraft | undefined { const base = { actorId, sourceType: 'dev_task' as const, sourceId: task.id, title: task.title, metadata: { fromStatus, toStatus }, }; if (toStatus === 'in_progress') { return { ...base, action: 'dev_task_started', category: 'progress', summary: `开始开发:${task.title}`, }; } if (toStatus === 'testing') { return { ...base, action: 'dev_task_self_testing', category: 'progress', summary: `进入自测:${task.title}`, }; } if (toStatus === 'submitted') { return { ...base, action: 'dev_task_submitted', category: 'delivery', summary: `已提测开发任务:${task.title}`, }; } return undefined; } export function makeDevTaskBlockedActivity( task: DevTask, actorId: string, reason?: string, helperId?: string, ): WorkActivityDraft { return { actorId, sourceType: 'dev_task', sourceId: task.id, action: 'dev_task_blocked', category: 'risk', title: task.title, summary: `标记阻塞:${reason?.trim() || task.title}`, metadata: { blocker: reason?.trim() || undefined, helperId: helperId?.trim() || undefined, }, }; } export function makeDevTaskUnblockedActivity(task: DevTask, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'dev_task', sourceId: task.id, action: 'dev_task_unblocked', category: 'progress', title: task.title, summary: `解除阻塞:${task.title}`, }; } export function makeBugCreatedActivity(bug: Bug, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'bug', sourceId: bug.id, action: 'bug_created', category: 'creation', title: bug.title, summary: `新建 Bug:${bug.title}`, }; } export function makeTestCaseCreatedActivity(testCase: TestCase, actorId: string): WorkActivityDraft { return { actorId, sourceType: 'test_case', sourceId: testCase.id, action: 'test_case_created', category: 'creation', title: testCase.title, summary: `新建测试用例:${testCase.title}`, }; } export function makeTestCaseStatusActivity( testCase: TestCase, fromStatus: TestCaseStatus, toStatus: TestCaseStatus, actorId: string, ): WorkActivityDraft | undefined { const base = { actorId, sourceType: 'test_case' as const, sourceId: testCase.id, title: testCase.title, metadata: { fromStatus, toStatus }, }; if (toStatus === 'running') { return { ...base, action: 'test_case_started', category: 'progress', summary: `开始测试:${testCase.title}`, }; } if (toStatus === 'passed') { return { ...base, action: 'test_case_passed', category: 'delivery', summary: `测试通过:${testCase.title}`, }; } if (toStatus === 'failed') { return { ...base, action: 'test_case_failed', category: 'risk', summary: `测试不通过:${testCase.title}`, }; } if (toStatus === 'blocked') { return { ...base, action: 'test_case_blocked', category: 'risk', summary: `测试阻塞:${testCase.title}`, }; } return undefined; } export function makeBugStatusActivity( bug: Bug, fromStatus: BugStatus, toStatus: BugStatus, actorId: string, ): WorkActivityDraft | undefined { const base = { actorId, sourceType: 'bug' as const, sourceId: bug.id, title: bug.title, metadata: { fromStatus, toStatus }, }; if (toStatus === 'fixing') { return { ...base, action: 'bug_fixing', category: 'progress', summary: `开始修复 Bug:${bug.title}`, }; } if (toStatus === 'fixed') { return { ...base, action: 'bug_fixed', category: 'delivery', summary: `已修复 Bug:${bug.title}`, }; } if (toStatus === 'closed') { return { ...base, action: 'bug_closed', category: 'delivery', summary: `已关闭 Bug:${bug.title}`, }; } return undefined; } export function makeBugTransferredActivity(bug: Bug, actorId: string, toAssigneeId: string): WorkActivityDraft { return { actorId, sourceType: 'bug', sourceId: bug.id, action: 'bug_transferred', category: 'progress', title: bug.title, summary: `转交 Bug:${bug.title} → ${toAssigneeId}`, metadata: { toAssigneeId }, }; }