feat: SEO backend output (2/4)

This commit is contained in:
Florian Sylvain committed 2026-10-15 21:48:55 +02:00
1 parent 0eb46b0d74
commit eb9876fde3
32 files changed
+3859 -65

No files matched your search

@@ -14,6 +14,7 @@ const (
SortByStatus SortField = "status"
SortByCreatedAt SortField = "created_at"
SortByUpdatedAt SortField = "updated_at"
SortByID SortField = "id"
SortAsc SortDirection = "asc"
SortDesc SortDirection = "desc"
@@ -36,6 +37,7 @@ type Filters struct {
Q string
Status string
Sort Sort
Unpaged bool
}
type Nullable[T any] struct {
+91
View File
@@ -0,0 +1,91 @@
package article
const (
SEOSourceSEOTitle = "seo_title"
SEOSourceTitle = "title"
SEOSourceSEODescription = "seo_description"
SEOSourceExcerpt = "excerpt"
SEOSourceBody = "body"
SEOSourceSite = "site"
SEOSourceNone = "none"
SEOSourceSocial = "social"
SEOSourceCover = "cover"
SEOSourceCanonicalURL = "canonical_url"
)
type SEOOpenGraph struct {
Type string `json:"type"`
Title string `json:"title"`
Description string `json:"description"`
Image string `json:"image"`
ImageAlt string `json:"image_alt"`
URL string `json:"url"`
SiteName string `json:"site_name"`
Locale string `json:"locale"`
}
type SEOTwitter struct {
Card string `json:"card"`
Title string `json:"title"`
Description string `json:"description"`
Image string `json:"image"`
ImageAlt string `json:"image_alt"`
}
type SEOImage struct {
URL string `json:"url"`
Alt string `json:"alt"`
Source string `json:"source"`
}
type SEOAuthor struct {
Name string `json:"name"`
URL string `json:"url"`
SameAs []string `json:"same_as"`
}
type SEOFallbacks struct {
Title string `json:"title"`
Description string `json:"description"`
Image string `json:"image"`
Canonical string `json:"canonical"`
}
type SEOJSONLDPerson struct {
Type string `json:"@type"`
Name string `json:"name"`
URL string `json:"url"`
SameAs []string `json:"sameAs"`
}
type SEOJSONLDPage struct {
Type string `json:"@type"`
ID string `json:"@id"`
}
type SEOJSONLD struct {
Context string `json:"@context"`
Type string `json:"@type"`
Headline string `json:"headline"`
Description string `json:"description,omitempty"`
Image []string `json:"image,omitempty"`
Author []SEOJSONLDPerson `json:"author,omitempty"`
DatePublished string `json:"datePublished,omitempty"`
DateModified string `json:"dateModified"`
MainEntityOfPage SEOJSONLDPage `json:"mainEntityOfPage"`
}
type ResolvedSEO struct {
Title string `json:"title"`
Description string `json:"description"`
CanonicalURL string `json:"canonical_url"`
Robots string `json:"robots"`
OG SEOOpenGraph `json:"og"`
Twitter SEOTwitter `json:"twitter"`
Image SEOImage `json:"image"`
Authors []SEOAuthor `json:"authors"`
PublishedAt *string `json:"published_at"`
ModifiedAt string `json:"modified_at"`
Fallbacks SEOFallbacks `json:"fallbacks"`
JSONLD SEOJSONLD `json:"json_ld"`
}
+53
View File
@@ -0,0 +1,53 @@
package article
const (
SEOStatusReady = "ready"
SEOStatusSuggestions = "suggestions"
SEOStatusHidden = "hidden"
SEOTitleMaxRunes = 60
SEODescriptionMinRunes = 70
SEODescriptionMaxRunes = 160
SEOSlugMaxRunes = 75
SEOHeadingMinTextRunes = 1000
SEOShortBodyRunes = 300
SEOFieldTitle = "seo_title"
SEOFieldDescription = "seo_description"
SEOFieldCoverAlt = "cover_image_alt"
SEOFieldCoverID = "cover_image_id"
SEOFieldSlug = "slug"
SEOFieldAuthors = "author_ids"
SEOFieldBody = "body"
)
type SEOSuggestion struct {
Code string `json:"code"`
Field string `json:"field"`
Params map[string]int `json:"params"`
}
type SEOAssessment struct {
Status string `json:"status"`
Suggestions []SEOSuggestion `json:"suggestions"`
}
type SEOSummary struct {
Status string
Suggestions int
}
func (a SEOAssessment) Summary() SEOSummary {
return SEOSummary{Status: a.Status, Suggestions: len(a.Suggestions)}
}
type SEOSlugCheck struct {
Available bool `json:"available"`
Suggestion *string `json:"suggestion"`
}
type SEOCheck struct {
Status string `json:"status"`
Suggestions []SEOSuggestion `json:"suggestions"`
Slug SEOSlugCheck `json:"slug"`
}