Bridge global catalogue DB to per-store product catalogue

Adds a separate CatalogueDB (pgvector) connection alongside the main
nearledb, plus a new catalogue module (repository/service/controller/
routes) to browse it by brand, category, and keyword, with brand
optional so the whole ~237-product catalogue can be browsed unfiltered.

Adds the actual bridge: importing a catalogue product snapshots it into
the tenant's own products table (keyed on brand+catalogueid, since a
catalogue row's bare id is only unique within its own brand table),
then links it via the existing productlocations upsert. Re-importing
tops up stock and refreshes price instead of duplicating. Also adds an
imported-refs endpoint so the frontend can badge already-imported items
without diffing full product lists, and wires the new AWS S3 image
store used to resolve catalogue product photos.

Bumps Go/Docker to 1.24 for the AWS SDK dependency this needs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Suriya
2026-07-16 17:34:20 +05:30
parent 950064de6c
commit fab06bb33e
20 changed files with 1408 additions and 15 deletions

View File

@@ -256,6 +256,33 @@ type Subcategory struct {
Image string `json:"image" gorm:"column:image"`
}
// ImportedCatalogueRef identifies a catalogue product a tenant has already
// imported. Brand is always included, even when a caller filtered by a
// single brand, because a bare catalogueid is ambiguous across brand tables.
type ImportedCatalogueRef struct {
Brand string `json:"brand"`
Catalogueid int64 `json:"catalogueid"`
}
// ImportCatalogueProductRequest is the payload for importing a product from
// the global catalogue (CatalogueDB) into a tenant's own store catalogue.
// Brand+Catalogueid is the bridge key back to CatalogueDB: a catalogue row's
// bare id is only unique within its brand table, so both are required.
type ImportCatalogueProductRequest struct {
Tenantid int `json:"tenantid"`
Locationid int `json:"locationid"`
Brand string `json:"brand"`
Catalogueid int64 `json:"catalogueid"`
Categoryid int `json:"categoryid"`
Subcategoryid int `json:"subcategoryid"`
Quantity int `json:"quantity"`
Stocktype string `json:"stocktype"`
Status string `json:"status"`
Retailprice float64 `json:"retailprice"`
Productcost float64 `json:"productcost"`
Taxpercent float64 `json:"taxpercent"`
}
type Productlocations struct {
Productlocationid int `json:"productlocationid" gorm:"Primary_Key"`
Tenantid int `json:"tenantid"`