catalogentry

package
v1.800.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: Apache-2.0, MIT Imports: 9 Imported by: 0

Documentation

Overview

Package catalogentry is the CMS source-of-truth for the platform product catalog — the single list docs.<brand>, the console sidebar, and pricing all derive from. commerce owns the DATA (source + seed + edits); the shape is the @hanzo/products contract (that package owns the schema + the iconKey→component and brandColor→css code-maps). Pricing is native: an entry references a pricing plan by key (PricingId), or carries a fixed PriceCents.

Conformance (GET /v1/commerce/catalog → the @hanzo/products CatalogEntry):

  • iconKey is a @hanzogui/lucide-icons-2 export NAME ("Brain") — never a component.
  • brandColor is a swatch KEY ("violet") — never hex. @hanzo/products maps key→css.
  • category is EXACTLY one of the 13 canonical labels (others are dropped by scope).
  • route is "/<slug>", apiPath is /v1-prefixed, docsUrl is /docs/services/<slug>.
  • pricingId is a pricing plans/<key>.json key, or null.
  • brands is a category-derived convenience — NOT a hand-authored filter; the server scopes by CATEGORY (categoriesForBrand), matching @hanzo/products catalogForBrand.

Index

Constants

View Source
const (
	StatusEnabled  = "enabled"  // in-console module that works
	StatusExternal = "external" // live external brand surface
	StatusSoon     = "soon"     // primitive shipped, no console surface yet
)

Status enumerates a product's honest enablement state (mirrors the console registry): a working in-console module, a live external surface, or a primitive that ships with no console surface yet. No fabricated states.

Variables

This section is empty.

Functions

func CategorySlug

func CategorySlug(label string) string

CategorySlug slugifies a category label the way @hanzo/products categorySlug does: simple lowercase ("AI"→"ai", "Web3"→"web3").

func Query

func Seed

func Seed(db *datastore.Datastore) (created int, err error)

Seed loads the embedded @hanzo/products snapshot into db (which MUST be namespaced to the catalog-owning "system" org). IDEMPOTENT + NON-DESTRUCTIVE: an entry whose slug already exists is left UNTOUCHED so CMS edits are never clobbered; only missing slugs are created. Order is the snapshot index (stable display order within a category). Returns the number created.

func SeedIfEmpty

func SeedIfEmpty(db *datastore.Datastore) (created int, err error)

SeedIfEmpty seeds the catalog only when it is currently empty — a cheap single count query gates the full per-row create, so it is safe to call on every bootstrap. Once any entry exists (seeded or CMS-created) it never re-runs, so CMS state stays authoritative.

Types

type Catalog

type Catalog struct {
	Brand      string     `json:"brand"`
	Categories []Category `json:"categories"`
	Products   []Item     `json:"products"`
}

Catalog is the full projection returned by GET /v1/commerce/catalog. `products` is the CatalogEntry[] @hanzo/products consumes; brand + categories are additive envelope fields.

func Project

func Project(db *datastore.Datastore, brand string) (Catalog, error)

Project reads the published catalog entries from db (which MUST be namespaced to the catalog-owning "system" org) and returns the brand-scoped projection: the ordered taxonomy + the entries whose CATEGORY the brand surfaces, sorted by (category order, entry order, name). Scoping is by category only — matching @hanzo/products catalogForBrand — so the same store serves every brand.

type CatalogEntry

