后端: - 事件流模型(project_cost_events / project_revenue_events)+ launchedAt 截断 - 3 大业务体系归属(airhubs/airflow/aircore) + 项目类型(hw/sw) + identifier 自动生成 - AI 三件套推荐(category + bizSystem + projectType) - 营收 mock API + 外部对接规范 + 资产摊销 cron - 5 个 migration(0003 ROI 引擎 / 0004 driver factors / 0005 biz system) - 单测 11/11 过 前端: - 项目级 ROI 看板:4 KPI 卡片 + 折线图(周/月/年)+ 成本/产出事件流并排 - 全公司决策罗盘:3 大 ROI 指标 + 业务线堆叠 + 分类筛选 chip - 项目列表 + 侧边栏:按产品线分组(可折叠 + localStorage 持久化) - Admin: ROI 策略配置 + 项目映射 + 未映射收容 数据: - 23 项目全部 AI 自动分类 + 自动 identifier(airhubs-hw-001 这种) - launchedAt 按各项目首次 commit 时间设置 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
123 lines
5.5 KiB
SQL
123 lines
5.5 KiB
SQL
-- ROI 动态规则引擎(v2.0) — 事件流模型
|
|
-- 包含: projects 扩展字段、roi_strategies、project_cost_events、project_revenue_events、
|
|
-- project_revenue_mapping、unmapped_revenue_events、sync_logs.source 枚举扩展
|
|
|
|
-- ── 1. 扩展 projects 表 ──
|
|
ALTER TABLE `projects` ADD COLUMN `category` enum('cash_cow','efficiency_tool','moat','composite') NULL;
|
|
--> statement-breakpoint
|
|
ALTER TABLE `projects` ADD COLUMN `composite_strategies` json NULL;
|
|
--> statement-breakpoint
|
|
ALTER TABLE `projects` ADD COLUMN `owner_id` varchar(50) NULL;
|
|
--> statement-breakpoint
|
|
ALTER TABLE `projects` ADD COLUMN `tags` json NULL;
|
|
--> statement-breakpoint
|
|
ALTER TABLE `projects` ADD COLUMN `launched_at` datetime NULL;
|
|
--> statement-breakpoint
|
|
ALTER TABLE `projects` ADD COLUMN `v_asset` double NULL;
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_projects_category` ON `projects` (`category`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 2. 扩展 sync_logs.source 枚举 ──
|
|
ALTER TABLE `sync_logs` MODIFY COLUMN `source` enum('plane','gitea','ai_okr','roi_cost_ingest','roi_revenue_ingest','roi_amortizer','roi_ai_driver') NOT NULL;
|
|
--> statement-breakpoint
|
|
|
|
-- ── 3. roi_strategies ──
|
|
CREATE TABLE IF NOT EXISTS `roi_strategies` (
|
|
`id` varchar(50) NOT NULL PRIMARY KEY,
|
|
`category` enum('cash_cow','efficiency_tool','moat','composite') NOT NULL,
|
|
`name` varchar(200) NOT NULL,
|
|
`formula_key` varchar(100) NOT NULL,
|
|
`params` json NOT NULL,
|
|
`updated_at` datetime NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_roi_strategy_category` ON `roi_strategies` (`category`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 4. project_cost_events ──
|
|
CREATE TABLE IF NOT EXISTS `project_cost_events` (
|
|
`id` varchar(50) NOT NULL PRIMARY KEY,
|
|
`project_id` varchar(50) NOT NULL,
|
|
`event_date` datetime NOT NULL,
|
|
`cost_type` enum('dev_hours','hardware_bom','service_fee','amortization','other') NOT NULL,
|
|
`amount` double NOT NULL,
|
|
`hours` double NULL,
|
|
`hourly_rate_used` double NULL,
|
|
`data_source` enum('auto_commits','auto_tasks','plane_actual','manual','amortization_cron') NOT NULL,
|
|
`ref_type` varchar(50) NULL,
|
|
`ref_id` varchar(200) NULL,
|
|
`notes` text NULL,
|
|
`created_by` varchar(50) NULL,
|
|
`created_at` datetime NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_cost_events_project_date` ON `project_cost_events` (`project_id`, `event_date`);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_cost_events_ref` ON `project_cost_events` (`project_id`, `ref_type`, `ref_id`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 5. project_revenue_events ──
|
|
CREATE TABLE IF NOT EXISTS `project_revenue_events` (
|
|
`id` varchar(50) NOT NULL PRIMARY KEY,
|
|
`project_id` varchar(50) NOT NULL,
|
|
`event_date` datetime NOT NULL,
|
|
`revenue_type` enum('direct_revenue','subscription','saved_cost','asset_value_add','refund','other') NOT NULL,
|
|
`amount` double NOT NULL,
|
|
`data_source` enum('api_pulled','manual','calculated','mock') NOT NULL,
|
|
`ref_type` varchar(50) NULL,
|
|
`ref_id` varchar(200) NULL,
|
|
`channel` varchar(50) NULL,
|
|
`notes` text NULL,
|
|
`created_by` varchar(50) NULL,
|
|
`created_at` datetime NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_revenue_events_project_date` ON `project_revenue_events` (`project_id`, `event_date`);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_revenue_events_ref` ON `project_revenue_events` (`project_id`, `ref_type`, `ref_id`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 6. project_revenue_mapping ──
|
|
CREATE TABLE IF NOT EXISTS `project_revenue_mapping` (
|
|
`id` varchar(50) NOT NULL PRIMARY KEY,
|
|
`project_id` varchar(50) NOT NULL,
|
|
`business_project_key` varchar(100) NOT NULL,
|
|
`enabled` int NULL DEFAULT 1,
|
|
`notes` text NULL,
|
|
`created_at` datetime NOT NULL,
|
|
`updated_at` datetime NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_revenue_mapping_business_key` ON `project_revenue_mapping` (`business_project_key`);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_revenue_mapping_project` ON `project_revenue_mapping` (`project_id`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 7. unmapped_revenue_events ──
|
|
CREATE TABLE IF NOT EXISTS `unmapped_revenue_events` (
|
|
`id` varchar(50) NOT NULL PRIMARY KEY,
|
|
`external_id` varchar(200) NOT NULL,
|
|
`business_project_key` varchar(100) NOT NULL,
|
|
`event_date` datetime NOT NULL,
|
|
`amount` double NOT NULL,
|
|
`revenue_type` varchar(50) NULL,
|
|
`channel` varchar(50) NULL,
|
|
`raw_payload` json NULL,
|
|
`status` enum('pending','resolved','ignored') NULL DEFAULT 'pending',
|
|
`resolved_event_id` varchar(50) NULL,
|
|
`created_at` datetime NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_unmapped_external_id` ON `unmapped_revenue_events` (`external_id`);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_unmapped_status` ON `unmapped_revenue_events` (`status`);
|
|
--> statement-breakpoint
|
|
|
|
-- ── 8. seed: 4 套默认策略参数 ──
|
|
INSERT INTO `roi_strategies` (`id`, `category`, `name`, `formula_key`, `params`, `updated_at`) VALUES
|
|
('strat-cash-cow', 'cash_cow', '现金牛', 'cash_cow', '{"hourlyRate":400,"commitHourCoef":0.5,"taskHourCoef":6}', NOW()),
|
|
('strat-efficiency-tool', 'efficiency_tool', '效能工具', 'efficiency_tool', '{"hourlyRate":400,"commitHourCoef":0.5,"taskHourCoef":6}', NOW()),
|
|
('strat-moat', 'moat', '资本护城河', 'moat', '{"hourlyRate":400,"amortYears":3,"commitHourCoef":0.5,"taskHourCoef":6}', NOW()),
|
|
('strat-composite', 'composite', '复合型', 'composite', '{"hourlyRate":400,"amortYears":3,"commitHourCoef":0.5,"taskHourCoef":6}', NOW());
|