17 KiB
Payload Schema — Remaining Collections and Globals (Final)
Purpose
Final schema for every Payload collection and global used on the new Eversolo site, excluding Product (see SCHEMA-PRODUCT.md). This document is the source of truth for the Payload config.
Shared Conventions
Locales
en,zh- Field-level localization is used (not document-level).
**localized**below means the field is per-locale.**shared**means a single value across locales.
Status Workflow
All content-bearing collections share:
status:draft | review | published | archivedpublishedAt: auto-set on first publishcreatedAt,updatedAt: auto
Access Control
- Public read: only
status = published. - Write: authenticated editors and above.
- Admin-only fields are marked inline.
SEO Group
Used on all public-facing documents:
title— localized — text, max 70.description— localized — textarea, max 160.ogImage— shared — upload.canonical— shared — text, optional.noIndex— shared — checkbox, admin-only, default false.
Revalidation
Every collection that renders on the public site triggers on-demand revalidation of the affected route paths in its afterChange hook.
Collections
1. Product Categories
Slug: productCategories
slug— shared — text, required, URL-safe, unique.name— localized — text, required.description— localized — rich text.heroImage— shared — upload.order— shared — number, default 0.seo— group (see SEO group).
Validation
slugunique.namerequired per locale if that locale is published.
Admin UI Tabs
Overview: slug, name, description, order.Media: heroImage.SEO: seo.
2. FAQ
Slug: faqs
group— shared — select, required. Suggested values:setup | streaming | connectivity | hardware | warranty | other. Editable at admin level.question— localized — text, required.answer— localized — rich text, required.relatedProducts— shared — relationship toproducts, multi-select, optional.relatedDownloads— shared — relationship todownloads, multi-select, optional.order— shared — number, default 0.status— shared — select (see status workflow).
Listing
- Grouped by
group, ordered byorderascending. - Support page shows curated groups; dedicated FAQ page shows all published entries.
Validation
questionandanswerrequired for any locale being published.
3. Downloads
Slug: downloads
title— localized — text, required.type— shared — select, required. Values:firmware | manual | software | other.product— shared — relationship toproducts, required.version— shared — text, optional.releaseDate— shared — date, optional.file— shared — upload, required.checksum— shared — text, optional.changelog— localized — rich text, optional.notes— localized — rich text, optional.visibility— group.showInProductPage— shared — checkbox, default true.showInDownloadsCenter— shared — checkbox, default true.
status— shared — select (see status workflow).
Rules
- Firmware display on product pages also requires the product's
firmware.showOnProductPagetoggle to be on. - Firmware display in the Downloads center also requires the product's
firmware.showInDownloadsCentertoggle to be on. showInProductPageandshowInDownloadsCenterare download-level overrides: they can hide a specific file even when the product-level toggle is on.
Validation
titlerequired per published locale.filerequired.productrequired.typerequired.
Admin UI Tabs
Overview: title, type, product, version, releaseDate, status.File: file, checksum.Content: changelog, notes.Visibility: visibility group.
4. Product Videos
Slug: productVideos
title— shared — text, required.product— shared — relationship toproducts, required.provider— shared — select, required. Values:youtube | vimeo | bilibili | other.videoUrl— shared — text, required.embedUrl— shared — text, optional.thumbnail— shared — relationship tomedia, optional.description— localized — rich text, optional.publishedAt— shared — date, optional.sortOrder— shared — number, default 0.legacySourceUrl— shared — text, optional.status— shared — select (see status workflow).
Rules
- Product detail pages render all published videos related to the current product, ordered by
sortOrder, then newest first. - Seed import may create draft records first; editors can refine descriptions later.
5. Product Reviews
Slug: productReviews
title— shared — text, required.product— shared — relationship toproducts, required.sourceName— shared — text, optional.reviewUrl— shared — text, required.thumbnail— shared — relationship tomedia, optional.excerpt— localized — text, optional.quote— localized — text, optional.publishedAt— shared — date, optional.sortOrder— shared — number, default 0.legacySourceUrl— shared — text, optional.status— shared — select (see status workflow).
Rules
- Product detail pages render all published reviews related to the current product, ordered by
sortOrder, then newest first. - Reviews may be imported from the legacy site with minimal metadata and enriched later in CMS.
6. Dealers
Slug: dealers
name— shared — text, required.region— shared — select, required. Values mirror the Dealers page region filter.country— shared — text, required.city— shared — text, optional.address— localized — textarea, optional.email— shared — email, optional.phone— shared — text, optional.website— shared — URL, optional.logo— shared — upload, optional.isAuthorized— shared — checkbox, default true.order— shared — number, default 0.status— shared — select (see status workflow).
Listing
- Grouped by region, then country, then name.
- Only
isAuthorized = trueare shown in public lists.
7. News Articles
Slug: news
slug— localized — text, required, unique per locale.category— shared — select, required. Values:announcement | press | review | event.title— localized — text, required.excerpt— localized — textarea, optional.coverImage— shared — upload, required.body— localized — rich text, required.author— shared — text, optional.source— shared — text, optional (for press / review entries).sourceUrl— shared — URL, optional.publishedAt— shared — date, required on publish.relatedProducts— shared — relationship toproducts, multi-select, optional.status— shared — select (see status workflow).seo— group.
Listing Rules
- News list: all published, newest first.
- Homepage news highlights: manually selected via Homepage global.
- Articles may exist in a single locale; the UI surfaces only locales with published content.
8. Media
Slug: media
Generic upload collection for images used across the site.
file— upload, required.alt— localized — text, required.caption— localized — text, optional.credit— shared — text, optional.tags— shared — array of text.
Usage
Every image field in other collections references media. Editors upload once, reuse everywhere.
9. Videos
Slug: videos
Dedicated upload collection for video assets (hero videos, product showcase).
file— upload, required.poster— relationship tomedia, required.durationSeconds— shared — number, optional.alt— localized — text, required.tags— shared — array of text.
10. Files
Slug: files
Upload collection for firmware, manuals, software binaries, and other downloadable files. Used as the file reference on the downloads collection.
file— upload, required.sizeBytes— shared — number (auto).mimeType— shared — text (auto).
11. Redirects
Slug: redirects
Source of truth for 301 redirects from the legacy site, including the entries documented in REDIRECTS.md.
from— shared — text, required. Matches a path or pattern on the legacy URL space.to— shared — text, required. Destination path on the new site, locale-prefixed.statusCode— shared — select, required. Values:301 | 302 | 307 | 308. Default301.matchType— shared — select, required. Values:exact | prefix | regex. Defaultexact.locale— shared — select, optional. Values:any | en | zh. Controls whether the redirect applies only to a locale-scoped target.notes— shared — text, optional.enabled— shared — checkbox, default true.
Rules
- Redirects are resolved at the edge in priority order:
exact>prefix>regex. - External links (Amazon, JD, Tmall, forum.zidoo, shop.zidoo, blog.eversolo) are not managed here.
- The APP header link points directly to
https://www.eversolo.com/controlapp/index.htmland is not stored as a redirect.
Globals
1. Homepage
Slug: homepage
hero— group.mode— shared — select, required. Values:image | video. Defaultimage.image— shared — relationship tomedia, required whenmode = image.video— shared — relationship tovideos, required whenmode = video.headline— localized — text, required.supportingLine— localized — text, optional.primaryCta— group.label— localized — text.href— shared — text (internal path or URL).
secondaryCta— group.label— localized — text.href— shared — text.
featuredProducts— shared — relationship toproducts, required, exactly 4.statement— group.title— localized — text.body— localized — rich text.image— shared — relationship tomedia.cta— optional group of{ label, href }.
supportShortcuts— array, 3 to 4 items.label— localized — text, required.description— localized — text.href— shared — text, required.
recognition— group.awards— shared — array of{ logo: media, label (localized), year, url }.reviews— shared — array of{ sourceLogo: media, sourceName (localized), quote (localized), url }.
newsHighlights— shared — relationship tonews, up to 3, optional.seo— group.
Validation
featuredProductslength must equal 4.recognition.awardsshould contain at least 1 item if the module is shown; otherwise leave empty.
2. Support Page
Slug: supportPage
intro— group.title— localized — text.body— localized — rich text.
primaryEntries— array, required, exactly 3.key— shared — select, required. Values:faq | warranty | contact.label— localized — text, required.description— localized — text.href— shared — text, required.
secondaryEntries— array, 0 to 3 items.key— shared — select. Values:downloads | manuals | firmware.label— localized — text, required.description— localized — text.href— shared — text, required.
seo— group.
3. Warranty Page
Slug: warrantyPage
intro— group.title— localized — text.body— localized — rich text.
policyBody— localized — rich text, required.regionalNotes— array.region— shared — select.body— localized — rich text.
registrationCta— optional group of{ label, href }.seo— group.
4. Contact Page
Slug: contactPage
intro— group.title— localized — text.body— localized — rich text.
regions— array.region— shared — select.email— shared — email.phone— shared — text.address— localized — textarea.hours— localized — text.
formEnabled— shared — checkbox, default true.formSuccessMessage— localized — rich text.seo— group.
5. About Page
Slug: aboutPage
intro— group.title— localized — text.body— localized — rich text.
brandStory— localized — rich text.philosophy— localized — rich text.milestones— array.year— shared — number.title— localized — text.description— localized — rich text.image— shared — relationship tomedia, optional.
seo— group.
6. Global Settings
Slug: globalSettings
-
site— group.name— localized — text.logoLight— shared — relationship tomedia.logoDark— shared — relationship tomedia.favicon— shared — relationship tomedia.
-
navigation— group.primary— array, required. Each item:label— localized — text.href— shared — text.external— shared — checkbox, default false.openInNewTab— shared — checkbox, default false.iconKey— shared — text, optional (for future icon support).
app— group (singleton inside navigation).label— localized — text, defaultAPP.href— shared — text, required, defaulthttps://www.eversolo.com/controlapp/index.html.openInNewTab— shared — checkbox, default true.showOnDesktop— shared — checkbox, default true.showOnMobile— shared — checkbox, default true.
-
footer— group.columns— array.title— localized — text.items— array of{ label (localized), href, external, openInNewTab }.
legalLinks— array of{ label (localized), href }.copyright— localized — text.
-
social— array of{ platform, url, iconKey }. -
languageSwitcher— group.labels— per-locale{ en: "English", zh: "简体中文" }.
-
analytics— group.provider— select:plausible | ga4 | none.domain— text.measurementId— text.
-
seoDefaults— group.titleSuffix— localized — text.description— localized — textarea.ogImage— shared — relationship tomedia.
-
cookieBanner— group.enabled— shared — checkbox, default true.body— localized — rich text.acceptLabel— localized — text.declineLabel— localized — text.
Notes
- The header APP entry is driven by
navigation.appso editors can update the label, URL, and visibility without a code change. openInNewTabdefaults to true for external items.
Hooks (cross-collection)
afterChangeon any publishable document:- Revalidate affected public routes.
- Revalidate Homepage if the document is referenced in Homepage fields.
beforeValidateon any slug field:- Normalize (lowercase, trim, dashes, ASCII fallback).
beforeChangeonstatus:- Set
publishedAton first transition topublished.
- Set
Admin UX Principles
- Use tabs per collection to separate structural, content, media, and SEO fields.
- Globals use grouped sections rather than tabs to stay editor-friendly.
- Every relationship field is labeled with its expected content type and any filters applied.
- Locale selector is persistent across the admin UI.
Open Items
- Whether Redirects are managed in CMS or in a versioned file; current plan: CMS-managed for editor control.
- Whether News articles should support per-locale
statusseparately. - Whether the Dealers region list should be a CMS-managed enum or hardcoded.
- Whether the Homepage
recognitionmodule should allow a layout choice (logo wall vs quote strip) per locale.