This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-MVP/apps/web/src/shared/gov/gov-route.ts
T
ChaiHaoandClaude Opus 5 e5cfca638f 运营中心撤掉「数据」区;流程包首页重排:卡有层次、⋯ 管编辑与删除、新建变幽灵卡
**运营 · 数据(活动记忆四层)整个撤掉** —— 记忆的放行口还没成形,摆一个空区不如
不摆;真要做时随「数据资产」一并重开。区表、面归属、shell 映射、KnowledgeHome /
MemPage、活动详情里那枚入口一并清干净;旧深链 `#/gov/memory/layers` 落运营首页
(测试跟着改口径,不留死链)。运营中心自此六区。

**流程包首页**:
  · 「编排要素:四种」这枚计数删了 —— 网关早废,它是句没人用的口号;
  · 卡片重做。从前是「头 + 芯片行 + 一大片空 + 脚注」,158 高全靠留白撑;
    现在两段:头(图标 · 名 · 标识 · 生效版 · ⋯)+ **数据板**(活动/审批/边闭合/版本
    四格等宽、竖线分隔)。段段有内容、段间有线,高矮由内容说了算 —— 实测 111 高;
  · 卡上 **⋯ 菜单**:编辑(就地改名,落在卡面那一版上)/ 删除(整条流,菜单原地翻成
    确认,不另弹窗);
  · **新建按钮变幽灵卡**:虚线卡住在货架末位,与真卡同宽同高(111/111)。

删整条流是新能力:`DELETE /api/gov/process/:id` + `process.deleteFlow`。
生效版这道闸不设(明示动作,不是手滑),在途单那道照设(PinnedVersionError → 409);
**「还有调起规则指着它」由路由层反查** —— process 是 L7,不该知道 trigger 的存在。

实测(丁子乔账号):改名往返、删除被 2 条调起规则如实挡回、幽灵卡建 `tmp-drop`
再删掉整条流,库里回到只剩 unified-quote v4,试跑数据已清。五闸绿。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-29 22:38:52 +08:00

