Files
sm-seo-plugin/controllers/api/issues.go
Jakub Zych 59f0457c69 feat: sitemap-aware batch conflict and the sitemap_blocked issue
- noindex_published fires only when a sitemap file lists the address now
  (read once per batch through contract.Listing)
- CMS issue sitemap_blocked (severity error, tool seo_update_robots,
  details line and rule): a listed address the production robots.txt
  keeps Googlebot from
- the SEO tab's P1 shows status.excluded_title with the reason (noindex,
  canonical elsewhere, redirect, or the type switched off in the sitemap
  settings via ListingSettings.TypesOff) as a plain callout
- robots.txt is composed once per check of many addresses
2026-11-04 13:39:31 +01:00

36 lines
1.2 KiB
Go

package api
import (
"context"
"net/http"
"git.golem15.com/golem15/sm-seo-plugin/classes"
)
// ListIssuesInput is the query of GET /_seo/api/v1/issues.
type ListIssuesInput struct {
Kind string `json:"kind,omitempty" query:"kind" jsonschema:"one kind only: missing_title, missing_description, duplicate_title, duplicate_description, rule_overrides_record, redirect_chain, canonical_noindex, canonical_redirected, noindex_blocked or sitemap_blocked"`
}
// ListIssues serves GET /_seo/api/v1/issues (D-13, D-14 CMS part): the
// CMS-data issue report, each issue with its URL, kind, details and the
// tool that fixes it, and a count per kind.
func ListIssues(service func() *classes.Service) http.HandlerFunc {
return manage(service, func(ctx context.Context, svc *classes.Service, r *http.Request) (int, any, error) {
issues, err := svc.Issues(ctx)
if err != nil {
return 0, nil, err
}
kind := r.URL.Query().Get("kind")
counts := map[string]int{}
out := make([]classes.Issue, 0, len(issues))
for _, issue := range issues {
counts[issue.Kind]++
if kind == "" || issue.Kind == kind {
out = append(out, issue)
}
}
return http.StatusOK, map[string]any{"data": out, "counts": counts, "total": len(out)}, nil
})
}