Files
backend_fiesta/facade/container.go
2026-08-31 12:33:10 +05:30

134 lines
5.8 KiB
Go

package facade
import (
"nearle/controllers"
"nearle/repositories"
"nearle/services"
"gorm.io/gorm"
)
type Facade struct {
UserController *controllers.UserController
ProductController *controllers.ProductController
OrderController *controllers.OrderController
DeliveriesController *controllers.DeliveriesController
UtilsController *controllers.UtilsController
TenantController *controllers.TenantController
PartnerController *controllers.PartnerController
CustomerController *controllers.CustomerController
StockRequestController *controllers.StockRequestController
CatalogueController *controllers.CatalogueController
PosController *controllers.PosController
LiveController *controllers.LiveController
CatalogueUploadController *controllers.CatalogueUploadController
// Held so the NATS consumer can reach the ingest without going through
// HTTP. Unexported: everything else should use the controller.
posService services.PosService
}
// 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, catalogueService)
productController := controllers.NewProductController(productService)
// Order Module
orderRepo := repositories.NewOrderRepository(db)
orderService := services.NewOrderService(orderRepo)
orderController := controllers.NewOrderController(orderService)
// Deliveries Module
deliveriesRepo := repositories.NewDeliveriesRepository(db)
deliveriesService := services.NewDeliveriesService(deliveriesRepo)
deliveriesController := controllers.NewDeliveriesController(deliveriesService)
// Utils Module
utilsRepo := repositories.NewUtilsRepository(db)
utilsService := services.NewUtilsService(utilsRepo)
utilsController := controllers.NewUtilsController(utilsService)
//Tenant Module
tenantRepo := repositories.NewTenantRepository(db)
tenantService := services.NewTenantService(tenantRepo)
tenantController := controllers.NewTenantController(tenantService)
//Partner Module
partnerRepo := repositories.NewPartnerRepository(db)
partnerService := services.NewPartnerService(partnerRepo)
partnerController := controllers.NewPartnerController(partnerService)
//Customer Module
customerRepo := repositories.NewCustomerRepository(db)
customerService := services.NewCustomerService(customerRepo)
customerController := controllers.NewCustomerController(customerService)
// Stock Request Module
stockRequestRepo := repositories.NewStockRequestRepository(db)
stockRequestService := services.NewStockRequestService(stockRequestRepo, productService)
stockRequestController := controllers.NewStockRequestController(stockRequestService)
// POS Module — ingest from the in-store terminals.
//
// Presence has no *gorm.DB: terminal health lives in Redis under a TTL, so
// a till that loses power ages out of the board by itself instead of
// leaving a Postgres row claiming it is online.
posRepo := repositories.NewPosRepository(db)
posPresence := repositories.NewPosPresenceRepository()
posService := services.NewPosService(posRepo, posPresence)
posController := controllers.NewPosController(posService)
// Shares the POS service purely for its outlet-ownership check — the
// stream itself reads no database and holds no state beyond its
// subscribers.
liveController := controllers.NewLiveController(posService)
// Catalogue Upload Module — our own receipt for every spreadsheet sent to
// the ingest service. Their host deletes an unreviewed drop after seven
// days and the batch id is the only credential for reading the result
// back, so the id has to be kept somewhere that outlives a browser tab.
catalogueUploadRepo := repositories.NewCatalogueUploadRepository(db)
catalogueUploadService := services.NewCatalogueUploadService(catalogueUploadRepo)
catalogueUploadController := controllers.NewCatalogueUploadController(catalogueUploadService)
return &Facade{
UserController: userController,
ProductController: productController,
OrderController: orderController,
DeliveriesController: deliveriesController,
UtilsController: utilsController,
TenantController: tenantController,
PartnerController: partnerController,
CustomerController: customerController,
StockRequestController: stockRequestController,
CatalogueController: catalogueController,
PosController: posController,
LiveController: liveController,
CatalogueUploadController: catalogueUploadController,
posService: posService,
}
}
// PosService exposes the ingest to callers outside the HTTP layer — the NATS
// consumer runs the same code path a POST does, so a bill arriving over MQTT
// and one arriving over HTTP cannot diverge.
func (f *Facade) PosService() services.PosService { return f.posService }