docs(todos): capture plugin-registered cabana field types

This commit is contained in:
2026-10-09 18:45:14 +02:00
parent 6ea3652303
commit 65d577b828

View File

@@ -0,0 +1,32 @@
---
created: 2026-10-09T16:45:00Z
title: Let plugins register their own value-bearing cabana field types (Winter registerFormWidgets successor)
area: framework
severity: major
files:
- modules/cabana/form_schema.go
- modules/cabana/crud.go
- modules/cabana/extension.go
- modules/pact
- admin/src/components/form/registry.ts
---
## Problem
WinterCMS plugins ship their own form widgets through `registerFormWidgets()` and use them as `type: <widget>` fields that own a column value. cabana has no equivalent:
- The field-type set is closed. `modules/cabana/form_schema.go` (the known-types map, around lines 25-29), `modules/cabana/crud.go` (the scalar type switch, around line 1226) and the SPA renderer registry `admin/src/components/form/registry.ts` list every type, and an unknown type fails boot.
- The Phase 10.1 `type: widget` extension (`modules/cabana/extension.go`) mounts a plugin custom element, but the field is valueless: it runs a controller action and writes back declared scalar sibling fields through `fill:`. It cannot own a value, define its JSON shape, validate and decode it on save, or render it in lists.
Plugins about to be ported deliver their own fields that cannot become cabana core types (raised during the Phase 18 discussion, 2026-10-09). Without this, each one forces a framework release or a workaround through widget actions.
## Solution
Add a capability interface in `pact` (for example `HasFormFieldTypes`) through which a plugin registers a namespaced field type (`{vendor}-{plugin}-*` or `vendor.plugin::type`):
- Server side: a Go type that validates the field's YAML options at boot (fail-loud, like the built-ins), decodes and validates the submitted value (any JSON shape), maps it to the column, and optionally formats it for list columns.
- Client side: a custom element served through the existing `pact.AdminClientAssets` mechanism. It binds a value through a documented contract (a `value` property plus a `summer-change` event) instead of the action/fill round-trip, and reads the public `--c-*` CSS variables only.
- The form schema and the generated TS types carry plugin types as a generic `plugin-field` shape so the SPA build does not need to know them.
- Update the cabana README and `docs/`, the admin OpenAPI and the generated types, and commit `dist/`, all in the same change.
Decide in a framework phase (or a decimal phase before the first plugin that needs it). Phase 18's `money` field stays a core cabana type (18-CONTEXT); this todo covers the plugins that follow.