Files
ftb-project-management/apps/web/lib/work-activity.ts
Script Generator 3d3d56697a feat(版本): 完善研发计划与预警已读
关键改动:

- 增加版本表单、发布校验和调研方向进度规则

- 扩展小宝预警已读状态、风险签名和今日证据

- 补充组长权限、加班查看范围、活动记录与相关测试

Co-Authored-By: Codex GPT-5 <codex@openai.com>
2026-06-30 16:48:58 +08:00

72 lines
1.9 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;
[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));
}