type CatalogEntry struct {
	mixin.Model[CatalogEntry]

	Slug        string `json:"slug"`                             // stable id / path segment, e.g. "gateway"
	Name        string `json:"name"`                             // "Gateway"
	Category    string `json:"category"`                         // one of the 13 canonical labels
	Description string `json:"description" datastore:",noindex"` // one-line (additive; not in the core contract)
	Gcp         string `json:"gcp,omitempty"`                    // GCP product it stands in for

	// Presentation KEYS (CMS-editable; @hanzo/products resolves them).
	IconKey    string `json:"iconKey"`    // lucide export name, e.g. "Network"
	BrandColor string `json:"brandColor"` // swatch key, e.g. "blue"

	Route   string `json:"route"`   // "/<slug>"
	DocsUrl string `json:"docsUrl"` // https://docs.hanzo.ai/docs/services/<slug>
	ApiPath string `json:"apiPath"` // /v1-prefixed

	// PricingId references a pricing plan by key (plans/<key>.json); empty ⇒
	// projected as JSON null. PriceCents is an optional native fixed-price
	// override (additive to the contract).
	PricingId  string         `json:"pricingId"`
	PriceCents currency.Cents `json:"priceCents,omitempty"`
	Currency   currency.Type  `json:"currency,omitempty"`

	Status string `json:"status" orm:"default:enabled"` // enabled|external|soon
	Repo   string `json:"repo,omitempty"`               // source repo, e.g. "hanzoai/ai"
	Admin  bool   `json:"admin,omitempty"`              // admin-gated surface

	// Brands is a category-derived convenience preserved from the seed (the
	// server filters by category, not by this list). Stored as a noindex blob.
	Brands  []string `json:"brands,omitempty" datastore:"-"`
	Brands_ string   `json:"-" datastore:",noindex"`

	Order     int  `json:"order"`                        // display rank within a category
	Published bool `json:"published" orm:"default:true"` // gates from the public projection

	// ProductId optionally links this catalog surface to a real commerce
	// product for checkout/subscription. Empty = presentation/pricing only.
	ProductId string `json:"productId,omitempty"`

	Metadata  Map    `json:"metadata,omitempty" datastore:"-"`
	Metadata_ string `json:"-" datastore:",noindex"`
}

CatalogEntry is one product in the platform catalog. Slug (== id) is the stable, globally-unique key the entry is addressed by.

func New

func (*CatalogEntry) Load

func (e *CatalogEntry) Load(ps []datastore.Property) (err error)

func (*CatalogEntry) Save

func (e *CatalogEntry) Save() ([]datastore.Property, error)

type Category

type Category struct {
	ID    string `json:"id"`    // slugified label, e.g. "ai"
	Label string `json:"label"` // "AI"
	Order int    `json:"order"` // display rank
}

Category is one taxonomy entry in the projection.

type Item

type Item struct {
	ID         string   `json:"id"` // == Slug (stable, unique)
	Name       string   `json:"name"`
	Category   string   `json:"category"`
	BrandColor string   `json:"brandColor"`
	IconKey    string   `json:"iconKey"`
	Slug       string   `json:"slug"`
	Route      string   `json:"route"`
	DocsUrl    string   `json:"docsUrl"`
	ApiPath    string   `json:"apiPath"`
	PricingId  *string  `json:"pricingId"`        // string OR null
	Brands     []string `json:"brands,omitempty"` // category-derived convenience

	// Additive (client ignores unknowns).
	Description string         `json:"description,omitempty"`
	Gcp         string         `json:"gcp,omitempty"`
	Status      string         `json:"status,omitempty"`
	Repo        string         `json:"repo,omitempty"`
	Admin       bool           `json:"admin,omitempty"`
	PriceCents  currency.Cents `json:"priceCents,omitempty"`
	Currency    currency.Type  `json:"currency,omitempty"`
	Order       int            `json:"order,omitempty"`
	ProductId   string         `json:"productId,omitempty"`
}

Item is the public projection of a CatalogEntry — the exact @hanzo/products CatalogEntry shape. Presentation keys (iconKey, brandColor) are strings resolved client-side; pricingId is null when unset. Fields beyond the core contract (gcp, repo, admin, status, description, priceCents, order, productId) are additive — the client ignores unknowns.

type SeedRow

type SeedRow struct {
	ID         string   `json:"id"`
	Name       string   `json:"name"`
	Category   string   `json:"category"`
	BrandColor string   `json:"brandColor"`
	IconKey    string   `json:"iconKey"`
	Slug       string   `json:"slug"`
	Route      string   `json:"route"`
	DocsUrl    string   `json:"docsUrl"`
	ApiPath    string   `json:"apiPath"`
	PricingId  string   `json:"pricingId"` // null → ""
	Brands     []string `json:"brands"`
	Repo       string   `json:"repo"`
	Admin      bool     `json:"admin"`
	Status     string   `json:"status"`
	Gcp        string   `json:"gcp"`
}

SeedRow is the @hanzo/products snapshot shape (the exact CatalogEntry contract). `id` == `slug`; `pricingId` may be JSON null (→ "").

func HanzoSeedRows

func HanzoSeedRows() ([]SeedRow, error)

HanzoSeedRows returns the parsed embedded snapshot.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL