Skip to content

Commit 056faa8

Browse files
os-zhuangclaude
andauthored
fix(types,detail): derive five spec-named symbols instead of forking them (objectstack#4115) (#3057)
Burns the first five names off the spec-symbol DEBT ledger (149 -> 144). None of these were "one spec release away from drifting" — all five had already drifted, and two were live defects: - PageVariableSchema (zod/layout.zod.ts) omitted `source`, the entire ADR-0049 write-binding, so a spec-authored master/detail page parsed into a variable nothing could ever write; its `type` enum was also missing `record_id`, rejecting spec-valid record-picker variables. The sibling PageTypeSchema three lines below was already a spec re-export, with a comment describing this exact failure — one mirror was fixed and its neighbour left broken. - FeedItemType carried 7 of the spec's 13 members. The six missing kinds (file, sharing, note, record_create, record_delete, approval) had no icon and no colour in RecordActivityTimeline, so a server emitting any of them produced an unrenderable feed item. Both maps are `Record<FeedItemType, …>`, so widening the union surfaced the gap as a compile error; the six entries are filled in here. - PermissionAction was 8 of 11, missing `execute`/`manage`/`configure`. - ObjectIndex lacked `fulltext`, `unique: 'global'` and `partial`. - PageVariable (TS) was member-for-member identical to spec's — a second place to drift from and nothing else. Note its own Zod counterpart had drifted while it had not. The ledger is regenerated with `--ledger`, not hand-edited; the diff is exactly these five names, so no other package's debt was dropped. Mutation-tested both directions: re-forking a burned-down name fails the guard by name, and leaving a burned name in the ledger fails it as stale. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 4c2a465 commit 056faa8

7 files changed

Lines changed: 70 additions & 48 deletions

File tree

packages/plugin-detail/src/RecordActivityTimeline.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import {
2222
Phone,
2323
ChevronDown,
2424
Loader2,
25+
StickyNote,
26+
FileText,
27+
Share2,
28+
BadgeCheck,
2529
} from 'lucide-react';
2630
import type { FeedItem, FeedItemType, RecordActivityComponentProps, RecordSubscription } from '@object-ui/types';
2731
import { FieldChangeItem } from './FieldChangeItem';
@@ -73,6 +77,10 @@ export interface RecordActivityTimelineProps {
7377
className?: string;
7478
}
7579

80+
// Total over `FeedItemType`, so a feed kind the spec adds cannot reach the
81+
// timeline without an icon and a colour (objectstack#4115): the six entries
82+
// below `call` were missing for as long as the local union was a 7-member
83+
// hand copy of the spec's 13.
7684
const FEED_TYPE_ICONS: Record<FeedItemType, React.ElementType> = {
7785
comment: MessageSquare,
7886
field_change: Edit,
@@ -81,6 +89,12 @@ const FEED_TYPE_ICONS: Record<FeedItemType, React.ElementType> = {
8189
system: Zap,
8290
email: Mail,
8391
call: Phone,
92+
note: StickyNote,
93+
file: FileText,
94+
sharing: Share2,
95+
record_create: PlusCircle,
96+
record_delete: Trash2,
97+
approval: BadgeCheck,
8498
};
8599

86100
const FEED_TYPE_COLORS: Record<FeedItemType, string> = {
@@ -91,6 +105,12 @@ const FEED_TYPE_COLORS: Record<FeedItemType, string> = {
91105
system: 'bg-gray-100 text-gray-600',
92106
email: 'bg-indigo-100 text-indigo-600',
93107
call: 'bg-teal-100 text-teal-600',
108+
note: 'bg-yellow-100 text-yellow-700',
109+
file: 'bg-slate-100 text-slate-600',
110+
sharing: 'bg-sky-100 text-sky-600',
111+
record_create: 'bg-emerald-100 text-emerald-600',
112+
record_delete: 'bg-red-100 text-red-600',
113+
approval: 'bg-violet-100 text-violet-600',
94114
};
95115

96116
function getFilterOptions(t: (key: string) => string): { value: FeedFilterMode; label: string }[] {

packages/types/src/field-types.ts

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -987,26 +987,17 @@ export interface ObjectSchemaMetadata {
987987
}
988988

989989
/**
990-
* Object index configuration
990+
* Object index configuration — re-exported from `@objectstack/spec/data`
991+
* rather than restated (objectstack#4115).
992+
*
993+
* The hand-written interface it replaces had drifted three ways: its `type`
994+
* enum was missing `fulltext`, `unique` was a bare `boolean` where the spec
995+
* also accepts `'global'` (the global-unique scope), and it had no `partial`
996+
* member at all — so a spec-authored partial or globally-unique index could
997+
* not be expressed here.
991998
*/
992-
export interface ObjectIndex {
993-
/**
994-
* Index name
995-
*/
996-
name: string;
997-
/**
998-
* Fields to index
999-
*/
1000-
fields: string[];
1001-
/**
1002-
* Whether index is unique
1003-
*/
1004-
unique?: boolean;
1005-
/**
1006-
* Index type
1007-
*/
1008-
type?: 'btree' | 'hash' | 'gist' | 'gin';
1009-
}
999+
import type { ObjectIndex } from '@objectstack/spec/data';
1000+
export type { ObjectIndex };
10101001

10111002
/**
10121003
* Object relationship configuration

packages/types/src/layout.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -460,20 +460,14 @@ export type PageVisualizationAlias =
460460
export type PageType = SpecPageType | PageVisualizationAlias;
461461

462462
/**
463-
* Page Variable
464-
* Local page state that can be read/written by components and expressions.
465-
* Aligned with @objectstack/spec PageVariableSchema
463+
* Page Variable — local page state that components and expressions read and
464+
* write. Re-exported from `@objectstack/spec/ui` rather than restated
465+
* (objectstack#4115); the hand-written interface it replaces was
466+
* member-for-member identical, so the only thing it added was a second place
467+
* to drift from.
466468
*/
467-
export interface PageVariable {
468-
/** Variable name */
469-
name: string;
470-
/** Variable type @default 'string' */
471-
type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'record_id';
472-
/** Default value for initialization */
473-
defaultValue?: any;
474-
/** Variable data source (e.g. URL param, context, expression) */
475-
source?: string;
476-
}
469+
import type { PageVariable } from '@objectstack/spec/ui';
470+
export type { PageVariable };
477471

478472
/**
479473
* Page Region Size

packages/types/src/permissions.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@
2020
// Role-Based Access Control (RBAC)
2121
// ============================================================================
2222

23-
/** Standard CRUD permission actions */
24-
export type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'export' | 'import' | 'share' | 'admin';
23+
/**
24+
* Standard permission actions — re-exported from `@objectstack/spec/kernel`
25+
* rather than restated (objectstack#4115).
26+
*
27+
* The hand-written union this replaces carried 8 of the spec's 11 members: it
28+
* was missing `execute` (running a flow or action), `manage` and `configure`,
29+
* so a spec-valid grant of any of the three was a type error here.
30+
*/
31+
import type { PermissionAction } from '@objectstack/spec/kernel';
32+
export type { PermissionAction };
2533

2634
/** Permission effect */
2735
export type PermissionEffect = 'allow' | 'deny';

packages/types/src/views.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,16 @@ export interface ActivityEntry {
321321

322322
/**
323323
* Feed item type — determines rendering style in the activity timeline.
324-
* Aligned with @objectstack/spec FeedItemSchema.type enum.
324+
* Re-exported from `@objectstack/spec/data` rather than restated
325+
* (objectstack#4115).
326+
*
327+
* The hand-written union this replaces carried 7 of the spec's 13 members —
328+
* `file`, `sharing`, `note`, `record_create`, `record_delete` and `approval`
329+
* were all missing, so a server emitting any of them produced a feed item the
330+
* timeline could not type, let alone render.
325331
*/
326-
export type FeedItemType = 'comment' | 'field_change' | 'task' | 'event' | 'system' | 'email' | 'call';
332+
import type { FeedItemType } from '@objectstack/spec/data';
333+
export type { FeedItemType };
327334

328335
/**
329336
* FeedItem — A single item in the unified activity feed.

packages/types/src/zod/layout.zod.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
*/
1818

1919
import { z } from 'zod';
20-
import { PageTypeSchema as SpecPageTypeSchema } from '@objectstack/spec/ui';
20+
import {
21+
PageTypeSchema as SpecPageTypeSchema,
22+
PageVariableSchema as SpecPageVariableSchema,
23+
} from '@objectstack/spec/ui';
2124
import { BaseSchema, SchemaNodeSchema } from './base.zod.js';
2225

2326
/**
@@ -245,13 +248,17 @@ export const PageRegionSchema = z.object({
245248
});
246249

247250
/**
248-
* Page Variable Schema
251+
* Page Variable Schema — `@objectstack/spec/ui` schema re-exported **by
252+
* reference** (objectstack#4115), for exactly the reason the sibling
253+
* {@link PageTypeSchema} below documents.
254+
*
255+
* The mirror this replaces had drifted twice over: it omitted `source` — the
256+
* whole ADR-0049 write-binding, so a spec-authored master/detail page
257+
* (`{ name: 'selectedProjectId', source: 'project_picker' }`) parsed into a
258+
* variable nothing could ever write — and its `type` enum was missing
259+
* `record_id`, so a spec-valid record-picker variable was rejected outright.
249260
*/
250-
export const PageVariableSchema = z.object({
251-
name: z.string().describe('Variable name'),
252-
type: z.enum(['string', 'number', 'boolean', 'object', 'array']).optional().default('string').describe('Variable type'),
253-
defaultValue: z.any().optional().describe('Default value'),
254-
});
261+
export const PageVariableSchema = SpecPageVariableSchema;
255262

256263
/**
257264
* Page Type Schema — `@objectstack/spec/ui` schema re-exported **by reference**

scripts/check-spec-symbol-derivation.mjs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ const DEBT = {
148148
"DriverInterface",
149149
"EventHandler",
150150
"ExpressionSchema",
151-
"FeedItemType",
152151
"FileMetadata",
153152
"FilterCondition",
154153
"FilterConditionSchema",
@@ -169,15 +168,11 @@ const DEBT = {
169168
"NavigationAreaSchema",
170169
"NavigationItem",
171170
"NavigationItemSchema",
172-
"ObjectIndex",
173171
"ObjectPermission",
174172
"OfflineConfig",
175173
"PageRegion",
176174
"PageRegionSchema",
177175
"PageSchema",
178-
"PageVariable",
179-
"PageVariableSchema",
180-
"PermissionAction",
181176
"QueryAST",
182177
"QuerySchema",
183178
"ReportSchedule",

0 commit comments

Comments
 (0)