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, WorkActivitySourceType } 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, workStartedAt: log.workStartedAt, }, }; } export function makeVersionPlanResearchDirectionProgressActivity(plan: VersionPlan, log: VersionPlanLog): WorkActivityDraft | undefined { if (log.type !== 'research_direction_progress') return undefined; if (plan.type !== 'research') return undefined; const directionTitle = log.directionTitle || '调研方向'; const statusLabel = log.coverageStatus ? REQUIREMENT_COVERAGE_LABEL[log.coverageStatus] : '进度更新'; return { actorId: log.actor, sourceType: 'version_plan', sourceId: plan.id, action: 'version_plan_research_direction_progress', category: 'progress', title: plan.title, summary: `推进调研方向:${directionTitle}(${statusLabel})`, occurredAt: log.createdAt, metadata: { directionTaskId: log.directionTaskId, directionTitle: log.directionTitle, coverageStatus: log.coverageStatus, completedContent: log.completedContent, remainingContent: log.remainingContent, workStartedAt: log.workStartedAt, }, }; } export interface ProgressNoteActivityInput { actorId: string; sourceType: WorkActivitySourceType; sourceId: string; title: string; note: string; nextStartAt: string; blocker?: string; helperId?: string; delayRisk?: string; } export function makeProgressNoteActivity(data: ProgressNoteActivityInput): WorkActivityDraft { const note = data.note.trim(); const blocker = data.blocker?.trim() || undefined; const helperId = data.helperId?.trim() || undefined; const delayRisk = data.delayRisk?.trim() || undefined; const nextStartAt = data.nextStartAt.trim(); const details = [ note, blocker ? `阻塞:${blocker}` : '', helperId ? `需协助:${helperId}` : '', delayRisk ? `延期风险:${delayRisk}` : '', ].filter(Boolean); return { actorId: data.actorId, sourceType: data.sourceType, sourceId: data.sourceId, action: 'progress_note_added', category: blocker || delayRisk ? 'risk' : 'note', title: data.title, summary: `补充进展:${details.join(';')}`, metadata: { note, blocker, helperId, delayRisk, nextStartAt: nextStartAt || undefined, }, }; } 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 }, }; }