product

package
v1.42.3 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package product provides model initialization and query helpers for the v2 Product model.

Package product provides the Product model for e-commerce product management. This v2 implementation uses the new db.DB interface with SQLite backends and supports vector embeddings for AI-powered recommendations.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrProductNotFound    = errors.New("product: not found")
	ErrProductInvalidID   = errors.New("product: invalid id")
	ErrProductInvalidSlug = errors.New("product: invalid slug")
	ErrProductDuplicate   = errors.New("product: duplicate slug or sku")
	ErrProductValidation  = errors.New("product: validation failed")
	ErrEmbeddingFailed    = errors.New("product: failed to store embedding")
)

Common errors for Product operations

View Source
var IgnoreFieldMismatch = datastore.IgnoreFieldMismatch

Functions

func BulkCreate

func BulkCreate(ctx context.Context, database db.DB, products []*ProductV2) error

BulkCreate creates multiple products in a single transaction

func CountV2

func CountV2(ctx context.Context, database db.DB, orgID string) (int, error)

CountV2 returns the total number of products

func DeleteMultiV2

func DeleteMultiV2(ctx context.Context, database db.DB, ids []string) error

DeleteMultiV2 soft-deletes multiple products

func EnsureTableV2

func EnsureTableV2(ctx context.Context, database db.DB) error

EnsureTableV2 creates the product table if it doesn't exist This is called automatically by SQLiteDB but can be used for explicit setup

func ExportV2

func ExportV2(ctx context.Context, database db.DB, orgID string) ([]byte, error)

ExportV2 exports all products as JSON for backup/migration

func ImportV2

func ImportV2(ctx context.Context, database db.DB, data []byte) error

ImportV2 imports products from JSON backup

func KindV2

func KindV2() string

KindV2 returns the entity kind

func Query

Types

type Document

type Document struct {
	mixin.DocumentSaveLoad `datastore:"-" json:"-"`

	// Special Kind Option
	Kind string `search:",facet"`

	Id_  string
	Slug string
	SKU  string
	UPC  string

	Currency      string
	Price         float64
	ListPrice     float64
	InventoryCost float64

	// Shipping  float64
	Inventory float64

	Weight     float64
	WeightUnit string

	DimensionsLength float64
	DimensionsWidth  float64
	DimensionsHeight float64
	DimensionsUnit   string

	Name              string
	Description       string
	EstimatedDelivery string

	CreatedAt float64
	UpdatedAt float64

	// Facets
	PriceOption         float64 `search:"price,facet"`
	ListPriceOption     float64 `search:"listPrice,facet"`
	InventoryCostOption float64 `search:"inventoryCost,facet"`

	InventoryOption float64 `search:"inventory,facet"`

	WeightOption     float64 `search:"weight,facet"`
	WeightUnitOption string  `search:"weightUnit,facet"`

	DimensionsLengthOption float64 `search:"dimensionsLength,facet"`
	DimensionsWidthOption  float64 `search:"dimensionsWidth,facet"`
	DimensionsHeightOption float64 `search:"dimensionsHeight,facet"`
	DimensionsUnitOption   string  `search:"dimensionsUnit,facet"`

	AvailableOption string `search:"available,facet"`
	HiddenOption    string `search:"hidden,facet"`
	PreorderOption  string `search:"preorder,facet"`
}

func (*Document) Id

func (d *Document) Id() string

func (*Document) Init

func (d *Document) Init()

type Option

type Option struct {
	// Ex. Size
	Name string `json:"name"`
	// Ex. [S, M, L]
	Values []string `json:"values"`
}

type OptionV2

type OptionV2 struct {
	// Name is the option name (e.g., "Size", "Color")
	Name string `json:"name"`
	// Values are the available option values (e.g., ["S", "M", "L"])
	Values []string `json:"values"`
}

OptionV2 represents a product option (e.g., Size, Color)

type PriceRange

type PriceRange struct {
	Min currency.Cents `json:"min"`
	Max currency.Cents `json:"max"`
}

PriceRange represents a price range

type Product

