- 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)
94 lines
3.0 KiB
Go
94 lines
3.0 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// The writers of a history entry (D-13).
|
|
const (
|
|
ViaAdmin = "admin"
|
|
ViaMCP = "mcp"
|
|
ViaImport = "import"
|
|
ViaAuto = "auto"
|
|
ViaUndo = "undo"
|
|
)
|
|
|
|
// The subjects of a history entry.
|
|
const (
|
|
SubjectEntry = "entry"
|
|
SubjectRule = "rule"
|
|
SubjectRedirect = "redirect"
|
|
SubjectRobots = "robots"
|
|
SubjectSettings = "settings"
|
|
SubjectNotFound = "notfound"
|
|
// SubjectPage is a page of the page registry (D-33).
|
|
SubjectPage = "page"
|
|
)
|
|
|
|
// Revision is one recorded SEO change on golem15_seo_revisions (D-13): who
|
|
// made it (AuthorID and AuthorLabel, the label kept when the administrator
|
|
// is gone), through what (Via), on which object (SubjectKind and
|
|
// SubjectID: an entry as "<model type>|<record id>|<locale>", a rule by
|
|
// id, settings as "1" or "type:<key>"), a readable description (What) and
|
|
// the changed fields only, before and after. A created object has no
|
|
// Before and a deleted one no After. BatchID groups the changes of one
|
|
// batch; UndoneAt marks an undone change.
|
|
type Revision struct {
|
|
ID uint `gorm:"column:id;primaryKey"`
|
|
BatchID *string `gorm:"column:batch_id"`
|
|
AuthorID *uint `gorm:"column:author_id"`
|
|
AuthorLabel string `gorm:"column:author_label"`
|
|
Via string `gorm:"column:via"`
|
|
SubjectKind string `gorm:"column:subject_kind"`
|
|
SubjectID string `gorm:"column:subject_id"`
|
|
What string `gorm:"column:what"`
|
|
Before JSONMap `gorm:"column:before"`
|
|
After JSONMap `gorm:"column:after"`
|
|
UndoneAt *time.Time `gorm:"column:undone_at"`
|
|
UndoneByID *uint `gorm:"column:undone_by_id"`
|
|
CreatedAt time.Time `gorm:"column:created_at"`
|
|
// Change is the list's summary of the changed fields and ViaLabel the
|
|
// via column's label, filled by the history controller.
|
|
Change string `gorm:"-:all;column:change"`
|
|
ViaLabel string `gorm:"-:all;column:via_label"`
|
|
Batch string `gorm:"-:all;column:batch"`
|
|
}
|
|
|
|
func (Revision) TableName() string { return "golem15_seo_revisions" }
|
|
|
|
// Fillable is empty: history is written by the service only.
|
|
func (Revision) Fillable() []string { return []string{} }
|
|
|
|
// Rules is empty: history is never edited.
|
|
func (Revision) Rules() map[string]string { return map[string]string{} }
|
|
|
|
// FilterVia is the history list's via filter scope.
|
|
const FilterVia = "FilterVia"
|
|
|
|
// Vias lists the writers in display order.
|
|
var Vias = []string{ViaAdmin, ViaMCP, ViaImport, ViaAuto, ViaUndo}
|
|
|
|
func init() {
|
|
Register(Revision{})
|
|
}
|
|
|
|
// FilterScopes lists the history list's filter scopes.
|
|
func (Revision) FilterScopes() []string { return []string{FilterVia} }
|
|
|
|
// FilterScope narrows the history list to one writer; an unknown value
|
|
// matches nothing.
|
|
func (Revision) FilterScope(name string, db *gorm.DB, value any) *gorm.DB {
|
|
if db == nil || name != FilterVia {
|
|
return db
|
|
}
|
|
s, _ := value.(string)
|
|
for _, v := range Vias {
|
|
if v == s {
|
|
return db.Where("golem15_seo_revisions.via = ?", s)
|
|
}
|
|
}
|
|
return db.Where("1 = 0")
|
|
}
|