diff --git a/docs/release-notes.md b/docs/release-notes.md index 8546329..25c333f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -43,3 +43,4 @@ Each body lives in `docs/releases/.md`. Publish with `tea releases create - | `v3.4.0-beta` | Custom content types | | `v3.4.1-beta` | Media field and security updates | | `v3.4.2-beta` | Security and privacy hardening | +| `v3.5.0-beta` | Relation field | diff --git a/docs/releases/v3.5.0-beta.md b/docs/releases/v3.5.0-beta.md new file mode 100644 index 0000000..5c6429a --- /dev/null +++ b/docs/releases/v3.5.0-beta.md @@ -0,0 +1,40 @@ +This release adds a Relation field to custom content types, so an entry can point at entries of another type. + +## New + +**Relation field** +- A content type can now have a Relation field that links to another content type. Three kinds are available: one to one (a target can be used by only one entry), one to many (one target per entry) and many to many (up to 50 targets per entry). +- Entries are linked through a searchable picker in the entry form. Chosen targets appear as chips labelled with the first field of the target entry, or "Entry N" when that field is empty. +- Entry lists and cards show the linked entries of each relation column. +- When a linked entry is deleted afterwards, the relation is shown as missing instead of breaking the page. A required relation with a missing target must be fixed before the entry can be saved. +- The schema builder previews the inverse side of a relation, and the schema review dialog explains the impact of adding or removing one. + +## Improvements and fixes + +- Deleting a content type that another type points at is refused, and the delete dialog tells you which types depend on it. +- Adding a required relation to a type that already has entries is refused with the usual schema incompatibility message. +- The right side panel of the article editor no longer overflows vertically on short screens. +- The web app is split into smaller chunks, so the first page load transfers less code. + +## API + +- Changed: every entry answer (`POST`, `PUT` and `GET` of one entry, and each item of a list) carries a top-level `relations` object keyed by relation field key. Each value holds `id`, `content_type` and `first_field` for an existing target, or `id` and `missing: true` for a deleted one. Many to many fields return an array. +- `GET /v1/content-type/{key}/entry` accepts `q`, a text search over the entries of the type, applied before pagination. `total` reflects the filtered count. +- `POST /v1/content-type` and `PUT /v1/content-type/{key}` accept `type: "relation"` fields with `relation: {"content_type", "kind"}`. A bad definition answers `422` `invalid_field`. +- Entry writes answer `422` `invalid_entry: : required` or `invalid_entry: : type`, and `409` `invalid_entry: : unique` for a one to one target already taken. +- `DELETE /v1/content-type/{key}` answers `409` `content_type_referenced` while another type has a relation to it. + +## Under the hood + +- New feature specs and tests cover the backend and the web app, in `features/relation_field_type.feature` and `features/relation_field_spa.feature`. +- Vendor chunk splitting is configured in `web/vite/vendorChunks.ts` and covered by a spec. + +## Upgrading + +- Replace the binary, or pull the new image. Back up the database first as usual. +- No schema migration and no new environment variable. Existing content types and entries are unchanged. + +## Known limitations + +- Relation search filters entries in memory, so it is meant for types with a moderate number of entries. +- The inverse side of a relation is only shown in the builder preview. The target type's form, list and API do not list the entries pointing at it.