Repository navigation
Add entity types and references to entity fields - #2465
Merged
Merged
Conversation
4 tasks done
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2461
What
The third slice of F-SCH (#2415): entity types (SCH-03) and references to an entity or one of its fields (SCH-04), on top of the stored content types from #2451. There is no migration.
"entity": true|false, written first and read back asContentTypeDefinition.IsEntity. A stored document without it (everything written by Store content types with their versions and the site record #2455) reads as a plain content type.FactMetadatasets the names every field of an entity type carries next to itsvalue:source(url,file,personorsystem),owner,validFrom,validUntilandlastVerified. A field cannot opt out, because the definition has no syntax for it and an unknown field property such as"fact": falseis already rejected.ContentType.Reviserejects a definition that drops the flag (entity_flag_removed). A content type may still become an entity type.referencetakes an optionalfield, as in{"target": "product", "field": "price"}.IFieldType.ReferencedTypesbecomesReferenceTargetsand returnsReferenceTarget(Type, Field?).listpasses on its item type's targets.ContentTypeDirectory):reference_field_unknown).reference_target_not_entity).field_referenced, naming the referencing type and field).Why
SCH-03 and SCH-04, and the F-SCH acceptance: every field on an entity type carries source, owner and validity, a definition that drops them is rejected, and
ProductPagecan referenceProduct.price.Choices worth a look:
The flag lives in the versioned definition, not a column. Flagging a type is a schema change like any other, and SCH-05 will version it as one. Nothing queries the flag yet. A column can come with the first query that needs it.
"A definition that drops them" is read as two rules.
If the maintainers want the flag to be reversible, for example through a reviewed change set once SCH-05 exists, only the check in
ContentType.Revisechanges.Field references only target entity types. SCH-04 names entity fields, and only facts are worth pointing at field by field. Plain content types are referenced as whole entries, as before.
FactMetadatais only names. Checking a fact's value, whether it is unsourced or stale, and its owner comes with F-ENT (F-ENT: Entity registry with sources, validity and blast radius #2417). Pinning the names here keeps the schema document (SCH-06) and entity values in agreement.Removing a referenced field is checked against every type's current definition in the site, and only when a revision removes fields. Tens of types per site keep that cheap (D26). Two concurrent schema writers could still slip past each other. Schema changes going through change sets (SCH-05) is where that gets serialised.
ReferencedTypesis renamed toReferenceTargetson the field type extension point. It landed in Store content types with their versions and the site record #2455 and nothing outside this repository implements it. There is no versioning policy for extension interfaces yet (EXT-N2).Tests
Unit:
"fact"property are rejected.FactMetadatapins its five properties and four source kinds.referenceacceptsfieldand rejects a field that is malformed, blank or not a string, or one given without a target. It declaresReferenceTarget("product", "price").listpasses a field target on. A definition reports field references.Integration, each on SQLite and PostgreSQL:
"entity": trueand reads back as one. A definition stored without the flag reads as a content type.product-pagereferencesproduct.pricedirectly and through a list.pricewhile two types reference it. Removing an unreferenced field works.product,category,specandregionas entity types and the four page types as content types, withproduct-pageandcomparison-pagereferencingproduct.price.All ran locally against a
postgres:17container as well as SQLite. There is no migration and no pending model change, no new package and no new project reference.Checklist
v2