Repository navigation
Add field types and the content type model - #2448
Merged
Merged
Conversation
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 #2445
What
The first slice of F-SCH (#2415): the schema model in Core, with no storage yet.
FluentCMS.Core.Schema):IFieldTypeis marked[ExtensionPoint]. It has a stable name and checks the settings a definition gives a field of its type, returning errors instead of throwing.FieldTypeRegistryresolves registered types by name and refuses to start with a duplicate or malformed name.FieldSettingsReaderis the public helper the built-ins use: every setting a type reads counts as known, and anything else in the object comes back assetting_unknownwith the list of settings the type does have.FluentCMS.Core.Builtin.FieldTypes): the SCH-02 typestext,richText(Markdown),number,boolean,dateTime,enum,media,reference(target type by slug),listandjson.AddFluentCmsCore()discovers them with the sameAddFluentCmsExtensionscall a plugin assembly uses.listchecks its item settings through the registry, so a list of a plugin type works like a list of a built-in. A list of lists is rejected, and the error points tojson.ContentTypeDefinitionholds an ordered list ofFieldDefinition(name, type, required, settings) and stores as{"fields":[{"name":"price","type":"number","required":true,"settings":{"min":0}}]}.Parsechecks only the shape and reports every problem with its JSON path; duplicate properties are rejected.Validatechecks names (lower camel case or snake case, unique ignoring case), known types and each field's settings, and every error names its field.ContentTypehas an id, site id (SCH-07), name, slug, version and current definition.Createreports every problem at once.Revisevalidates again and returns version n+1 with the same id, site, name and slug, leaving the current instance unchanged.Why
F-SCH is next on the critical path (#2432), and #2438 left field types to F-SCH as the first real extension point. The epic lists the aggregate and the field types as separate slices. This PR puts both in Core because the aggregate validates its definition through the field types. The next slice adds the application services, the stored type with its versions, the one site record, the checks that need stored data (slug unique per site, reference target exists), audit events, and migrations for both providers. Splitting there keeps this diff free of migrations.
Some choices worth a look:
JsonElementhas no value equality, so record equality would be misleading.Tests
Conformance base
FieldTypeConformanceTests(EXT-N1). Each type is registered once through the extension point under a valid name. It accepts the settings it documents and rejects invalid ones with a code and a message. It reports an unknown setting assetting_unknown. It never throws, whatever JSON value a setting holds. All ten built-ins pass it, and so doesRatingFieldType, a sample type in the test assembly outsideBuiltin.Unit: Core lists exactly the ten SCH-02 types, all as built-ins. Duplicate and malformed type names are rejected. A plugin type validates in a definition and inside a list, and is unknown without its assembly. A definition with one field of every type parses, validates, writes to JSON and reads back unchanged. The JSON shape is exact. Malformed JSON, the wrong root shape and every structural problem are reported with their path. Validation reports invalid and duplicate names, unknown types, bad settings, a list of lists and missing settings, each naming its field. The aggregate starts at version 1 scoped to its site and rejects an empty site, a blank or too long name, and invalid slugs. A revision makes the next version with the same identity, and an invalid one changes nothing. Field name and type name rules have their own tests.
ExtensionRegistrationTestshas two adjustments now that Core has built-ins and the test assembly has a field type. The "no built-ins yet" test becomes "Core registers its built-ins through the catalog". The discovery test asserts that every catalogued contract is an extension point, instead of asserting it isIGreeting.No new package and no new project reference. No model change, so no migration.
Checklist
v2