Archived
**运营 · 数据(活动记忆四层)整个撤掉** —— 记忆的放行口还没成形,摆一个空区不如
不摆;真要做时随「数据资产」一并重开。区表、面归属、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
102 lines
4.3 KiB
TypeScript
102 lines
4.3 KiB
TypeScript
/**
|
|
* 三面骨架的唯一事实源 —— 区归属、亮灯、旧链接改写。
|
|
*
|
|
* 这里守的是「配置自洽」:每个区恰属一面(不重不漏);亮灯只看该面功能;旧深链一条不死。
|
|
* 三者都是纯函数,壳层只消费 —— 配置错了在这里就红,不必等到点开界面才发现。
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import type { Session } from '@contracts';
|
|
import { sessionSchema } from '@contracts';
|
|
import { GOV_ZONES } from '../gov-route.ts';
|
|
import { SURFACE_ZONES, canSeeSurface, legacyGovTarget, surfaceOfZone } from '../surfaces.ts';
|
|
|
|
/** 经 schema 构造合法会话 —— §12.5 禁 `as unknown as`,测试同样遵守 */
|
|
const sessionWith = (fns: readonly string[]): Session =>
|
|
sessionSchema.parse({
|
|
staff: { id: 's-1', account: 'a', name: 'n', positionId: 'p-1', state: 'active' },
|
|
position: { id: 'p-1', code: 'PM', name: '项目经理' },
|
|
grants: fns.map((fn) => ({
|
|
positionId: 'p-1',
|
|
object: { kind: 'governance', function: fn },
|
|
action: 'read',
|
|
})),
|
|
});
|
|
|
|
describe('SURFACE_ZONES —— 每个区恰属一面', () => {
|
|
it('两面之和即全部区,不重不漏', () => {
|
|
const all = [...SURFACE_ZONES.design, ...SURFACE_ZONES.ops];
|
|
expect([...all].sort()).toEqual([...GOV_ZONES].sort());
|
|
expect(new Set(all).size).toBe(all.length);
|
|
});
|
|
|
|
it('设计面没有任何运行态区', () => {
|
|
for (const zone of ['tasks', 'cockpit', 'ledgers'] as const) {
|
|
expect(SURFACE_ZONES.design).not.toContain(zone);
|
|
}
|
|
});
|
|
|
|
it('surfaceOfZone 与区表一致', () => {
|
|
expect(surfaceOfZone('workflows')).toBe('design');
|
|
expect(surfaceOfZone('ledgers')).toBe('ops');
|
|
});
|
|
});
|
|
|
|
describe('canSeeSurface —— 入口按授权亮灯', () => {
|
|
it('持有该面任一功能的授权即亮', () => {
|
|
expect(canSeeSurface(sessionWith(['process']), 'design')).toBe(true);
|
|
expect(canSeeSurface(sessionWith(['task']), 'ops')).toBe(true);
|
|
});
|
|
|
|
it('只有另一面的授权不亮', () => {
|
|
expect(canSeeSurface(sessionWith(['task']), 'design')).toBe(false);
|
|
expect(canSeeSurface(sessionWith(['activity']), 'ops')).toBe(false);
|
|
});
|
|
|
|
it('trigger 与 data 两面都算 —— 定义归设计,处置与行数据归运营', () => {
|
|
expect(canSeeSurface(sessionWith(['trigger']), 'design')).toBe(true);
|
|
expect(canSeeSurface(sessionWith(['trigger']), 'ops')).toBe(true);
|
|
expect(canSeeSurface(sessionWith(['data']), 'design')).toBe(true);
|
|
expect(canSeeSurface(sessionWith(['data']), 'ops')).toBe(true);
|
|
});
|
|
|
|
it('无会话不亮;无治理授权不亮', () => {
|
|
expect(canSeeSurface(undefined, 'design')).toBe(false);
|
|
expect(canSeeSurface(sessionWith([]), 'ops')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('legacyGovTarget —— 旧 #/gov 深链一条不死', () => {
|
|
it('设计态区改写到 /design,深链原样带走', () => {
|
|
expect(legacyGovTarget('#/gov/workflows/pkgs/pkg:unified-quote%404')).toBe(
|
|
'/design#/design/workflows/pkgs/pkg:unified-quote%404',
|
|
);
|
|
});
|
|
|
|
it('运行态区改写到 /ops', () => {
|
|
// 看板已迁「工作流」区(2026-07-30):工作流是流程包的运行时,一级看板归它
|
|
expect(legacyGovTarget('#/gov/tasks/board')).toBe('/ops#/ops/runs/board');
|
|
});
|
|
|
|
it('已删的区落到对应新家', () => {
|
|
expect(legacyGovTarget('#/gov/memory/metrics')).toBe('/ops#/ops/cockpit/dash');
|
|
// 活动记忆那一区 2026-07-29 整个撤了(运营 · 数据)—— 旧链接落运营首页,不给白屏
|
|
expect(legacyGovTarget('#/gov/memory/layers')).toBe('/ops#/ops/cockpit/dash');
|
|
});
|
|
|
|
/*
|
|
* 触发器与大模型**又独立成区**了(2026-07-29):触发器一度并进流程包页签、
|
|
* 模型一度住在系统区 —— 那两段旧链接要各回各家,不能停在中途那一站。
|
|
*/
|
|
it('搬回自己区的:触发器与大模型', () => {
|
|
expect(legacyGovTarget('#/gov/triggers/rules')).toBe('/design#/design/triggers/rules');
|
|
expect(legacyGovTarget('#/gov/workflows/rules')).toBe('/design#/design/triggers/rules');
|
|
expect(legacyGovTarget('#/gov/system/llm')).toBe('/design#/design/models/llm');
|
|
});
|
|
|
|
it('裸 #/gov 落运营首页;非 gov 哈希不管', () => {
|
|
expect(legacyGovTarget('#/gov')).toBe('/ops#/ops/cockpit/dash');
|
|
expect(legacyGovTarget('')).toBeUndefined();
|
|
expect(legacyGovTarget('#/whatever')).toBeUndefined();
|
|
});
|
|
});
|