Archived
三面拆分①:surface 配置与区表 —— 归属/亮灯/旧链改写皆纯函数先测后写
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 三面骨架的唯一事实源 —— 区归属、亮灯、旧链接改写。
|
||||
*
|
||||
* 这里守的是「配置自洽」:每个区恰属一面(不重不漏);亮灯只看该面功能;旧深链一条不死。
|
||||
* 三者都是纯函数,壳层只消费 —— 配置错了在这里就红,不必等到点开界面才发现。
|
||||
*/
|
||||
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', () => {
|
||||
expect(legacyGovTarget('#/gov/tasks/board')).toBe('/ops#/ops/tasks/board');
|
||||
});
|
||||
|
||||
it('已删的区落到对应新家', () => {
|
||||
expect(legacyGovTarget('#/gov/triggers/rules')).toBe('/design#/design/workflows/rules');
|
||||
expect(legacyGovTarget('#/gov/memory/metrics')).toBe('/ops#/ops/cockpit/dash');
|
||||
expect(legacyGovTarget('#/gov/memory/layers')).toBe('/ops#/ops/knowledge/layers');
|
||||
});
|
||||
|
||||
it('裸 #/gov 落运营首页;非 gov 哈希不管', () => {
|
||||
expect(legacyGovTarget('#/gov')).toBe('/ops#/ops/cockpit/dash');
|
||||
expect(legacyGovTarget('')).toBeUndefined();
|
||||
expect(legacyGovTarget('#/whatever')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user