feat: structured data, graph preview and primary category in the SEO tab

- E8 golem15-seo-schema: the type per content kind, the Service grid with
  price and currency checks, custom JSON-LD with a 300 ms parse status
- E9 golem15-seo-graph: nodes and findings from the seo_graph action, the
  JSON, the Rich Results Test link, 800 ms re-check on fill changes, the
  ML locale switch, one queued request, the failure line
- golem15-seo-parent: the primary category select over the record's
  parents; the seoparent Decode accepts the loaded value sent back
- the rebuilt element bundle and vitest smoke tests
This commit is contained in:
Jakub Zych
2026-11-04 14:37:49 +01:00
parent 17da132b00
commit 10ff628f6a
10 changed files with 1350 additions and 4 deletions

View File

@@ -177,7 +177,12 @@ func decodeSchema(app func() *backpack.App) func(context.Context, pact.FormField
// parents as <type>:<id>.
func decodeParent(app func() *backpack.App) func(context.Context, pact.FormFieldValue) (pact.FormFieldDecoded, error) {
return func(ctx context.Context, in pact.FormFieldValue) (pact.FormFieldDecoded, error) {
raw, ok := stringValue(in.Value)
value := in.Value
if m, isMap := value.(map[string]any); isMap {
// The loaded {selected, options} sent back unchanged.
value = m["selected"]
}
raw, ok := stringValue(value)
raw = strings.TrimSpace(raw)
if !ok {
return pact.FormFieldDecoded{}, &pact.FormFieldError{Messages: []string{"golem15.seo::lang.api.value_invalid"}}