237 lines
11 KiB
TypeScript
Raw 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.
/**
* 治理台的分级页面路由 —— 自原型 `Governance.tsx` 第 25–90 行平移。
*
* 「不用抽屉、不用弹窗:每一层内容都有自己的页面。」
* 区 → 对象 → 子维度 → 元素,顶部面包屑可回跳任意一级,Esc / 返回退一级。
*/
export type Route =
| { k: 'wf'; id: string }
| { k: 'task'; id: string }
| { k: 'tasklog'; id: string }
| { k: 'apr'; id: string }
| { k: 'emp'; id: string }
| { k: 'role'; id: string }
| { k: 'pkg'; id: string }
| { k: 'trigger'; id: string }
| { k: 'act'; id: string }
| { k: 'tool'; id: string }
| { k: 'obj'; id: string }
| { k: 'llm'; id: string }
| { k: 'chan'; id: string };
/**
* 十一区 —— 分属两个台面(见 `surfaces.ts`):
* 设计中心定义企业(战略 → 方法 → 能力 → 对象),运营中心看企业跑。
* 触发器不再独立成区:定义并入 workflows,启停并入 tasks;
* 记忆只剩度量:升为 cockpit 首页。活动记忆那一区(运营 · 数据)2026-07-29 撤销 ——
* 记忆的放行口未建成形,摆一个空区不如不摆;真要做时随「数据资产」一并重开。
*/
export const GOV_ZONES = [
/*
* 设计中心九区,顺序即设计的次序:
* 蓝图(全局) → 触发器(谁调起) → 流程包(怎么流转) → 活动库(每件事怎么干)
* → 工具箱(能对世界做什么) → 数据域(运营什么) → 知识库(资料,待建)
* → 大模型(模型实例绑在哪) → 测试台(跑一遍看看)
*/
'blueprint',
'triggers',
'workflows',
'library',
'tools',
'data',
'archive',
'models',
'testbed',
// 运营中心 —— 区名即运行时:工作流是流程包的运行时,任务是活动的运行时
'cockpit',
'runs',
'tasks',
'people',
'ledgers',
'system',
] as const;
export type GovZone = (typeof GOV_ZONES)[number];
export const ZONES: ReadonlyArray<{ key: GovZone; label: string; icon: string }> = [
{ key: 'blueprint', label: '蓝图', icon: 'route' },
{ key: 'triggers', label: '触发器', icon: 'zap' },
{ key: 'workflows', label: '流程包', icon: 'workflow' },
{ key: 'library', label: '活动库', icon: 'boxes' },
{ key: 'tools', label: '工具箱', icon: 'wrench' },
{ key: 'data', label: '数据域', icon: 'database' },
{ key: 'archive', label: '知识库', icon: 'library' },
{ key: 'models', label: '大模型', icon: 'cpu' },
{ key: 'testbed', label: '测试台', icon: 'flask-conical' },
{ key: 'cockpit', label: '驾驶舱', icon: 'gauge' },
{ key: 'runs', label: '工作流', icon: 'activity' },
{ key: 'tasks', label: '任务', icon: 'list-checks' },
{ key: 'people', label: '员工', icon: 'users' },
{ key: 'ledgers', label: '台账', icon: 'table' },
{ key: 'system', label: '系统', icon: 'settings' },
];
/** 区元信息:标题 / 定位说明 / 主色 —— 说明文取自两卷规范,不是装饰 */
export const ZM: Readonly<Record<GovZone, { title: string; desc: string; accent: string; icon: string }>> = {
blueprint: {
title: '企业蓝图',
icon: 'route',
accent: 'linear-gradient(140deg,#4954e6,#232b6e)',
desc: '战略 → 方法 → 能力 → 对象:流程包决定企业以哪些流转运转,活动库决定每件事怎么干,工具箱决定系统能对世界做什么,数据域决定企业运营什么。四库的健康度与待补清单聚在这一屏——设计者看的是定义完不完整,不是今天忙不忙。',
},
cockpit: {
title: '经营驾驶舱',
icon: 'gauge',
accent: 'linear-gradient(140deg,#12b886,#0b7a5c)',
desc: '看企业今天跑得怎样:度量八指标(自主率与纠正率成对读,复合为有效自主率)+ 异常面(异常工作流、需处置件数)。指标零埋点——全部由留痕投影而来,点数字直达处置页。',
},
ledgers: {
title: '台账管理',
icon: 'table',
accent: 'linear-gradient(140deg,#245bdb,#16307a)',
desc: '行数据 · 版本 · 引用——域的结构在设计中心改,这里做运营动作。域即页签,随数据域发布生长:设计侧一发布新域,台账里自动多一个域页签。',
},
runs: {
title: '工作流',
icon: 'activity',
accent: 'linear-gradient(140deg,#3370ff,#245bdb)',
desc: '流程包的运行时:在途工作流的监控,和每个包的运行配置——起单开关、命中后要不要人工确认、谁来确认、每个节点归谁负责。设计中心定义流程长什么样,这里管它今天怎么跑。',
},
tasks: {
title: '任务管理',
icon: 'list-checks',
accent: 'linear-gradient(140deg,#3370ff,#245bdb)',
desc: '活动的运行时:任务 = 活动被调起的一次运行,恰有一名负责人。这里做任务与审批单的在途监控、干预与控制——暂停可恢复、叫停归负责人、终止级联作废。工作流一级去「工作流」区看。',
},
people: {
title: '员工管理',
icon: 'users',
accent: 'linear-gradient(140deg,#2bc7d4,#0e9fd8)',
desc: '员工负载、岗位与授权。权限按岗位授予:客体三类 × 动作三种;停用前置检查——在途任务与待答卡须先改派完毕。',
},
workflows: {
title: '流程包管理',
icon: 'workflow',
accent: 'linear-gradient(140deg,#4954e6,#3a44c9)',
desc: '战略——企业以哪些流转运转。一条流一个包,版本收在包内部:画图不检查、激活才查完整,恰一个生效版本、在途按启动版本跑完。边只表达顺序与条件(对齐 Mastra),数据按输入/输出字段名流动——约束力在两端活动契约上。触发器已独立成区;启停在运营中心。',
},
library: {
title: '活动库',
icon: 'boxes',
accent: 'linear-gradient(140deg,#0aa294,#0a6a64)',
desc: '已安装活动的资产货架:活动是任务的定义——编排引用一个活动,运行时就长出一个任务。审批点与网关是系统内置要素,零开发、不入库。业务分类 × 活动类型两维,每活动两条版本序列。',
},
tools: {
title: '工具箱',
icon: 'wrench',
accent: 'linear-gradient(140deg,#7f3bf5,#5b21cf)',
desc: '能力——系统能对世界做什么。一件事能交给谁办的全集:功能工具(交给系统)、LLM 工具(交给模型)、人类工具(交给人)。读类过程中自由调用,写类只登记动作意向、放行后落地;密钥只存治理台,不入包、不入活动。',
},
data: {
title: '数据域',
icon: 'database',
accent: 'linear-gradient(140deg,#0e9fd8,#245bdb)',
desc: '对象——企业运营什么。域 × 对象的结构定义:声明物化(最大化合并、只增不破坏)与调用接入(事实源在外)。数据可以自生长,权力不可以自生长。行数据不在这里看——那在运营中心的台账。',
},
testbed: {
title: '联调测试台',
icon: 'flask-conical',
accent: 'linear-gradient(140deg,#e8833a,#c25f1a)',
desc: '把定义试着跑一遍:装一次调用、指派每个节点归谁、起单看穿全程。真实任务照旧落到被指派人的工作台,测试台不代答。一次只跑一条流,生命周期跟着仿真状态——停止仿真,这条流连同它派出的任务一起销毁。',
},
triggers: {
title: '触发器',
icon: 'zap',
accent: 'linear-gradient(140deg,#f0a020,#c47a0a)',
desc: '谁调起流程:事件(通道来件命中规则)、登记(人在表单上起一单)、周期(到点自己起)。规则在这里定,起单开关在运营中心。',
},
archive: {
title: '知识库',
icon: 'library',
accent: 'linear-gradient(140deg,#8a5f1c,#5e3f10)',
desc: '企业的资料与文档 —— 规范、图纸、样例、外部材料。待建。',
},
models: {
title: '大模型',
icon: 'cpu',
accent: 'linear-gradient(140deg,#4b4a8c,#2f2e63)',
desc: '模型实例的四元绑定(Provider / URL / Key / Model)。活动只声明用途名,换厂商换型号改这里,活动一行不动;密钥只存这儿,不入包、不入留痕。',
},
system: {
title: '系统管理',
icon: 'settings',
accent: 'linear-gradient(140deg,#46586a,#2b3644)',
desc: '系统边界的配置面:通道实例——归属键规则与默认认领岗位。模型实例已独立成设计中心的「大模型」区。',
},
};
/**
* 区内页签 —— **多数区只有一格**:一区一内容,页签栏此时由壳层收起,不占一行。
* 还留着多格的只有运营侧的任务与员工(它们确实是几个不同维度),
* 以及 `ledgers`:它的页签是数据域,随发布动态生成(壳层运行时铺开),故此表留空。
*/
export const TABS: Readonly<Record<GovZone, ReadonlyArray<{ key: string; label: string; ico: string }>>> = {
blueprint: [{ key: 'map', label: '企业蓝图', ico: 'route' }],
testbed: [{ key: 'run', label: '仿真试跑', ico: 'flask-conical' }],
triggers: [{ key: 'rules', label: '调起规则', ico: 'zap' }],
archive: [{ key: 'docs', label: '资料', ico: 'library' }],
models: [{ key: 'llm', label: '模型实例', ico: 'cpu' }],
workflows: [{ key: 'pkgs', label: '流程包', ico: 'boxes' }],
library: [{ key: 'shelf', label: '活动货架', ico: 'boxes' }],
tools: [{ key: 'catalog', label: '能力目录', ico: 'wrench' }],
data: [{ key: 'domains', label: '数据对象', ico: 'database' }],
cockpit: [{ key: 'dash', label: '驾驶舱', ico: 'gauge' }],
runs: [
{ key: 'board', label: '在途工作流', ico: 'activity' },
{ key: 'conf', label: '运行配置', ico: 'settings' },
],
tasks: [
{ key: 'list', label: '任务', ico: 'list-checks' },
{ key: 'apr', label: '审批单', ico: 'shield-check' },
{ key: 'todo', label: '需处置', ico: 'flag' },
],
people: [
{ key: 'emp', label: '员工', ico: 'users' },
{ key: 'roles', label: '岗位授权', ico: 'key' },
{ key: 'groups', label: '工作组', ico: 'users' },
],
ledgers: [], // 动态:页签即数据域(短名呈现),由壳层按已发布域生成
system: [{ key: 'chan', label: '通道实例', ico: 'mail' }],
};
export function routeLabel(r: Route): string {
switch (r.k) {
case 'wf':
return '工作流';
case 'task':
return '任务';
case 'tasklog':
return '任务日志';
case 'apr':
return '审批单';
case 'emp':
return '员工';
case 'role':
return '岗位授权';
case 'pkg':
return '流程包';
case 'trigger':
return '触发器';
case 'act':
return '活动';
case 'tool':
return '工具';
case 'obj':
return '数据对象';
case 'llm':
return 'LLM 实例';
case 'chan':
return '通道实例';
}
}
export type Nav = {
push: (r: Route) => void;
jump: (z: GovZone, tab: string, r?: Route) => void;
};