Skip to content

Commit 8636492

Browse files
os-zhuangclaude
andcommitted
feat(spec): mark the deprecated role approver type with xEnumDeprecated (#3133)
Dogfooding the Studio flow designer surfaced the gap the rename alone left: the approver-type dropdown derives straight from this enum, so adding `org_membership_level` beside `role` put the NEW name in the list without removing the trap — `role` was still one click away from `position`. `.meta({ xEnumDeprecated })` on the approver type (sourced from DEPRECATED_APPROVER_TYPES, the single map) rides into the published node configSchema. Renderers omit listed members from pickers while still rendering a stored value, so a 15.x flow keeps loading. Locked by a test asserting the published schema carries it (the objectui side reads exactly this key). No new export (api-surface unchanged); generated references stay in sync. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0abc1b3 commit 8636492

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

packages/spec/src/automation/approval.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ApprovalNodeApproverSchema,
1010
ApprovalEscalationSchema,
1111
ApprovalNodeConfigSchema,
12+
getApprovalNodeConfigJsonSchema,
1213
} from './approval.zod';
1314

1415
describe('ApproverType', () => {
@@ -40,6 +41,20 @@ describe('ApproverType', () => {
4041
expect(() => ApproverType.parse(target)).not.toThrow();
4142
}
4243
});
44+
45+
// Cross-repo contract: the published node configSchema must carry
46+
// `xEnumDeprecated` on the approver type, or the Studio designer (objectui)
47+
// derives its dropdown straight from `enum` and keeps offering `role` — the
48+
// exact trap ADR-0090 D3 retires. Renderers read this to omit deprecated
49+
// members from pickers while still rendering a stored value.
50+
it('publishes xEnumDeprecated on the approver type so pickers can drop `role`', () => {
51+
const schema = getApprovalNodeConfigJsonSchema() as any;
52+
const typeNode = schema?.properties?.approvers?.items?.properties?.type;
53+
expect(typeNode?.enum).toContain('role'); // still parses (back-compat)
54+
expect(typeNode?.enum).toContain('org_membership_level');
55+
expect(typeNode?.xEnumDeprecated).toEqual(Object.keys(DEPRECATED_APPROVER_TYPES));
56+
expect(typeNode?.xEnumDeprecated).toContain('role');
57+
});
4358
});
4459

4560
describe('Approval node constants (ADR-0019)', () => {

packages/spec/src/automation/approval.zod.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,14 @@ export const APPROVAL_BRANCH_LABELS = {
9999

100100
/** A single approver assignment on an Approval node. */
101101
export const ApprovalNodeApproverSchema = lazySchema(() => z.object({
102-
type: ApproverType,
102+
// `xEnumDeprecated` lists enum members that still PARSE but must not be
103+
// offered for new authoring. Without it the Studio designer derives its
104+
// approver-type dropdown straight from this enum and keeps offering `role`
105+
// — the exact trap ADR-0090 D3 is retiring — one click away from `position`.
106+
// Renderers omit these from pickers while still rendering a stored value.
107+
type: ApproverType.meta({
108+
xEnumDeprecated: Object.keys(DEPRECATED_APPROVER_TYPES),
109+
}),
103110
/**
104111
* The approver reference, interpreted per `type`: a user id (`user`), a
105112
* membership tier — owner/admin/member (`org_membership_level`), a position

0 commit comments

Comments
 (0)