Files
ok_r/app/api/seed/route.ts
2026-01-25 21:55:29 +08:00

285 lines
8.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export const dynamic = 'force-dynamic';
import { NextResponse } from 'next/server';
import { supabase } from '@/lib/supabase';
function addDays(date: Date, days: number): string {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result.toISOString().split('T')[0];
}
export async function POST() {
const today = new Date();
const todayStr = today.toISOString().split('T')[0];
const ownerUser = {
name: '老板',
role: 'owner' as const,
avatar_url: null,
};
const pmUser = {
name: '张项目经理',
role: 'pm' as const,
avatar_url: null,
};
const memberUser = {
name: '李工程师',
role: 'member' as const,
avatar_url: null,
};
const { data: users, error: usersError } = await supabase
.from('users')
.insert([ownerUser, pmUser, memberUser])
.select();
if (usersError || !users) {
return NextResponse.json({ error: usersError?.message || '创建用户失败' }, { status: 500 });
}
const [owner, pm, member] = users;
const project1 = {
name: '产品升级项目',
description: '核心产品功能升级与优化',
owner_id: owner.id,
pm_id: pm.id,
project_type: '产品研发',
status: 'green' as const,
};
const project2 = {
name: '市场拓展计划',
description: '新市场开拓与客户获取',
owner_id: owner.id,
pm_id: pm.id,
project_type: '市场营销',
status: 'yellow' as const,
};
const { data: projects, error: projectsError } = await supabase
.from('projects')
.insert([project1, project2])
.select();
if (projectsError || !projects) {
return NextResponse.json({ error: projectsError?.message || '创建项目失败' }, { status: 500 });
}
const [proj1, proj2] = projects;
await supabase.from('project_members').insert([
{ project_id: proj1.id, user_id: owner.id },
{ project_id: proj1.id, user_id: pm.id },
{ project_id: proj1.id, user_id: member.id },
{ project_id: proj2.id, user_id: owner.id },
{ project_id: proj2.id, user_id: pm.id },
]);
const objective1 = {
project_id: proj1.id,
title: '提升产品用户体验和性能',
description: '通过优化核心功能,提升用户满意度和系统性能',
period_start: addDays(today, -15),
period_end: addDays(today, 15),
created_by: owner.id,
};
const { data: objectives, error: objectivesError } = await supabase
.from('objectives')
.insert([objective1])
.select();
if (objectivesError || !objectives) {
return NextResponse.json({ error: objectivesError?.message || '创建目标失败' }, { status: 500 });
}
const [obj1] = objectives;
const krs = [
{
project_id: proj1.id,
objective_id: obj1.id,
period_type: '1w' as const,
period_name: '本周',
period_start: addDays(today, -3),
period_end: addDays(today, 4),
title: '完成首页加载速度优化',
metric_name: '页面加载时间',
unit: '秒',
direction: 'decrease' as const,
target_value: 2,
current_value: 2.8,
owner_user_id: member.id,
confidence: 85,
status: 'green' as const,
reason_code: null,
note: null,
need_owner_help: false,
},
{
project_id: proj1.id,
objective_id: obj1.id,
period_type: '3d' as const,
period_name: '紧急任务',
period_start: todayStr,
period_end: addDays(today, 3),
title: '修复关键Bug',
metric_name: 'Bug修复数',
unit: '个',
direction: 'increase' as const,
target_value: 5,
current_value: 2,
owner_user_id: member.id,
confidence: 70,
status: 'yellow' as const,
reason_code: 'RESOURCE' as const,
note: '需要更多测试资源',
},
{
project_id: proj1.id,
objective_id: obj1.id,
period_type: '2w' as const,
period_name: '双周迭代',
period_start: addDays(today, -7),
period_end: addDays(today, 7),
title: '提升用户满意度评分',
metric_name: 'NPS评分',
unit: '分',
direction: 'increase' as const,
target_value: 50,
current_value: 35,
owner_user_id: pm.id,
confidence: 60,
status: 'yellow' as const,
reason_code: 'DEPENDENCY' as const,
note: '依赖功能还未上线',
need_owner_help: false,
},
{
project_id: proj2.id,
objective_id: null,
period_type: 'monthly' as const,
period_name: '月度目标',
period_start: addDays(today, -10),
period_end: addDays(today, 20),
title: '新客户获取',
metric_name: '新签客户数',
unit: '家',
direction: 'increase' as const,
target_value: 10,
current_value: 3,
owner_user_id: pm.id,
confidence: 45,
status: 'red' as const,
reason_code: 'EXECUTION' as const,
note: '市场推广效果不及预期',
need_owner_help: true,
},
];
const { data: krsData, error: krsError } = await supabase
.from('krs')
.insert(krs)
.select();
if (krsError || !krsData) {
return NextResponse.json({ error: krsError?.message || '创建KR失败' }, { status: 500 });
}
const checkins = krsData.flatMap((kr) => {
const baseCheckins = [];
for (let i = 0; i < 20; i++) {
const checkinDate = addDays(today, -i - 1);
const progressMultiplier = (20 - i) / 21;
baseCheckins.push({
kr_id: kr.id,
project_id: kr.project_id,
user_id: kr.owner_user_id,
date: checkinDate,
current_value: kr.current_value * progressMultiplier,
delta_value: kr.current_value * 0.1,
confidence: kr.confidence + (i * 5),
status_snapshot: i === 0 ? kr.status : 'green',
reason_code: i === 0 ? kr.reason_code : null,
note: i === 0 ? `进度更新 - ${kr.title}` : null,
});
}
return baseCheckins;
});
await supabase.from('checkins').insert(checkins);
const meeting = {
project_id: proj1.id,
period_start: addDays(today, -7),
period_end: addDays(today, -1),
summary: `本周期完成情况总结:
- 页面加载优化进展顺利,预计可按时完成
- Bug修复进度略有滞后,需要协调测试资源
- 用户满意度提升依赖新功能上线
完成率:约65%`,
decisions: `1. 协调测试团队支援Bug修复
2. 推动依赖功能优先上线
3. 下周进行用户回访收集反馈`,
risks: `- 测试资源紧张可能影响交付质量
- 依赖功能延期风险`,
next_period_commitments: `- 完成所有关键Bug修复
- 页面加载时间降至2秒以内
- 收集至少20份用户反馈`,
created_by: pm.id,
};
await supabase.from('meetings').insert([meeting]);
const metrics = [
{ name: '页面加载时间', unit: '秒', direction: 'decrease' as const, category: '技术性能' },
{ name: 'Bug修复数', unit: '个', direction: 'increase' as const, category: '质量' },
{ name: 'NPS评分', unit: '分', direction: 'increase' as const, category: '用户体验' },
{ name: '新签客户数', unit: '家', direction: 'increase' as const, category: '业务' },
{ name: '活跃用户数', unit: '人', direction: 'increase' as const, category: '业务' },
{ name: '客户流失率', unit: '%', direction: 'decrease' as const, category: '业务' },
{ name: '代码覆盖率', unit: '%', direction: 'increase' as const, category: '质量' },
{ name: '响应时间', unit: 'ms', direction: 'decrease' as const, category: '技术性能' },
];
await supabase.from('metrics').insert(metrics);
const templates = [
{
name: '产品迭代模板',
description: '适用于产品功能迭代的KR模板',
project_type: '产品研发',
tags: ['产品', '迭代', '功能'],
items: [
{ title: '功能上线', metricName: '功能完成数', unit: '个', direction: 'increase', targetValue: 3 },
{ title: '性能优化', metricName: '响应时间', unit: 'ms', direction: 'decrease', targetValue: 200 },
{ title: '质量保障', metricName: 'Bug数', unit: '个', direction: 'decrease', targetValue: 5 },
],
},
{
name: '市场拓展模板',
description: '适用于市场营销项目的KR模板',
project_type: '市场营销',
tags: ['市场', '营销', '客户'],
items: [
{ title: '客户获取', metricName: '新客户数', unit: '家', direction: 'increase', targetValue: 10 },
{ title: '线索转化', metricName: '转化率', unit: '%', direction: 'increase', targetValue: 30 },
{ title: '客户留存', metricName: '续约率', unit: '%', direction: 'increase', targetValue: 85 },
],
},
];
await supabase.from('templates').insert(templates);
return NextResponse.json({
success: true,
ownerId: owner.id,
message: '演示数据已成功创建',
});
}