type Product struct {
	mixin.Model[Product]
	productcachedvalues.ProductCachedValues

	Ref refs.EcommerceRef `json:"ref,omitempty"`

	// Unique human readable id
	Slug string `json:"slug"`
	SKU  string `json:"sku,omitempty"`
	UPC  string `json:"upc,omitempty"`

	// Product Name
	Name string `json:"name"`

	// Product headline
	Headline string `json:"headline" datastore:",noindex"`

	// Product Excerpt
	Excerpt string `json:"excerpt" datastore:",noindex"`

	// Product Description
	Description string `json:"description" datastore:",noindex"`

	// Product Media
	Header Media   `json:"header"`
	Image  Media   `json:"image"`
	Media  []Media `json:"media"`

	// Is the product available
	Available bool `json:"available"`

	// Is product hidden from users
	Hidden bool `json:"hidden"`

	// Range in which product is available. If active, it takes precedent over
	// Available bool.
	Availability Availability `json:"availability"`

	// Is this product for preorder
	Preorder bool `json:"preorder"`

	// Pre-order now or Add to cart
	AddLabel string `json:"addLabel"`

	// List of variants
	Variants  []*variant.Variant `json:"variants" datastore:"-"`
	Variants_ string             `json:"-" datastore:",noindex"`

	// Reference to options used
	Options  []*Option `json:"options" datastore:"-"`
	Options_ string    `json:"-" datastore:",noindex"`

	Reservation Reservation `json:"reservation"`

	// Arbitrary key/value pairs associated with this order
	Metadata  Map    `json:"metadata,omitempty" datastore:"-"`
	Metadata_ string `json:"-" datastore:",noindex"`
}

Prune down since Product Listing has a lot of this info now

func Fake

func Fake(db *datastore.Datastore) *Product

func New

func New(db *datastore.Datastore) *Product

func (*Product) Defaults

func (p *Product) Defaults()

func (Product) DisplayImage

func (p Product) DisplayImage() Media

func (Product) DisplayName

func (p Product) DisplayName() string

func (Product) DisplayPrice

func (p Product) DisplayPrice() string

func (Product) Document

func (p Product) Document() mixin.Document

func (*Product) Load

func (p *Product) Load(ps []datastore.Property) (err error)

func (Product) MinPrice

func (p Product) MinPrice() currency.Cents

func (*Product) Save

func (p *Product) Save() ([]datastore.Property, error)

func (*Product) Validator

func (p *Product) Validator() *val.Validator

func (Product) VariantOptions

func (p Product) VariantOptions(name string) (options []string)

TODO: Don't do this.

type ProductQueryV2

type ProductQueryV2 struct {
	// contains filtered or unexported fields
}

ProductQueryV2 provides query operations for products

func QueryProductsV2

func QueryProductsV2(database db.DB) *ProductQueryV2

QueryProductsV2 creates a new product query

func QueryV2

func QueryV2(database db.DB) *ProductQueryV2

QueryV2 creates a new product query

func (*ProductQueryV2) Available

func (q *ProductQueryV2) Available() *ProductQueryV2

Available filters to only available products

func (*ProductQueryV2) Count

func (q *ProductQueryV2) Count(ctx context.Context) (int, error)

Count returns the number of matching products

func (*ProductQueryV2) Filter

func (q *ProductQueryV2) Filter(field string, value interface{}) *ProductQueryV2

Filter adds a filter condition

func (*ProductQueryV2) First

func (q *ProductQueryV2) First(ctx context.Context) (*ProductV2, error)

First retrieves the first matching product

func (*ProductQueryV2) GetAll

func (q *ProductQueryV2) GetAll(ctx context.Context) ([]*ProductV2, error)

GetAll retrieves all matching products

func (*ProductQueryV2) InCollection

func (q *ProductQueryV2) InCollection(collectionID string) *ProductQueryV2

InCollection filters by collection ID

func (*ProductQueryV2) Keys

func (q *ProductQueryV2) Keys(ctx context.Context) ([]db.Key, error)

Keys returns only the keys of matching products

func (*ProductQueryV2) Limit

func (q *ProductQueryV2) Limit(n int) *ProductQueryV2

Limit sets the maximum results

func (*ProductQueryV2) NotDeleted

func (q *ProductQueryV2) NotDeleted() *ProductQueryV2

NotDeleted filters out deleted products

func (*ProductQueryV2) Offset

func (q *ProductQueryV2) Offset(n int) *ProductQueryV2

Offset sets the starting offset

func (*ProductQueryV2) Order

func (q *ProductQueryV2) Order(field string) *ProductQueryV2

Order sets the sort order

func (*ProductQueryV2) OrderDesc

func (q *ProductQueryV2) OrderDesc(field string) *ProductQueryV2

OrderDesc sets descending sort order

func (*ProductQueryV2) Visible

func (q *ProductQueryV2) Visible() *ProductQueryV2

