feat(cabana): settings entries that link to an admin controller

pact.SettingsItem gains an additive Controller field, the equivalent of a
WinterCMS registerSettings 'url' => Backend::url(...) entry. A link entry
declares no Model, Form or NewModel and needs no AdminFS; start-up fails
when it combines Controller with a singleton form or a model, or names an
unregistered controller. Settings codes stay one namespace.

GET /settings lists a link entry with its controller only when the
principal passes the item's permissions and may open the controller.
Registry.Setting never returns a link entry, so the singleton settings
endpoints answer 404 for its code. SettingsEntry carries controller,
empty for singletons; the OpenAPI document, generated SPA types and
settings fixture follow, and the pact and cabana READMEs and the
settings docs describe the link.
This commit is contained in:
Jakub Zych
2026-10-07 18:22:01 +02:00
parent b040ee3a74
commit 4a9b0896b1
15 changed files with 338 additions and 14 deletions

View File

@@ -196,6 +196,16 @@ func compileContributions(reg *Registry, plugins []party.Plugin) error {
if _, exists := reg.settings[item.Code]; exists {
return fmt.Errorf("cabana: duplicate setting %s", item.Code)
}
if item.Controller != "" {
// A link entry opens an admin controller and needs no
// singleton form, so no AdminFS either.
compiled, err := compileSettingLink(plugin.ID(), item)
if err != nil {
return err
}
reg.settings[item.Code] = compiled
continue
}
if !hasAssets || assets == nil || assets.AdminFS() == nil {
return fmt.Errorf("cabana: plugin %s has settings but no AdminFS", plugin.ID())
}
@@ -250,6 +260,11 @@ func compileContributions(reg *Registry, plugins []party.Plugin) error {
if err := reg.validatePermissions("setting "+code, setting.Item.Permissions); err != nil {
return err
}
if controller := setting.Item.Controller; controller != "" {
if _, ok := reg.byID[controller]; !ok {
return fmt.Errorf("cabana: setting %s references unknown controller %s", code, controller)
}
}
}
return nil
}