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 // 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) return &Facade{ UserController: userController, ProductController: productController, OrderController: orderController, DeliveriesController: deliveriesController, UtilsController: utilsController, TenantController: tenantController, PartnerController: partnerController, CustomerController: customerController, StockRequestController: stockRequestController, CatalogueController: catalogueController, PosController: posController, 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 }