You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7a813d3
Browse filesBrowse the repository at this point in the historyBrowse files
Merge plan/field-object-storage — relocate @storage into per-concern modules
The constants-colocation refactor (ADR-0003/0004) landed on main while
this branch was in flight, deleting constants.ts and core-attr-schemas.ts.
The merge relocates this branch's additions into the new per-concern
structure:
* FIELD_ATTR_STORAGE + STORAGE_FLATTENED/JSONB/SUBDOCUMENT +
STORAGE_VALUES + StorageValue type → core/field/field-constants.ts
(alongside the other FIELD_ATTR_* and AUTO_SET_* constants)
* @storage AttrSchema entry → core/field/field-schema.ts (alongside
the @objectref entry in commonFieldAttrs)
* validateFieldObjectStorage validator → unchanged location at
loader/validation-passes.ts; imports redirected to per-concern files
The barrel re-exports in metadata/src/index.ts preserve bare-name
imports, so migrate-ts code and tests need no changes — they import
FIELD_ATTR_STORAGE from "@metaobjectsdev/metadata" which resolves
through the new per-concern path transparently.
Plus a related .gitignore broadening: csharp build outputs (bin/, obj/,
*.dll, *.pdb, etc.) are now ignored under any **/csharp/** subtree,
cleaning up the stale root-level csharp/ directory left by the layout
migration.
Verification: 2168 pass / 0 fail (TS), 168 pass / 0 fail (C# conformance,
+6 for the four new @storage fixtures), 14/14 packages build + typecheck
exit 0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/superpowers/specs/2026-05-20-csharp-tool-and-metamodel-extensions-design.md
+13-12Lines changed: 13 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -75,8 +75,7 @@ These additions are Tier 1 cross-language metamodel changes — TS, Java (future
75
75
76
76
| Addition | Shape | Notes |
77
77
|---|---|---|
78
-
|**JSONB column subtype**|`field.subType = "jsonb"`| Postgres-native. Column maps to `jsonb`. C# codegen emits the property as `string` or a typed model + value converter (configurable via `@csJsonbType`). |
79
-
|**Schema namespacing**| A `package` segment maps to a DB schema (e.g., `acme::api` → `acme_api`). Default schema: `public`. | Necessary for projects with curated read-model schemas alongside the canonical OLTP schema. |
78
+
|**Schema namespacing**|`@schema` attr on `source[dbTable]` / `source[dbView]`. Default `public` for Postgres; SQLite rejects non-default values. |**Shipped** 2026-05-20 — see plan `2026-05-20-schema-namespacing.md`. |
80
79
|**Partial indexes**|`index.@filter "IsOpen = true"`| Postgres `CREATE INDEX ... WHERE ...`. Common in production schemas. |
81
80
|**Computed columns**|`field.@computed "(\"ParentId\" IS NULL)"`| Postgres `GENERATED ... STORED`. Codegen emits `HasComputedColumnSql(...)` on the Fluent side. |
82
81
@@ -85,7 +84,7 @@ These additions are Tier 1 cross-language metamodel changes — TS, Java (future
85
84
| Addition | Shape | Notes |
86
85
|---|---|---|
87
86
|**TPH discriminator inheritance**|`object.@discriminator "Type"` on the base; `object.@discriminatorValue "Bridge"` on each child object that `extends` it | Maps to EF `HasDiscriminator`. Discriminator column type: int / string / enum. Conformance must cover: nullable subtypes, FK pointing at base vs. subtype, EF skip-navigation onto subtypes. |
88
-
|**Owned types**| A field of subtype `ownedComplex` references a separate`object` declared with `object.@owned true`; columns from the owned object flatten into the owner's table with optional column-name remap | Maps to EF `OwnsOne`/ `OwnsMany`. Cross-language ports represent the same flattening; non-.NET languages may emit a nested struct or a flattened record. |
87
+
|**Structured nested values via `object.value` + `@storage` hint**| A field declared `field.object @objectRef "Address"` references an existing`object.value`. The `@storage` attr — `"flattened"`\|`"jsonb"`\|`"subdocument"` — tells codegen + introspect how the nested value lands in storage. `isArray true` supported with `"jsonb"` / `"subdocument"`. |**Unifies the original Tier-2 "JSONB subtype" and Tier-3 "Owned types".** One concept: the metadata declares the structured shape, the storage hint picks the strategy. `flattened` → multiple columns prefixed by field name (EF `OwnsOne`pattern). `jsonb` → single Postgres jsonb column holding the structured value (and an array of values when `isArray true`). `subdocument` → nested document for Mongo-shaped stores. Cross-language ports interpret the same metadata against their target dialect; the metamodel does not encode any dialect-specific behavior. |
89
88
|**External-SQL function references**|`function[externalSql]` declaration: name, parameters (typed), return type, and a path to a `.sql` file holding the body | For Postgres functions whose body is too large or imperative to author in metadata. The tool tracks the file's checksum; when it changes, the next `migrate emit` produces a `CREATE OR REPLACE FUNCTION` statement. |
90
89
|**External-SQL view references**|`view[externalSql]` declaration: name, optional column list, and a path to a `.sql` file holding the SELECT body | Same pattern for views that aren't projections (legacy hand-written views, complex CTEs that resist projection authoring). |
91
90
@@ -113,21 +112,22 @@ Both extensions are general-purpose and benefit every TypeScript consumer that d
113
112
114
113
Required new fixtures under `fixtures/conformance/`:
Each fixture pairs input metadata with the canonical serializer output. TS implementation establishes the canonical form; C# (and future Java, Python) implementations must match.
132
132
133
133
## Estimated effort
@@ -153,19 +153,20 @@ Each fixture pairs input metadata with the canonical serializer output. TS imple
153
153
## Risks
154
154
155
155
1.**EF model reflection at design time has historically been fiddly** — assembly loading, design-time DI, runtime-only configuration. Mitigation: the `ModelSnapshot.cs` parsing fallback. Validate which is robust in the first 2 weeks.
156
-
2.**Owned-type codegen has edge cases** the conformance fixtures might not catch on first pass (shadow FKs, nullable owned blocks, nested owned types). Mitigation: 2-3 week buffer in the estimate for first-real-project iteration.
156
+
2.**`field.object + @storage`codegen has edge cases** the conformance fixtures might not catch on first pass — column-name prefixing for `flattened` (`PRPAddress_Street` vs `Address_Street`?), nullable owned blocks, nested objects inside JSONB, arrays of jsonb-stored values. Mitigation: 2-3 week buffer in the estimate for first-real-project iteration; cover all four shapes (single+flattened, single+jsonb, array+jsonb, array+subdocument) with dedicated fixtures.
157
157
3.**TPH inheritance is the gnarliest codegen pattern.** Subtype-pointing FKs, EF skip-navigation, discriminator-as-enum vs. discriminator-as-int. Mitigation: cover 5+ TPH conformance fixtures before C# codegen ships.
158
158
4.**`view[externalSql]` checksum tracking format must be stable across language ports.** A naive whitespace-sensitive checksum is fragile. Mitigation: define a canonical normalization (strip trailing whitespace, normalize line endings, optionally strip SQL comments) — and conformance-test it.
159
159
5.**`migrate emit` SQL output divergence between TS and C# implementations.** The cross-language conformance corpus must enforce byte-equality of emitted DDL for the same metadata + dialect. Mitigation: a `fixtures/migrations/` corpus parallel to the loader corpus, validating both implementations against the same canonical script.
0 commit comments