Skip to content

Commit 2f9c654

Browse files
os-zhuangclaude
andcommitted
feat(spec): remove first batch of dead metadata props (#2377, A2)
Cleanly-verifiable, unique-named dead props with zero footprint outside spec: - field: caseSensitive, maxRating - object: partitioning (+PartitioningConfigSchema), defaultDetailForm Liveness ledgers (field/object) updated; api-surface regenerated (drops PartitioningConfig type only). softDelete + measures.certified deferred (set in non-spec test fixtures); overloaded-name candidates deferred (see #2377). Verified: full spec suite green; check:api-surface ✓; liveness gate ✓; no non-spec usage of the four removed props. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8c84c97 commit 2f9c654

6 files changed

Lines changed: 14 additions & 55 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@objectstack/spec": minor
3+
---
4+
5+
Remove a first batch of dead (unenforced, unauthored) metadata properties (#2377, ADR-0049).
6+
7+
Verified set 0× / read 0× across framework + objectui + cloud + hotcrm + templates, with no test footprint outside `@objectstack/spec`:
8+
9+
- **field**: `caseSensitive`, `maxRating`
10+
- **object**: `partitioning` (+ `PartitioningConfigSchema`), `defaultDetailForm`
11+
12+
Liveness ledgers (field/object) updated; api-surface regenerated (drops `PartitioningConfig`/`PartitioningConfigSchema` only). Folded into the 11 line (`minor`).
13+
14+
The remaining #2377 candidates are deliberately not in this batch: overloaded names (`tags`/`active`/`versioning`/`dependencies`/`index`/…) need per-occurrence handling, and `softDelete` / `measures.certified` turned out to be set in non-spec test fixtures (analytics, mcp) — both deferred. See the issue for the full split.

packages/spec/api-surface.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,6 @@
347347
"ObjectOwnershipEnum (const)",
348348
"ObjectSchema (const)",
349349
"OperatorKey (type)",
350-
"PartitioningConfig (type)",
351-
"PartitioningConfigSchema (const)",
352350
"PoolConfig (type)",
353351
"PoolConfigSchema (const)",
354352
"QueryAST (type)",

packages/spec/liveness/field.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,6 @@
192192
"status": "live",
193193
"note": "objectui LookupField — opt-in inline quick-create (dataSource.create from typed text) (reads allowCreate || allow_create)."
194194
},
195-
"maxRating": {
196-
"status": "dead",
197-
"evidence": "RatingField reads `max` (RatingField.tsx:13) — dead + redundant with max",
198-
"authorWarn": true,
199-
"authorHint": "The rating renderer reads `max`, not `maxRating` — set `max` instead; `maxRating` is ignored."
200-
},
201195
"columnName": {
202196
"status": "dead",
203197
"evidence": "resolveColumnName (spec system-names.ts:182) has ZERO call sites; SQL driver hardcodes column = field key",
@@ -246,10 +240,6 @@
246240
"status": "dead",
247241
"evidence": "no consumer"
248242
},
249-
"caseSensitive": {
250-
"status": "dead",
251-
"evidence": "no consumer"
252-
},
253243
"inlineTitle": {
254244
"status": "live",
255245
"evidence": "objectui: packages/app-shell/src/providers/MetadataProvider.tsx + plugin-form/deriveMasterDetail.ts",

packages/spec/liveness/object.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,6 @@
201201
"authorWarn": true,
202202
"authorHint": "No record-versioning engine reads this block — setting it stores nothing and snapshots no history. Remove it (use Field.trackHistory for field-level history)."
203203
},
204-
"partitioning": {
205-
"status": "dead",
206-
"evidence": "aspirational; no runtime",
207-
"authorWarn": true,
208-
"authorHint": "No table-partitioning is applied from this block. Remove it — it has no runtime effect."
209-
},
210204
"softDelete": {
211205
"status": "dead",
212206
"evidence": "no runtime; duplicates the (also dead) enable.trash",
@@ -219,12 +213,6 @@
219213
"authorWarn": true,
220214
"authorHint": "No search-engine config is consumed. Remove it — records remain queryable via the normal data API regardless."
221215
},
222-
"defaultDetailForm": {
223-
"status": "dead",
224-
"evidence": "documented fallback chain unimplemented",
225-
"authorWarn": true,
226-
"authorHint": "The detail form is chosen by the view layer; this field's documented fallback chain is unimplemented and ignored. Remove it."
227-
},
228216
"recordName": {
229217
"status": "dead",
230218
"evidence": "superseded by a field of type:'autonumber' + autonumberFormat (engine.ts:757)",

packages/spec/src/data/field.zod.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,6 @@ export const FieldSchema = lazySchema(() => z.object({
509509
// addressFormat, color colorFormat/allowAlpha/presetColors, slider showValue/marks,
510510
// barcode/qr barcodeFormat/qrErrorCorrection/displayValue/allowScanning.
511511
language: z.string().optional().describe('Programming language for syntax highlighting (e.g., javascript, python, sql)'),
512-
maxRating: z.number().optional().describe('Maximum rating value (default: 5)'),
513512
step: z.number().optional().describe('Step increment for slider (default: 1)'),
514513

515514
// Currency field config
@@ -582,7 +581,6 @@ export const FieldSchema = lazySchema(() => z.object({
582581
system: z.boolean().optional().describe('Auto-injected system/audit field (e.g. created_at, updated_by, organization_id). Tools that surface system fields separately from author-declared business fields should branch on this flag.'),
583582
sortable: z.boolean().optional().default(true).describe('Whether field is sortable in list views'),
584583
inlineHelpText: z.string().optional().describe('Help text displayed below the field in forms'),
585-
caseSensitive: z.boolean().optional().describe('Whether text comparisons are case-sensitive'),
586584
/**
587585
* Auto-number display format. Literal text interleaved with `{...}` tokens:
588586
*

packages/spec/src/data/object.zod.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -197,32 +197,6 @@ export const VersioningConfigSchema = lazySchema(() => z.object({
197197
versionField: z.string().default('version').describe('Field name for version number/timestamp'),
198198
}));
199199

200-
/**
201-
* Partitioning Strategy Schema
202-
* Configures table partitioning for performance at scale
203-
*
204-
* @example Range partitioning by date (monthly)
205-
* {
206-
* enabled: true,
207-
* strategy: 'range',
208-
* key: 'created_at',
209-
* interval: '1 month'
210-
* }
211-
*/
212-
export const PartitioningConfigSchema = lazySchema(() => z.object({
213-
enabled: z.boolean().describe('Enable table partitioning'),
214-
strategy: z.enum(['range', 'hash', 'list']).describe('Partitioning strategy: range (date ranges), hash (consistent hashing), list (predefined values)'),
215-
key: z.string().describe('Field name to partition by'),
216-
interval: z.string().optional().describe('Partition interval for range strategy (e.g., "1 month", "1 year")'),
217-
}).refine((data) => {
218-
// If strategy is 'range', interval must be provided
219-
if (data.strategy === 'range' && !data.interval) {
220-
return false;
221-
}
222-
return true;
223-
}, {
224-
message: 'interval is required when strategy is "range"',
225-
}));
226200

227201
/**
228202
* Object Field Group Schema — MVP (data-layer protocol)
@@ -540,7 +514,6 @@ const ObjectSchemaBase = z.object({
540514
versioning: VersioningConfigSchema.optional().describe('Record versioning and history tracking configuration'),
541515

542516
// Partitioning strategy
543-
partitioning: PartitioningConfigSchema.optional().describe('Table partitioning configuration for performance'),
544517

545518
/**
546519
* Logic & Validation (Co-located)
@@ -620,7 +593,6 @@ const ObjectSchemaBase = z.object({
620593
* same metadata drives both the public collection form and the operator's
621594
* edit panel.
622595
*/
623-
defaultDetailForm: z.string().optional().describe('Name of the default FormView for record detail / edit screens'),
624596

625597
/**
626598
* Search Engine Config
@@ -915,7 +887,6 @@ export type TenancyConfig = z.infer<typeof TenancyConfigSchema>;
915887
export type ObjectAccessConfig = z.infer<typeof ObjectAccessConfigSchema>;
916888
export type SoftDeleteConfig = z.infer<typeof SoftDeleteConfigSchema>;
917889
export type VersioningConfig = z.infer<typeof VersioningConfigSchema>;
918-
export type PartitioningConfig = z.infer<typeof PartitioningConfigSchema>;
919890

920891
/**
921892
* Resolved CRUD affordance matrix for an object — what generic

0 commit comments

Comments
 (0)