package plugin import ( "context" "encoding/json" "github.com/google/uuid" ) // Provisioner allows plugins to ensure required resources exist on startup. // All methods are idempotent — they check first and only create if missing. type Provisioner interface { EnsureDataTable(config DataTableConfig) error MergeSiteSettings(defaults map[string]any) error EnsureSetting(key string, defaultValue any) error EnsurePage(config PageConfig) error OverrideSiteSettings(overrides map[string]any) error EnsureMenuItem(menuName string, config MenuItemConfig) error RegisterEmbeddingConfig(config EmbeddingConfigDef) error EnsureEmbed(config EmbedConfig) error EnsureJobSchedule(config JobScheduleConfig) error UpdateDataTableRowField(ctx context.Context, rowID uuid.UUID, fieldKey string, value any) error DisableOrphanedJobSchedules(registeredTypes []string) error EnsurePlugin(name string) error EnsureCustomColor(config CustomColorConfig) error // EnsureMedia deposits an image under the plugin-chosen MediaDeposit.ID if a // row with that ID does not already exist. Idempotent: an existing ID is a // no-op; if the bytes differ from what was first deposited it logs a warning // rather than overwriting (seeded media is immutable once placed). EnsureMedia(deposit MediaDeposit) error } // DataTableConfig defines a data table to provision. type DataTableConfig struct { Key string Name string Description string Schema json.RawMessage PrimaryKey string } // PageConfig defines a page to provision. type PageConfig struct { // Key is the stable, plugin-scoped identity used to find the page across // slug and hierarchy changes. Key string Slug string // ParentKey identifies a parent provisioned by the same plugin. ParentKey string // ParentSlug is the legacy slug-based parent reference. New declarations // should use ParentKey so moving or renaming the parent does not break the // relationship. ParentSlug string // MountPath is applied when the page is first created. Reconciliation does // not move an existing page when this value later changes. MountPath string Title string TemplateKey string Blocks []PageBlockConfig DetailSourceType string DetailSourceKey string DetailSlugField string ReconcileBlocks bool ReconcileTemplate bool // MergeMissingBlockContent shallowly adds absent top-level default keys to // matching plugin-owned block assignments. Present values, including empty // strings, zero, false, and null, are preserved. MergeMissingBlockContent bool } // PageBlockConfig defines a block within a provisioned page. type PageBlockConfig struct { BlockKey string Title string Content map[string]any HtmlContent *string Slot string SortOrder int32 } // EmbeddingConfigDef defines embedding text generation for a data table. type EmbeddingConfigDef struct { TableKey string TextTemplate string Enabled bool } // MenuItemConfig defines a menu item to provision. type MenuItemConfig struct { Label string URL string PageSlug string // PagePlugin and PageKey identify a provisioned page independently of its // current slug. PagePlugin permits a menu declared by one plugin to target // a page owned by another. PagePlugin string PageKey string SortOrder int32 } // EmbedConfig defines an embeddable component template. type EmbedConfig struct { Key string Title string Description string Icon string LabelField string Template string RenderFunc func(ctx context.Context, content map[string]any) string DataSource EmbedDataSource } // EmbedDataSource specifies where embed data comes from. type EmbedDataSource struct { Type string TableKey string } // JobScheduleConfig defines a cron schedule for a background job. type JobScheduleConfig struct { JobType string CronExpression string Config json.RawMessage } // CustomColorConfig defines a custom theme color variable. type CustomColorConfig struct { Name string LightValue string DarkValue string Source string }