Visible filters to only visible (not hidden) products

func (*ProductQueryV2) WithTag

func (q *ProductQueryV2) WithTag(tag string) *ProductQueryV2

WithTag filters by tag

type ProductStats

type ProductStats struct {
	TotalProducts     int            `json:"totalProducts"`
	AvailableProducts int            `json:"availableProducts"`
	HiddenProducts    int            `json:"hiddenProducts"`
	DeletedProducts   int            `json:"deletedProducts"`
	TotalVariants     int            `json:"totalVariants"`
	TotalInventory    int            `json:"totalInventory"`
	TotalSold         int            `json:"totalSold"`
	PriceRange        PriceRange     `json:"priceRange"`
	CollectionCounts  map[string]int `json:"collectionCounts,omitempty"`
	TagCounts         map[string]int `json:"tagCounts,omitempty"`
}

ProductStats holds aggregate statistics for products

func GetStatsV2

func GetStatsV2(ctx context.Context, database db.DB, orgID string) (*ProductStats, error)

GetStatsV2 calculates aggregate statistics for products

type ProductV2

type ProductV2 struct {
	productcachedvalues.ProductCachedValues

	// Core identification
	ID        string    `json:"id"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
	Deleted   bool      `json:"deleted,omitempty"`

	// Organization context
	OrgID     string `json:"orgId"`
	Namespace string `json:"namespace,omitempty"`

	// External references
	Ref refs.EcommerceRef `json:"ref,omitempty"`

	// Human-readable identifiers
	Slug string `json:"slug"`
	SKU  string `json:"sku,omitempty"`
	UPC  string `json:"upc,omitempty"`

	// Product content
	Name        string `json:"name"`
	Headline    string `json:"headline,omitempty"`
	Excerpt     string `json:"excerpt,omitempty"`
	Description string `json:"description,omitempty"`

	// Media assets
	Header Media   `json:"header,omitempty"`
	Image  Media   `json:"image,omitempty"`
	Media  []Media `json:"media,omitempty"`

	// Availability
	Available    bool         `json:"available"`
	Hidden       bool         `json:"hidden"`
	Availability Availability `json:"availability,omitempty"`
	Preorder     bool         `json:"preorder"`
	AddLabel     string       `json:"addLabel,omitempty"`

	// Variants and options
	Variants []*VariantV2 `json:"variants"`
	Options  []*OptionV2  `json:"options"`

	// Reservation state
	Reservation ReservationV2 `json:"reservation,omitempty"`

	// Flexible metadata (stored as JSON)
	Metadata Map `json:"metadata,omitempty"`

	// AI/ML fields
	EmbeddingVersion string    `json:"embeddingVersion,omitempty"`
	EmbeddingUpdated time.Time `json:"embeddingUpdated,omitempty"`

	// Collections and categories
	CollectionIDs []string `json:"collectionIds,omitempty"`
	Tags          []string `json:"tags,omitempty"`
	Categories    []string `json:"categories,omitempty"`

	// SEO fields
	SEOTitle       string `json:"seoTitle,omitempty"`
	SEODescription string `json:"seoDescription,omitempty"`
	SEOKeywords    string `json:"seoKeywords,omitempty"`
	// contains filtered or unexported fields
}

ProductV2 is the modernized product model using the new db.DB interface. It stores products in organization SQLite databases with JSON fields for flexible metadata and supports vector embeddings for AI recommendations.

func GetBySKUV2

func GetBySKUV2(ctx context.Context, database db.DB, sku string) (*ProductV2, error)

GetBySKUV2 retrieves a product by SKU

func GetBySlugV2

func GetBySlugV2(ctx context.Context, database db.DB, slug string) (*ProductV2, error)

GetBySlugV2 retrieves a product by slug

func GetMultiV2

func GetMultiV2(ctx context.Context, database db.DB, ids []string) ([]*ProductV2, error)

GetMultiV2 retrieves multiple products by ID

func GetV2

func GetV2(ctx context.Context, database db.DB, id string) (*ProductV2, error)

GetV2 retrieves a product by ID

func ListAvailableV2

func ListAvailableV2(ctx context.Context, database db.DB, orgID string, limit, offset int) ([]*ProductV2, error)

ListAvailableV2 retrieves all available products

func ListV2

func ListV2(ctx context.Context, database db.DB, orgID string, limit, offset int) ([]*ProductV2, error)

ListV2 retrieves all products for an organization

func MigrateFromV1

func MigrateFromV1(v1 *Product, database db.DB, orgID string) *ProductV2

MigrateFromV1 converts a v1 Product to v2 ProductV2 This is used during the migration process

func NewProductV2

func NewProductV2(database db.DB, orgID string) *ProductV2

NewProductV2 creates a new product instance bound to the given database

func NewV2

func NewV2(database db.DB, orgID string) *ProductV2

NewV2 creates a new product with the given database and organization ID

func SearchV2

func SearchV2(ctx context.Context, database db.DB, opts SearchV2Options) ([]*ProductV2, error)

SearchV2 performs a filtered search for products Note: Full-text search requires additional indexing setup

func SimilarProducts

func SimilarProducts(ctx context.Context, database db.DB, productID string, embedding []float32, limit int) ([]*ProductV2, error)

SimilarProducts finds products similar to the given product using vector search

func (*ProductV2) AddVariant

func (p *ProductV2) AddVariant(v *VariantV2)

AddVariant adds a new variant to the product

func (*ProductV2) AvailableVariants

func (p *ProductV2) AvailableVariants() []*VariantV2

AvailableVariants returns only variants that are available for purchase

func (*ProductV2) Clone

func (p *ProductV2) Clone() *ProductV2

Clone creates a deep copy of the product

func (*ProductV2) Create

func (p *ProductV2) Create(ctx context.Context) error

Create creates a new product (validates first)

func (*ProductV2) Delete

func (p *ProductV2) Delete(ctx context.Context) error

Delete soft-deletes the product

func (*ProductV2) DisplayImage

func (p *ProductV2) DisplayImage() Media

DisplayImage returns the first image media

func (*ProductV2) DisplayName

func (p *ProductV2) DisplayName() string

DisplayName returns a formatted display name

func (*ProductV2) DisplayPrice

func (p *ProductV2) DisplayPrice() string

DisplayPrice returns a formatted price string

func (*ProductV2) EmbeddingText

func (p *ProductV2) EmbeddingText() string

EmbeddingText generates text for creating AI embeddings

func (*ProductV2) FromJSON

func (p *ProductV2) FromJSON(data []byte) error

FromJSON populates the product from JSON

func (*ProductV2) Get

func (p *ProductV2) Get(ctx context.Context, key db.Key) error

Get retrieves a product by key

func (*ProductV2) GetByID

func (p *ProductV2) GetByID(ctx context.Context, id string) error

GetByID retrieves a product by its string ID

func (*ProductV2) GetBySKU

func (p *ProductV2) GetBySKU(ctx context.Context, sku string) error

GetBySKU retrieves a product by its SKU

func (*ProductV2) GetBySlug

func (p *ProductV2) GetBySlug(ctx context.Context, slug string) error

GetBySlug retrieves a product by its slug

func (*ProductV2) HardDelete

func (p *ProductV2) HardDelete(ctx context.Context) error

HardDelete permanently removes the product

func (*ProductV2) Key

func (p *ProductV2) Key() db.Key

Key returns the database key for this product

func (*ProductV2) Kind

func (p *ProductV2) Kind() string

Kind returns the entity kind for database operations

func (*ProductV2) MaxPrice

func (p *ProductV2) MaxPrice() currency.Cents

MaxPrice returns the highest variant price

func (*ProductV2) MinPrice

func (p *ProductV2) MinPrice() currency.Cents

MinPrice returns the lowest variant price

func (*ProductV2) PriceRange

func (p *ProductV2) PriceRange() (min, max currency.Cents)

PriceRange returns min and max prices

func (*ProductV2) ProductIndex

func (p *ProductV2) ProductIndex() map[string]interface{}

ProductIndex generates search index data for a product

func (*ProductV2) Put

func (p *ProductV2) Put(ctx context.Context) error

Put saves the product to the database

func (*ProductV2) PutEmbedding

func (p *ProductV2) PutEmbedding(ctx context.Context, vector []float32, version string) error

PutEmbedding stores a vector embedding for AI similarity search

func (*ProductV2) RemoveVariant

func (p *ProductV2) RemoveVariant(id string) bool

RemoveVariant removes a variant by ID

func (*ProductV2) SetKey

func (p *ProductV2) SetKey(key db.Key)

SetKey sets the key and ID for this product

func (*ProductV2) SyncToDatastore

func (p *ProductV2) SyncToDatastore() bool

SyncToDatastore returns true if this product should be synced to analytics

func (*ProductV2) ToJSON

func (p *ProductV2) ToJSON() []byte

ToJSON returns the JSON representation

func (*ProductV2) TotalInventory

func (p *ProductV2) TotalInventory() int

TotalInventory returns the sum of all variant inventories

func (*ProductV2) TotalSold

func (p *ProductV2) TotalSold() int

TotalSold returns the sum of all variant sales

func (*ProductV2) Update

func (p *ProductV2) Update(ctx context.Context) error

Update saves changes to an existing product

func (*ProductV2) Validate

func (p *ProductV2) Validate() error

Validate checks all required fields and returns an error if invalid

func (*ProductV2) Validator

func (p *ProductV2) Validator() *val.Validator

Validator returns a validator for product fields

func (*ProductV2) VariantByID

func (p *ProductV2) VariantByID(id string) *VariantV2

VariantByID finds a variant by its ID

func (*ProductV2) VariantBySKU

func (p *ProductV2) VariantBySKU(sku string) *VariantV2

VariantBySKU finds a variant by its SKU

func (*ProductV2) VariantOptions

func (p *ProductV2) VariantOptions(optionName string) []string

VariantOptions returns unique values for a given option name across all variants

func (*ProductV2) VariantOptionsDeprecated

func (p *ProductV2) VariantOptionsDeprecated(name string) (options []string)

VariantOptionsDeprecated returns unique option values by field name using reflection Deprecated: Use VariantOptions instead

type Reservation

type Reservation struct {
	// Is the product reservable?
	IsReservable bool `json:"isReservable"`

	// Set to true if being reserved
	IsBeingReserved bool `json:"isBeingReserved"`

	// Usually initials of reserver
	ReservedBy string `json:"reservedBy"`

	// OrderID of Reservation
	OrderId string `json:"orderId"`

	// When was the product reserved
	ReservedAt time.Time `json:"ReservedAt"`
}

type ReservationV2

type ReservationV2 struct {
	// IsReservable indicates if the product can be reserved
	IsReservable bool `json:"isReservable"`
	// IsBeingReserved indicates if currently reserved
	IsBeingReserved bool `json:"isBeingReserved"`
	// ReservedBy is usually the initials or ID of the reserver
	ReservedBy string `json:"reservedBy,omitempty"`
	// OrderId is the order ID associated with the reservation
	OrderId string `json:"orderId,omitempty"`
	// ReservedAt is when the product was reserved
	ReservedAt time.Time `json:"reservedAt,omitempty"`
}

ReservationV2 represents product reservation state

type SearchV2Options

type SearchV2Options struct {
	OrgID       string
	Query       string   // Text search query
	Collections []string // Filter by collection IDs
	Tags        []string // Filter by tags
	Categories  []string // Filter by categories
	MinPrice    currency.Cents
	MaxPrice    currency.Cents
	Available   *bool
	Hidden      *bool
	Limit       int
	Offset      int
	SortBy      string // Field to sort by
	SortDesc    bool   // Sort descending
}

SearchV2Options configures product search

type VariantOption

type VariantOption struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

VariantOption represents a selected option value for a variant

type VariantV2

type VariantV2 struct {
	// ID is the unique variant identifier
	ID string `json:"id"`
	// ProductId links back to the parent product
	ProductId string `json:"productId"`
	// SKU is the stock keeping unit
	SKU string `json:"sku"`
	// UPC is the universal product code
	UPC string `json:"upc,omitempty"`
	// Name is the variant name
	Name string `json:"name"`
	// Price in cents
	Price currency.Cents `json:"price"`
	// ListPrice is the original/list price
	ListPrice currency.Cents `json:"listPrice,omitempty"`
	// Available indicates if this variant is available for purchase
	Available bool `json:"available"`
	// Inventory count
	Inventory int `json:"inventory"`
	// Sold count
	Sold int `json:"sold"`
	// Options are the selected option values for this variant
	Options []VariantOption `json:"options"`
	// Media for this variant
	Header Media   `json:"header,omitempty"`
	Image  Media   `json:"image,omitempty"`
	Media  []Media `json:"media,omitempty"`
	// Weight for shipping calculations
	Weight WeightV2 `json:"weight,omitempty"`
}

VariantV2 represents a product variant with its own SKU and pricing

type WeightV2

type WeightV2 struct {
	Value float64  `json:"value"`
	Unit  MassUnit `json:"unit"`
}

WeightV2 represents product weight for shipping calculations

Jump to

Keyboard shortcuts

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