Files
website/SCHEMA-PRODUCT.md
2026-04-23 01:08:18 +08:00

193 lines
8.2 KiB
Markdown

# Payload Schema — Product Collection (Final)
## Purpose
Single source of truth for the Product collection in Payload. This is the version that will be implemented in code. All product detail pages (system-rendered layout and project-local HTML templates) depend on this schema.
## Collection Slug
`products`
## Localization
- Locales: `en`, `zh`
- Each locale can be edited and published independently.
- Fields marked **localized** below use Payload field-level localization.
- Fields marked **shared** are global and the same across locales.
## Access Control
- Public read: only documents with `status = published`.
- Write: authenticated editors and above.
- Admin-only fields: `seo.noIndex`, `template`, `firmware.showOnProductPage`, `firmware.showInDownloadsCenter`.
## Status Workflow
- `draft`
- `review`
- `published`
- `archived`
## Fields
### 1. Identity
- `slug`**localized** — text, required, unique per locale, URL-safe.
- `model`**shared** — text, required. The marketing model name, for example `DMP-A10`.
- `status`**shared** — select, required, one of `draft | review | published | archived`.
- `order`**shared** — number, default 0. Used for manual ordering inside category listings.
- `category`**shared** — relationship to `productCategories`, required.
### 2. Template Selection
- `template`**shared** — select, required, options dynamically enumerated from valid directories under `webroot/Products/`. If no templates exist, the UI falls back to the default system-rendered layout.
- `templateEnabled`**shared** — checkbox, default false. When true, the product detail route injects the HTML template into the middle content region. When false, the default system-rendered layout is used even if a template is selected.
### 3. Marketing Copy (localized)
- `name`**localized** — text, required. Display name shown in cards and headings.
- `tagline`**localized** — text. One-line descriptor used in product cards and hero.
- `summary`**localized** — rich text. Short paragraph used on overview pages.
- `overview`**localized** — rich text. Longer intro used in the system-rendered layout.
### 4. Media
- `heroImage`**shared** — upload, required. Used in the top of default-rendered product pages and as card image.
- `cardImage`**shared** — upload, optional. Optional override for the featured product card. Horizontal composition preferred to align with homepage visual spec.
- `gallery`**shared** — array of uploads, optional. Ordered product imagery.
- `lifestyleImage`**shared** — upload, optional. Used for lifestyle placement in listings or cross-links.
- `heroVideo`**shared** — group, optional.
- `src` — upload or URL.
- `poster` — upload.
### 5. Key Features (localized content, shared structure)
`keyFeatures` — array, 0 to 8 items.
Per item:
- `icon`**shared** — upload, optional.
- `image`**shared** — upload, optional.
- `title`**localized** — text, required.
- `description`**localized** — rich text.
### 6. Technology Highlights (localized)
`technologyHighlights`**localized** — rich text with blocks.
Allowed blocks:
- `textBlock`
- `imageTextBlock`
- `quoteBlock`
### 7. Specifications
`specifications` — array of spec groups.
Per group:
- `groupName`**localized** — text, required.
- `order`**shared** — number, default 0.
- `items` — array.
- `label`**localized** — text, required.
- `value`**localized** — text, required.
- `note`**localized** — text, optional.
### 8. Firmware (display is opt-in)
`firmware` — group.
- `showOnProductPage`**shared** — checkbox, default false. Controls whether firmware is displayed on the product detail page.
- `showInDownloadsCenter`**shared** — checkbox, default false. Controls whether this product's firmware appears in the site-wide Downloads center.
- `displayLabel`**localized** — text, optional. Overrides the default section title on the product page.
- `items` — relationship to `downloads`, filtered to `type = firmware`, multi-select, ordered.
- `notes`**localized** — rich text, optional. Release notes or compatibility notes rendered above the list.
UI rules:
- The two visibility toggles are independent. Either can be on or off without affecting the other.
- `items` and `notes` are edited independently of the toggles; disabling both toggles hides firmware from public UI but preserves data.
- Payload UI should clearly show current visibility status on each product record.
### 9. Downloads (non-firmware)
`downloads` — group.
- `manuals` — relationship to `downloads`, filtered to `type = manual`, multi-select.
- `software` — relationship to `downloads`, filtered to `type = software`, multi-select.
- `other` — relationship to `downloads`, filtered to `type = other`, multi-select.
These are always available on the product page when entries exist. The firmware module is separated because its visibility is opt-in.
### 10. Relations
- `relatedProducts` — relationship to `products`, multi-select, up to 4.
- `accessories` — relationship to `products`, multi-select, optional.
- `featuredDealers` — relationship to `dealers`, multi-select, optional.
### 11. Awards and Reviews (optional on detail page)
`awards` — array, optional.
Per item:
- `logo`**shared** — upload.
- `label`**localized** — text.
- `year`**shared** — number.
- `url`**shared** — URL, optional.
`reviews` — array, optional.
Per item:
- `sourceLogo`**shared** — upload, optional.
- `sourceName`**localized** — text.
- `quote`**localized** — text, required.
- `url`**shared** — URL, optional.
### 12. SEO
`seo` — group, **localized**.
- `title` — text, max 70 chars.
- `description` — textarea, max 160 chars.
- `ogImage` — upload.
- `canonical` — text, optional.
- `noIndex` — checkbox, admin-only, default false.
### 13. Timestamps (auto)
- `createdAt`
- `updatedAt`
- `publishedAt`
## Hooks
- `beforeValidate`:
- Normalize `slug` (lowercase, trim, ASCII fallback, dashes).
- `beforeChange`:
- Auto-set `publishedAt` when `status` transitions to `published` for the first time.
- If `template` refers to a non-existent directory, reject with a validation error.
- `afterChange`:
- Trigger on-demand revalidation for `/en/products`, `/zh/products`, `/en/products/<slug>`, `/zh/products/<slug>`.
- Trigger revalidation for Homepage if the product is part of `Homepage.featuredProducts`.
## Admin UI Layout (recommended tabs)
1. `Overview` — identity, status, template, name, tagline, summary, category, order.
2. `Content` — overview, keyFeatures, technologyHighlights, specifications.
3. `Media` — heroImage, cardImage, gallery, lifestyleImage, heroVideo.
4. `Firmware` — firmware group.
5. `Downloads` — downloads group.
6. `Relations` — relatedProducts, accessories, featuredDealers.
7. `Recognition` — awards, reviews.
8. `SEO` — seo group.
## Rendering Rules (summary)
- If `templateEnabled` is true and `template` resolves to a valid directory, render:
- Header (from main layout)
- Breadcrumb (from main layout)
- Optional hero block (from CMS)
- **Middle content region** populated by `webroot/Products/<template>/<locale>/index.html`
- Firmware module (only if `firmware.showOnProductPage`)
- Related downloads, related products, recognition (if present)
- Footer (from main layout)
- Otherwise, render the default system-rendered layout using the structured fields above.
- The site-wide Downloads center lists firmware entries only for products with `firmware.showInDownloadsCenter = true`.
## Validation Rules
- `slug` must be unique per locale.
- `model` required.
- `category` required.
- `heroImage` required.
- `template` required; must reference an existing directory.
- `firmware.items` must all have `type = firmware`.
- `awards[].year` must be between 1990 and current year + 1.
- At least one locale must have `status = published` before the product is publicly visible.
## Open Items
- Whether `status` should be a per-locale field to allow a product to go live in EN before ZH.
- Whether `templateEnabled` toggle is visible to all editors or admin-only.
- Whether recognition (awards, reviews) should also live at brand level, not just per product.