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

@@ -18,18 +18,30 @@ type Facade struct {
PartnerController *controllers.PartnerController
CustomerController *controllers.CustomerController
StockRequestController *controllers.StockRequestController
CatalogueController *controllers.CatalogueController
}
func NewFacade(db *gorm.DB) *Facade {
// NewFacade wires up modules against the main (nearledb) connection.
// catalogueDB is a separate connection to the pgvector catalogue database;
// it may be nil if catalogue env vars are not configured, in which case
// catalogue endpoints will error at query time rather than at startup.
func NewFacade(db *gorm.DB, catalogueDB *gorm.DB) *Facade {
// User Module
userRepo := repositories.NewUserRepository(db)
userService := services.NewUserService(userRepo)
userController := controllers.NewUserController(userService)
// Catalogue Module (separate pgvector DB — never the main `db`). Built
// before the Product Module because ProductService depends on it to
// bridge catalogue imports into a tenant's own product catalogue.
catalogueRepo := repositories.NewCatalogueRepository(catalogueDB)
catalogueService := services.NewCatalogueService(catalogueRepo)
catalogueController := controllers.NewCatalogueController(catalogueService)
// Product Module
productRepo := repositories.NewProductRepository(db)
productService := services.NewProductService(productRepo)
productService := services.NewProductService(productRepo, catalogueService)
productController := controllers.NewProductController(productService)
// Order Module
@@ -77,5 +89,6 @@ func NewFacade(db *gorm.DB) *Facade {
PartnerController: partnerController,
CustomerController: customerController,
StockRequestController: stockRequestController,
CatalogueController: catalogueController,
}
}