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

@@ -101,3 +101,20 @@ func TestDocsDeclarations(t *testing.T) {
t.Fatal("BlogSettings has no posts_per_page rule")
}
}
// TestDocsSettingsLink activates the plugin with a settings entry that links
// to its posts controller, as the Settings page shows.
func TestDocsSettingsLink(t *testing.T) {
cfg, err := compass.Open(compass.Options{Dir: "config", Env: "development", Environ: []string{}})
if err != nil {
t.Fatal(err)
}
_ = cfg.Set("admin.jwt.secret", "test-only-secret-with-at-least-32-bytes")
if _, err := cabana.Activate(backpack.New(cfg), []party.Plugin{&LinkedBlogPlugin{}}); err != nil {
t.Fatal(err)
}
settings := (&LinkedBlogPlugin{}).Settings()
if len(settings) != 2 || settings[1].Controller != "acme.blog.posts" || settings[1].Model != "" {
t.Fatalf("Settings() = %+v", settings)
}
}