Files
sm-seo-plugin/operations.go
Jakub Zych 9e802ec850 feat: page registry with its admin screen and signpost type
- golem15_seo_pages (migration 202610280002): the site's own frontend pages
  with an address and a name per locale, kind, origin, parent, content date
  and note; settings routes_reported_at
- SEO > Pages (golem15.seo.pages) after URL rules: list with kind, origin
  and missing filters and the missing row state, form with the P9 partial;
  the plugin's form extension saves the address and name per locale and
  refuses url_required, url_invalid, url_taken and url_owned
- menu item type seo-page with a content descriptor, so each page gets
  the SEO tab, resolves ok and is listed in the sitemaps grouped by kind
  (pages, offers, services, landing-pages, titled per locale)
- management API GET/POST /_seo/api/v1/pages, PUT/DELETE /pages/{id} and
  the MCP tools seo_list_pages, seo_create_page, seo_update_page,
  seo_delete_page (in this commit because the operations parity test maps
  every Pages operation to its tool)
2026-11-04 13:20:45 +01:00

117 lines
5.6 KiB
Go

package seo
import "git.golem15.com/golem15/sm-seo-plugin/controllers"
// The kinds of an admin operation (AdminOperation.Kind). Record, bulk and
// widget actions add ":" and the action's name, and a widget action with
// several ops "#" and the op.
const (
// OpList is a controller's list.
OpList = "list"
// OpShow is a record's form or preview, or a singleton's form.
OpShow = "show"
// OpCreate is the create form's save (toolbar create).
OpCreate = "create"
// OpUpdate is the update form's save, or a singleton's save.
OpUpdate = "update"
// OpDelete is the form's and the list toolbar's delete.
OpDelete = "delete"
// OpExtensionSave is a form extension's save on the controller.
OpExtensionSave = "extension_save"
// OpUpload is a field type's upload.
OpUpload = "upload"
// OpRecordAction is a record action ("record_action:<name>").
OpRecordAction = "record_action"
// OpBulkAction is a bulk action ("bulk_action:<name>").
OpBulkAction = "bulk_action"
// OpWidgetAction is a widget action ("widget_action:<name>").
OpWidgetAction = "widget_action"
)
// ContentController stands for the form of every content type the SEO tab
// is added to (D-91): the operations of the tab are the same on all.
const ContentController = "*"
// AdminOperation is one operation of the SEO admin and the MCP tool that
// performs it (D-10): the controller, the kind of operation and the tool
// name without the seo_ prefix.
type AdminOperation struct {
Controller string
Kind string
Tool string
}
// AdminOperations maps every operation of the SEO admin to its MCP tool
// (D-10, SC-4). TestEveryAdminOperationHasTool derives the operations from
// the controllers, their configs, actions and form extensions, and fails
// when one is missing here, when a tool named here does not exist, or when
// a tool is not bound to a registered route.
var AdminOperations = []AdminOperation{
// The SEO tab of every content type.
{ContentController, OpShow, "get_url_seo"},
{ContentController, OpExtensionSave, "set_url_seo"},
{ContentController, OpWidgetAction + ":seo_snippet", "get_url_seo"},
// The social image is set by URL through MCP (uploads are no tool).
{ContentController, OpUpload, "set_url_seo"},
// SEO settings and the per-type tabs.
{controllers.SettingsControllerID, OpShow, "show_settings"},
{controllers.SettingsControllerID, OpUpdate, "update_settings"},
{controllers.SettingsControllerID, OpExtensionSave, "update_settings"},
// Redirects.
{controllers.RedirectsControllerID, OpList, "list_redirects"},
{controllers.RedirectsControllerID, OpShow, "show_redirect"},
{controllers.RedirectsControllerID, OpCreate, "create_redirect"},
{controllers.RedirectsControllerID, OpUpdate, "update_redirect"},
{controllers.RedirectsControllerID, OpDelete, "delete_redirect"},
{controllers.RedirectsControllerID, OpExtensionSave, "update_redirect"},
// 404 log.
{controllers.NotFoundControllerID, OpList, "list_not_found"},
{controllers.NotFoundControllerID, OpShow, "list_not_found"},
{controllers.NotFoundControllerID, OpDelete, "delete_not_found"},
{controllers.NotFoundControllerID, OpRecordAction + ":" + controllers.NotFoundActionRedirect, "redirect_not_found"},
{controllers.NotFoundControllerID, OpRecordAction + ":" + controllers.NotFoundActionGone, "gone_not_found"},
{controllers.NotFoundControllerID, OpBulkAction + ":" + controllers.NotFoundActionGone, "gone_not_found"},
// URL rules.
{controllers.RulesControllerID, OpList, "list_rules"},
{controllers.RulesControllerID, OpShow, "show_rule"},
{controllers.RulesControllerID, OpCreate, "create_rule"},
{controllers.RulesControllerID, OpUpdate, "update_rule"},
{controllers.RulesControllerID, OpDelete, "delete_rule"},
{controllers.RulesControllerID, OpExtensionSave, "update_rule"},
{controllers.RulesControllerID, OpWidgetAction + ":seo_snippet", "get_url_seo"},
// Pages, the page registry; its own address-and-name extension saves
// with the form.
{controllers.PagesControllerID, OpList, "list_pages"},
{controllers.PagesControllerID, OpShow, "list_pages"},
{controllers.PagesControllerID, OpCreate, "create_page"},
{controllers.PagesControllerID, OpUpdate, "update_page"},
{controllers.PagesControllerID, OpDelete, "delete_page"},
{controllers.PagesControllerID, OpExtensionSave, "update_page"},
// robots.txt and AI bots.
{controllers.RobotsControllerID, OpShow, "show_robots"},
{controllers.RobotsControllerID, OpUpdate, "update_robots"},
{controllers.RobotsControllerID, OpExtensionSave, "update_robots"},
{controllers.RobotsControllerID, OpWidgetAction + ":" + RobotsTestAction, "test_robots"},
// History.
{controllers.HistoryControllerID, OpList, "list_history"},
{controllers.HistoryControllerID, OpShow, "show_history"},
{controllers.HistoryControllerID, OpRecordAction + ":" + controllers.HistoryActionUndo, "undo_change"},
{controllers.HistoryControllerID, OpRecordAction + ":" + controllers.HistoryActionUndoBatch, "undo_batch"},
// Import and export: the delimiter is a settings column; the files
// widget's ops export, preview and apply.
{controllers.TransferControllerID, OpShow, "show_settings"},
{controllers.TransferControllerID, OpUpdate, "update_settings"},
{controllers.TransferControllerID, OpWidgetAction + ":" + controllers.TransferAction, "import_csv"},
{controllers.TransferControllerID, OpWidgetAction + ":" + controllers.TransferAction + "#export", "export_csv"},
{controllers.TransferControllerID, OpWidgetAction + ":" + controllers.TransferAction + "#preview", "import_csv"},
{controllers.TransferControllerID, OpWidgetAction + ":" + controllers.TransferAction + "#apply", "import_csv"},
}