Files
summercms/cabana/registry.go
Jakub Zych dfa00f7e3a feat(09-01): implement separate-admin genre list tracer
- Audience-aware mint, verify, refresh, and backend guard keep frontend tokens compatible
- Cabana mounts raw admin login, list schema, and record list behind admin.jwt.secret
- Framework migration seeds Winter backend users and developer/publisher roles
2026-09-24 17:17:19 +02:00

60 lines
1.5 KiB
Go

package cabana
import (
"fmt"
"strings"
"git.golem15.com/golem15/summercms/pact"
"git.golem15.com/golem15/summercms/party"
)
type controllerRef struct {
plugin party.Plugin
ctl pact.AdminController
}
func collectControllers(plugins []party.Plugin) ([]controllerRef, error) {
var out []controllerRef
for _, p := range plugins {
src, ok := p.(pact.HasAdminControllers)
if !ok || p == nil {
continue
}
for _, ctl := range src.AdminControllers() {
if ctl == nil {
continue
}
id := ctl.ID()
if id != p.ID() && !strings.HasPrefix(id, p.ID()+".") {
return nil, fmt.Errorf("cabana: controller %s is not owned by plugin %s", id, p.ID())
}
out = append(out, controllerRef{plugin: p, ctl: ctl})
}
}
return out, nil
}
func compileRegistry(items []controllerRef) (*Registry, error) {
byID := make(map[string]*CompiledController, len(items))
for _, item := range items {
id := item.ctl.ID()
if _, exists := byID[id]; exists {
return nil, fmt.Errorf("cabana: duplicate admin controller %s", id)
}
assets, ok := item.plugin.(pact.AdminAssets)
if !ok || assets == nil || assets.AdminFS() == nil {
return nil, fmt.Errorf("cabana: plugin %s has admin controllers but no AdminFS", item.plugin.ID())
}
list, err := compileList(item.plugin.ID(), item.ctl, assets.AdminFS())
if err != nil {
return nil, err
}
byID[id] = &CompiledController{
PluginID: item.plugin.ID(),
Controller: item.ctl,
List: list,
}
}
return &Registry{byID: byID}, nil
}