Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/v11-a2-trivial-deadprops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@objectstack/spec": minor
---

Remove a first batch of dead (unenforced, unauthored) metadata properties (#2377, ADR-0049).

Verified set 0× / read 0× across framework + objectui + cloud + hotcrm + templates, with no test footprint outside `@objectstack/spec`:

- **field**: `caseSensitive`, `maxRating`
- **object**: `partitioning` (+ `PartitioningConfigSchema`), `defaultDetailForm`

Liveness ledgers (field/object) updated; api-surface regenerated (drops `PartitioningConfig`/`PartitioningConfigSchema` only). Folded into the 11 line (`minor`).

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.
2 changes: 0 additions & 2 deletions packages/spec/api-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,6 @@
"ObjectOwnershipEnum (const)",
"ObjectSchema (const)",
"OperatorKey (type)",
"PartitioningConfig (type)",
"PartitioningConfigSchema (const)",
"PoolConfig (type)",
"PoolConfigSchema (const)",
"QueryAST (type)",
Expand Down
10 changes: 0 additions & 10 deletions packages/spec/liveness/field.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,6 @@
"status": "live",
"note": "objectui LookupField — opt-in inline quick-create (dataSource.create from typed text) (reads allowCreate || allow_create)."
},
"maxRating": {
"status": "dead",
"evidence": "RatingField reads `max` (RatingField.tsx:13) — dead + redundant with max",
"authorWarn": true,
"authorHint": "The rating renderer reads `max`, not `maxRating` — set `max` instead; `maxRating` is ignored."
},
"columnName": {
"status": "dead",
"evidence": "resolveColumnName (spec system-names.ts:182) has ZERO call sites; SQL driver hardcodes column = field key",
Expand Down Expand Up @@ -246,10 +240,6 @@
"status": "dead",
"evidence": "no consumer"
},
"caseSensitive": {
"status": "dead",
"evidence": "no consumer"
},
"inlineTitle": {
"status": "live",
"evidence": "objectui: packages/app-shell/src/providers/MetadataProvider.tsx + plugin-form/deriveMasterDetail.ts",
Expand Down
12 changes: 0 additions & 12 deletions packages/spec/liveness/object.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,6 @@
"authorWarn": true,
"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)."
},
"partitioning": {
"status": "dead",
"evidence": "aspirational; no runtime",
"authorWarn": true,
"authorHint": "No table-partitioning is applied from this block. Remove it — it has no runtime effect."
},
"softDelete": {
"status": "dead",
"evidence": "no runtime; duplicates the (also dead) enable.trash",
Expand All @@ -219,12 +213,6 @@
"authorWarn": true,
"authorHint": "No search-engine config is consumed. Remove it — records remain queryable via the normal data API regardless."
},
"defaultDetailForm": {
"status": "dead",
"evidence": "documented fallback chain unimplemented",
"authorWarn": true,
"authorHint": "The detail form is chosen by the view layer; this field's documented fallback chain is unimplemented and ignored. Remove it."
},
"recordName": {
"status": "dead",
"evidence": "superseded by a field of type:'autonumber' + autonumberFormat (engine.ts:757)",
Expand Down
2 changes: 0 additions & 2 deletions packages/spec/src/data/field.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ export const FieldSchema = lazySchema(() => z.object({
// addressFormat, color colorFormat/allowAlpha/presetColors, slider showValue/marks,
// barcode/qr barcodeFormat/qrErrorCorrection/displayValue/allowScanning.
language: z.string().optional().describe('Programming language for syntax highlighting (e.g., javascript, python, sql)'),
maxRating: z.number().optional().describe('Maximum rating value (default: 5)'),
step: z.number().optional().describe('Step increment for slider (default: 1)'),

// Currency field config
Expand Down Expand Up @@ -582,7 +581,6 @@ export const FieldSchema = lazySchema(() => z.object({
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.'),
sortable: z.boolean().optional().default(true).describe('Whether field is sortable in list views'),
inlineHelpText: z.string().optional().describe('Help text displayed below the field in forms'),
caseSensitive: z.boolean().optional().describe('Whether text comparisons are case-sensitive'),
/**
* Auto-number display format. Literal text interleaved with `{...}` tokens:
*
Expand Down
29 changes: 0 additions & 29 deletions packages/spec/src/data/object.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,32 +197,6 @@ export const VersioningConfigSchema = lazySchema(() => z.object({
versionField: z.string().default('version').describe('Field name for version number/timestamp'),
}));

/**
* Partitioning Strategy Schema
* Configures table partitioning for performance at scale
*
* @example Range partitioning by date (monthly)
* {
* enabled: true,
* strategy: 'range',
* key: 'created_at',
* interval: '1 month'
* }
*/
export const PartitioningConfigSchema = lazySchema(() => z.object({
enabled: z.boolean().describe('Enable table partitioning'),
strategy: z.enum(['range', 'hash', 'list']).describe('Partitioning strategy: range (date ranges), hash (consistent hashing), list (predefined values)'),
key: z.string().describe('Field name to partition by'),
interval: z.string().optional().describe('Partition interval for range strategy (e.g., "1 month", "1 year")'),
}).refine((data) => {
// If strategy is 'range', interval must be provided
if (data.strategy === 'range' && !data.interval) {
return false;
}
return true;
}, {
message: 'interval is required when strategy is "range"',
}));

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

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

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

/**
* Search Engine Config
Expand Down Expand Up @@ -915,7 +887,6 @@ export type TenancyConfig = z.infer<typeof TenancyConfigSchema>;
export type ObjectAccessConfig = z.infer<typeof ObjectAccessConfigSchema>;
export type SoftDeleteConfig = z.infer<typeof SoftDeleteConfigSchema>;
export type VersioningConfig = z.infer<typeof VersioningConfigSchema>;
export type PartitioningConfig = z.infer<typeof PartitioningConfigSchema>;

/**
* Resolved CRUD affordance matrix for an object — what generic
Expand Down