Skip to content

Commit b48772c

Browse files
committed
Add ADR for the forms schema refactor
This commit adds an ADR that explains why we have adopted the new forms structure in configurable documents schema and the benefit for us, especially with validating nested blocks. PR: #10972
1 parent eabb594 commit b48772c

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# 9. Separate configurable document forms and presenters from attribute schema
2+
3+
## Status
4+
5+
Accepted
6+
7+
## Context
8+
9+
The configurable document schema introduced in [ADR-0006](./0006-config-driven-content-types.md) and evolved in [ADR-0007](./0007-use-rails-validation-for-configurable-documents.md) and [ADR-0008](./0008-drop-json-schema-for-document-configuration.md) defined document properties under `schema.properties` and grouped UI fields via `settings.edit_screens`. This conflated three concerns:
10+
11+
- How publishers see and group fields in the UI (form layout and copy).
12+
- How field values are presented to downstream systems (e.g. Publishing API payload mapping and transformations).
13+
- How attributes and validations are defined and enforced.
14+
15+
This coupling made it hard to:
16+
17+
- Group related fields in the UI without affecting payload mapping.
18+
- Present the same attribute differently to publishers and Publishing API. E.g Duration block in topical events holding data for `start_date` and `end_date` but needed to be presented as individual fields to publishing API.
19+
- Flatten validations while still allowing nested form structures, leading to complex validation logic.
20+
21+
## Decision
22+
23+
We refactored the configurable document type schema to separate concerns:
24+
25+
1. Introduced a top-level `forms` hash describing UI forms and their fields (label, description, block type), replacing `settings.edit_screens`.
26+
2. Replaced `schema.properties` with `schema.attributes`. The current implementation focuses on simple types (string, integer, date), moving away from nested object properties. In future, we are open to introducing more complex attribute shapes like arrays.
27+
3. Introduced a top-level `presenters` hash to describe how attribute values are mapped or transformed for downstream consumers (e.g. Publishing API), helping to decouple UI layout from payload shape.
28+
4. Moved validation definitions to `schema.validations`, listing validators by attribute name. Nested validations within property definitions are no longer used in current schemas to simplify validation logic.
29+
5. Removed custom nested block content handling for `object` types. Object attributes now use Rails' default hash implementation.
30+
6. Updated the configurable document type JSON schema to validate the new structure and removed obsolete nested-schema code paths.
31+
32+
## Consequences
33+
34+
- All configurable document type definitions must use `schema.attributes`, `forms`, and `presenters`; `settings.edit_screens` and nested property validations are no longer supported.
35+
- UI layout changes (field grouping, titles, descriptions, block types) can now be made in `forms` without impacting Publishing API payloads, which are defined in `presenters`.
36+
- Validators will run against the flattened `schema.attributes` namespace. Added tests ensure nested data values stored in block content are preserved when present in the payload.
37+
- Future support for genuinely nested attribute schemas or arrays would need a new design rather than reintroducing `object` types.
38+
- It now becomes easier to present the same attribute differently in the UI and Publishing API (or any other consumer in future) by defining separate mappings in `forms` and `presenters`.
39+
40+
## Example
41+
42+
A configurable document type schema following the new structure will be identical to this:
43+
44+
```json
45+
{
46+
"key": "example_document_type",
47+
"title": "Example Document Type",
48+
"description": "An example document type with configurable forms and presenters",
49+
"forms": {
50+
"documents": {
51+
"fields": {
52+
"body": {
53+
"title": "Body",
54+
"description": "The main content area",
55+
"block": "govspeak"
56+
},
57+
"lead_paragraph": {
58+
"title": "Lead Paragraph",
59+
"description": "A short introduction",
60+
"block": "default_string"
61+
}
62+
}
63+
}
64+
},
65+
"schema": {
66+
"attributes": {
67+
"body": {
68+
"type": "string"
69+
},
70+
"lead_paragraph": {
71+
"type": "string"
72+
},
73+
},
74+
"validations": {
75+
"presence": {
76+
"attributes": ["body", "lead_paragraph"]
77+
},
78+
"length": {
79+
"attributes": ["lead_paragraph"],
80+
"maximum": 255
81+
}
82+
}
83+
},
84+
"presenters": {
85+
"publishing_api": {
86+
"body": "govspeak",
87+
"lead_paragraph": "string"
88+
}
89+
}
90+
}
91+
```

0 commit comments

Comments
 (0)