2025-07-18 20:10:29 +07:00
|
|
|
package router
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"apskel-pos-be/config"
|
|
|
|
|
"apskel-pos-be/internal/handler"
|
|
|
|
|
"apskel-pos-be/internal/middleware"
|
|
|
|
|
"apskel-pos-be/internal/service"
|
|
|
|
|
"apskel-pos-be/internal/transformer"
|
|
|
|
|
"apskel-pos-be/internal/validator"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Router struct {
|
|
|
|
|
config *config.Config
|
|
|
|
|
healthHandler *handler.HealthHandler
|
|
|
|
|
authHandler *handler.AuthHandler
|
|
|
|
|
userHandler *handler.UserHandler
|
|
|
|
|
organizationHandler *handler.OrganizationHandler
|
|
|
|
|
outletHandler *handler.OutletHandler
|
|
|
|
|
outletSettingHandler *handler.OutletSettingHandlerImpl
|
|
|
|
|
categoryHandler *handler.CategoryHandler
|
|
|
|
|
productHandler *handler.ProductHandler
|
|
|
|
|
productVariantHandler *handler.ProductVariantHandler
|
|
|
|
|
inventoryHandler *handler.InventoryHandler
|
|
|
|
|
orderHandler *handler.OrderHandler
|
|
|
|
|
fileHandler *handler.FileHandler
|
|
|
|
|
customerHandler *handler.CustomerHandler
|
|
|
|
|
paymentMethodHandler *handler.PaymentMethodHandler
|
|
|
|
|
analyticsHandler *handler.AnalyticsHandler
|
2025-08-10 20:41:34 +07:00
|
|
|
reportHandler *handler.ReportHandler
|
2025-07-30 23:18:20 +07:00
|
|
|
tableHandler *handler.TableHandler
|
2025-08-03 23:55:51 +07:00
|
|
|
unitHandler *handler.UnitHandler
|
|
|
|
|
ingredientHandler *handler.IngredientHandler
|
2025-08-10 21:46:44 +07:00
|
|
|
productRecipeHandler *handler.ProductRecipeHandler
|
2025-07-18 20:10:29 +07:00
|
|
|
authMiddleware *middleware.AuthMiddleware
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewRouter(cfg *config.Config,
|
|
|
|
|
healthHandler *handler.HealthHandler,
|
|
|
|
|
authService service.AuthService,
|
|
|
|
|
authMiddleware *middleware.AuthMiddleware,
|
|
|
|
|
userService *service.UserServiceImpl,
|
|
|
|
|
userValidator *validator.UserValidatorImpl,
|
|
|
|
|
organizationService service.OrganizationService,
|
|
|
|
|
organizationValidator validator.OrganizationValidator,
|
|
|
|
|
outletService service.OutletService,
|
|
|
|
|
outletValidator validator.OutletValidator,
|
|
|
|
|
outletSettingService service.OutletSettingService,
|
|
|
|
|
categoryService service.CategoryService,
|
|
|
|
|
categoryValidator validator.CategoryValidator,
|
|
|
|
|
productService service.ProductService,
|
|
|
|
|
productValidator validator.ProductValidator,
|
|
|
|
|
productVariantService service.ProductVariantService,
|
|
|
|
|
productVariantValidator validator.ProductVariantValidator,
|
|
|
|
|
inventoryService service.InventoryService,
|
|
|
|
|
inventoryValidator validator.InventoryValidator,
|
|
|
|
|
orderService service.OrderService,
|
|
|
|
|
orderValidator validator.OrderValidator,
|
|
|
|
|
fileService service.FileService,
|
|
|
|
|
fileValidator validator.FileValidator,
|
|
|
|
|
customerService service.CustomerService,
|
|
|
|
|
customerValidator validator.CustomerValidator,
|
|
|
|
|
paymentMethodService service.PaymentMethodService,
|
|
|
|
|
paymentMethodValidator validator.PaymentMethodValidator,
|
2025-07-30 23:18:20 +07:00
|
|
|
analyticsService *service.AnalyticsServiceImpl,
|
2025-08-10 20:41:34 +07:00
|
|
|
reportService service.ReportService,
|
2025-08-03 00:34:25 +07:00
|
|
|
tableService *service.TableServiceImpl,
|
2025-08-03 23:55:51 +07:00
|
|
|
tableValidator *validator.TableValidator,
|
|
|
|
|
unitService handler.UnitService,
|
2025-08-10 21:46:44 +07:00
|
|
|
ingredientService handler.IngredientService,
|
|
|
|
|
productRecipeService service.ProductRecipeService) *Router {
|
2025-07-18 20:10:29 +07:00
|
|
|
|
|
|
|
|
return &Router{
|
|
|
|
|
config: cfg,
|
|
|
|
|
healthHandler: healthHandler,
|
|
|
|
|
authHandler: handler.NewAuthHandler(authService),
|
|
|
|
|
userHandler: handler.NewUserHandler(userService, userValidator),
|
|
|
|
|
organizationHandler: handler.NewOrganizationHandler(organizationService, organizationValidator),
|
|
|
|
|
outletHandler: handler.NewOutletHandler(outletService, outletValidator),
|
|
|
|
|
outletSettingHandler: handler.NewOutletSettingHandlerImpl(outletSettingService),
|
|
|
|
|
categoryHandler: handler.NewCategoryHandler(categoryService, categoryValidator),
|
|
|
|
|
productHandler: handler.NewProductHandler(productService, productValidator),
|
|
|
|
|
inventoryHandler: handler.NewInventoryHandler(inventoryService, inventoryValidator),
|
|
|
|
|
orderHandler: handler.NewOrderHandler(orderService, orderValidator, transformer.NewTransformer()),
|
|
|
|
|
fileHandler: handler.NewFileHandler(fileService, fileValidator, transformer.NewTransformer()),
|
|
|
|
|
customerHandler: handler.NewCustomerHandler(customerService, customerValidator),
|
|
|
|
|
paymentMethodHandler: handler.NewPaymentMethodHandler(paymentMethodService, paymentMethodValidator),
|
|
|
|
|
analyticsHandler: handler.NewAnalyticsHandler(analyticsService, transformer.NewTransformer()),
|
2025-08-10 20:41:34 +07:00
|
|
|
reportHandler: handler.NewReportHandler(reportService, userService),
|
2025-08-03 00:34:25 +07:00
|
|
|
tableHandler: handler.NewTableHandler(tableService, tableValidator),
|
2025-08-03 23:55:51 +07:00
|
|
|
unitHandler: handler.NewUnitHandler(unitService),
|
|
|
|
|
ingredientHandler: handler.NewIngredientHandler(ingredientService),
|
2025-08-10 21:46:44 +07:00
|
|
|
productRecipeHandler: handler.NewProductRecipeHandler(productRecipeService),
|
2025-07-18 20:10:29 +07:00
|
|
|
authMiddleware: authMiddleware,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *Router) Init() *gin.Engine {
|
|
|
|
|
gin.SetMode(gin.ReleaseMode)
|
|
|
|
|
engine := gin.New()
|
|
|
|
|
engine.Use(
|
|
|
|
|
middleware.JsonAPI(),
|
|
|
|
|
middleware.CorrelationID(),
|
|
|
|
|
middleware.Recover(),
|
|
|
|
|
middleware.HTTPStatLogger(),
|
|
|
|
|
middleware.PopulateContext(),
|
2025-08-13 23:14:26 +07:00
|
|
|
middleware.CORS(),
|
2025-07-18 20:10:29 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
r.addAppRoutes(engine)
|
|
|
|
|
return engine
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *Router) addAppRoutes(rg *gin.Engine) {
|
|
|
|
|
rg.GET("/health", r.healthHandler.HealthCheck)
|
|
|
|
|
|
|
|
|
|
v1 := rg.Group("/api/v1")
|
|
|
|
|
{
|
|
|
|
|
auth := v1.Group("/auth")
|
|
|
|
|
{
|
|
|
|
|
auth.POST("/login", r.authHandler.Login)
|
|
|
|
|
auth.POST("/logout", r.authHandler.Logout)
|
|
|
|
|
auth.POST("/refresh", r.authHandler.RefreshToken)
|
|
|
|
|
auth.GET("/validate", r.authHandler.ValidateToken)
|
|
|
|
|
auth.GET("/profile", r.authHandler.GetProfile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
organizations := v1.Group("/organizations")
|
|
|
|
|
{
|
|
|
|
|
organizations.POST("", r.organizationHandler.CreateOrganization)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected := v1.Group("")
|
|
|
|
|
protected.Use(r.authMiddleware.RequireAuth())
|
|
|
|
|
{
|
|
|
|
|
users := protected.Group("/users")
|
|
|
|
|
{
|
|
|
|
|
adminUsers := users.Group("")
|
|
|
|
|
adminUsers.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
adminUsers.POST("", r.userHandler.CreateUser)
|
|
|
|
|
adminUsers.GET("", r.userHandler.ListUsers)
|
|
|
|
|
adminUsers.GET("/:id", r.userHandler.GetUser)
|
|
|
|
|
adminUsers.PUT("/:id", r.userHandler.UpdateUser)
|
|
|
|
|
adminUsers.DELETE("/:id", r.userHandler.DeleteUser)
|
|
|
|
|
adminUsers.PUT("/:id/activate", r.userHandler.ActivateUser)
|
|
|
|
|
adminUsers.PUT("/:id/deactivate", r.userHandler.DeactivateUser)
|
2025-08-03 23:55:51 +07:00
|
|
|
adminUsers.POST("/select-outlet", r.userHandler.UpdateUserOutlet)
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
users.PUT("/:id/password", r.userHandler.ChangePassword)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protectedOrganizations := protected.Group("/organizations")
|
|
|
|
|
{
|
|
|
|
|
adminOrgRoutes := protectedOrganizations.Group("")
|
|
|
|
|
adminOrgRoutes.Use(r.authMiddleware.RequireSuperAdmin())
|
|
|
|
|
{
|
|
|
|
|
adminOrgRoutes.GET("", r.organizationHandler.ListOrganizations)
|
|
|
|
|
adminOrgRoutes.GET("/:id", r.organizationHandler.GetOrganization)
|
|
|
|
|
adminOrgRoutes.PUT("/:id", r.organizationHandler.UpdateOrganization)
|
|
|
|
|
adminOrgRoutes.DELETE("/:id", r.organizationHandler.DeleteOrganization)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
categories := protected.Group("/categories")
|
|
|
|
|
categories.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
categories.POST("", r.categoryHandler.CreateCategory)
|
|
|
|
|
categories.GET("", r.categoryHandler.ListCategories)
|
|
|
|
|
categories.GET("/:id", r.categoryHandler.GetCategory)
|
|
|
|
|
categories.PUT("/:id", r.categoryHandler.UpdateCategory)
|
|
|
|
|
categories.DELETE("/:id", r.categoryHandler.DeleteCategory)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 23:55:51 +07:00
|
|
|
units := protected.Group("/units")
|
|
|
|
|
units.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
units.POST("", r.unitHandler.Create)
|
|
|
|
|
units.GET("", r.unitHandler.GetAll)
|
|
|
|
|
units.GET("/:id", r.unitHandler.GetByID)
|
|
|
|
|
units.PUT("/:id", r.unitHandler.Update)
|
|
|
|
|
units.DELETE("/:id", r.unitHandler.Delete)
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-18 20:10:29 +07:00
|
|
|
products := protected.Group("/products")
|
|
|
|
|
products.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
products.POST("", r.productHandler.CreateProduct)
|
|
|
|
|
products.GET("", r.productHandler.ListProducts)
|
|
|
|
|
products.GET("/:id", r.productHandler.GetProduct)
|
|
|
|
|
products.PUT("/:id", r.productHandler.UpdateProduct)
|
|
|
|
|
products.DELETE("/:id", r.productHandler.DeleteProduct)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inventory := protected.Group("/inventory")
|
|
|
|
|
inventory.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
inventory.POST("", r.inventoryHandler.CreateInventory)
|
|
|
|
|
inventory.GET("", r.inventoryHandler.ListInventory)
|
|
|
|
|
inventory.GET("/:id", r.inventoryHandler.GetInventory)
|
|
|
|
|
inventory.PUT("/:id", r.inventoryHandler.UpdateInventory)
|
|
|
|
|
inventory.DELETE("/:id", r.inventoryHandler.DeleteInventory)
|
|
|
|
|
inventory.POST("/adjust", r.inventoryHandler.AdjustInventory)
|
2025-08-14 01:35:19 +07:00
|
|
|
inventory.POST("/restock", r.inventoryHandler.RestockInventory)
|
2025-07-18 20:10:29 +07:00
|
|
|
inventory.GET("/low-stock/:outlet_id", r.inventoryHandler.GetLowStockItems)
|
|
|
|
|
inventory.GET("/zero-stock/:outlet_id", r.inventoryHandler.GetZeroStockItems)
|
2025-08-13 23:36:31 +07:00
|
|
|
inventory.GET("/report/summary/:outlet_id", r.inventoryHandler.GetInventoryReportSummary)
|
2025-08-14 00:38:26 +07:00
|
|
|
inventory.GET("/report/details/:outlet_id", r.inventoryHandler.GetInventoryReportDetails)
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orders := protected.Group("/orders")
|
|
|
|
|
orders.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
orders.GET("", r.orderHandler.ListOrders)
|
|
|
|
|
orders.GET("/:id", r.orderHandler.GetOrderByID)
|
|
|
|
|
orders.POST("", r.orderHandler.CreateOrder)
|
|
|
|
|
orders.POST("/:id/add-items", r.orderHandler.AddToOrder)
|
|
|
|
|
orders.PUT("/:id", r.orderHandler.UpdateOrder)
|
|
|
|
|
orders.PUT("/:id/customer", r.orderHandler.SetOrderCustomer)
|
|
|
|
|
orders.POST("/void", r.orderHandler.VoidOrder)
|
|
|
|
|
orders.POST("/:id/refund", r.orderHandler.RefundOrder)
|
2025-08-07 22:45:02 +07:00
|
|
|
orders.POST("/split-bill", r.orderHandler.SplitBill)
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
payments := protected.Group("/payments")
|
|
|
|
|
payments.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
payments.POST("", r.orderHandler.CreatePayment)
|
|
|
|
|
payments.POST("/:id/refund", r.orderHandler.RefundPayment)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paymentMethods := protected.Group("/payment-methods")
|
|
|
|
|
paymentMethods.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
paymentMethods.POST("", r.paymentMethodHandler.CreatePaymentMethod)
|
|
|
|
|
paymentMethods.GET("", r.paymentMethodHandler.ListPaymentMethods)
|
|
|
|
|
paymentMethods.GET("/:id", r.paymentMethodHandler.GetPaymentMethod)
|
|
|
|
|
paymentMethods.PUT("/:id", r.paymentMethodHandler.UpdatePaymentMethod)
|
|
|
|
|
paymentMethods.DELETE("/:id", r.paymentMethodHandler.DeletePaymentMethod)
|
|
|
|
|
paymentMethods.GET("/organization/:organization_id/active", r.paymentMethodHandler.GetActivePaymentMethodsByOrganization)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
files := protected.Group("/files")
|
|
|
|
|
files.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
files.GET("/organization", r.fileHandler.GetFilesByOrganization)
|
|
|
|
|
files.GET("/user", r.fileHandler.GetFilesByUser)
|
|
|
|
|
files.GET("/:id", r.fileHandler.GetFileByID)
|
|
|
|
|
files.POST("/upload", r.fileHandler.UploadFile)
|
|
|
|
|
files.PUT("/:id", r.fileHandler.UpdateFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
customers := protected.Group("/customers")
|
|
|
|
|
customers.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
customers.POST("", r.customerHandler.CreateCustomer)
|
|
|
|
|
customers.GET("", r.customerHandler.ListCustomers)
|
|
|
|
|
customers.GET("/:id", r.customerHandler.GetCustomer)
|
|
|
|
|
customers.PUT("/:id", r.customerHandler.UpdateCustomer)
|
|
|
|
|
customers.DELETE("/:id", r.customerHandler.DeleteCustomer)
|
|
|
|
|
customers.POST("/set-default", r.customerHandler.SetDefaultCustomer)
|
|
|
|
|
customers.GET("/default", r.customerHandler.GetDefaultCustomer)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
analytics := protected.Group("/analytics")
|
|
|
|
|
analytics.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
analytics.GET("/payment-methods", r.analyticsHandler.GetPaymentMethodAnalytics)
|
|
|
|
|
analytics.GET("/sales", r.analyticsHandler.GetSalesAnalytics)
|
|
|
|
|
analytics.GET("/products", r.analyticsHandler.GetProductAnalytics)
|
2025-08-14 00:45:14 +07:00
|
|
|
analytics.GET("/categories", r.analyticsHandler.GetProductAnalyticsPerCategory)
|
2025-07-18 20:10:29 +07:00
|
|
|
analytics.GET("/dashboard", r.analyticsHandler.GetDashboardAnalytics)
|
|
|
|
|
analytics.GET("/profit-loss", r.analyticsHandler.GetProfitLossAnalytics)
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-30 23:18:20 +07:00
|
|
|
tables := protected.Group("/tables")
|
|
|
|
|
tables.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
tables.POST("", r.tableHandler.Create)
|
|
|
|
|
tables.GET("", r.tableHandler.List)
|
|
|
|
|
tables.GET("/:id", r.tableHandler.GetByID)
|
|
|
|
|
tables.PUT("/:id", r.tableHandler.Update)
|
|
|
|
|
tables.DELETE("/:id", r.tableHandler.Delete)
|
|
|
|
|
tables.POST("/:id/occupy", r.tableHandler.OccupyTable)
|
|
|
|
|
tables.POST("/:id/release", r.tableHandler.ReleaseTable)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 23:55:51 +07:00
|
|
|
ingredients := protected.Group("/ingredients")
|
|
|
|
|
ingredients.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
ingredients.POST("", r.ingredientHandler.Create)
|
|
|
|
|
ingredients.GET("", r.ingredientHandler.GetAll)
|
|
|
|
|
ingredients.GET("/:id", r.ingredientHandler.GetByID)
|
|
|
|
|
ingredients.PUT("/:id", r.ingredientHandler.Update)
|
|
|
|
|
ingredients.DELETE("/:id", r.ingredientHandler.Delete)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-10 21:46:44 +07:00
|
|
|
productRecipes := protected.Group("/product-recipes")
|
|
|
|
|
productRecipes.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
productRecipes.POST("", r.productRecipeHandler.Create)
|
|
|
|
|
productRecipes.POST("/bulk", r.productRecipeHandler.BulkCreate)
|
|
|
|
|
productRecipes.GET("/:id", r.productRecipeHandler.GetByID)
|
|
|
|
|
productRecipes.PUT("/:id", r.productRecipeHandler.Update)
|
|
|
|
|
productRecipes.DELETE("/:id", r.productRecipeHandler.Delete)
|
|
|
|
|
productRecipes.GET("/product/:product_id", r.productRecipeHandler.GetByProductID)
|
|
|
|
|
productRecipes.GET("/ingredient/:ingredient_id", r.productRecipeHandler.GetByIngredientID)
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-30 23:18:20 +07:00
|
|
|
outlets := protected.Group("/outlets")
|
|
|
|
|
outlets.Use(r.authMiddleware.RequireAdminOrManager())
|
|
|
|
|
{
|
|
|
|
|
outlets.GET("/list", r.outletHandler.ListOutlets)
|
2025-08-03 00:34:25 +07:00
|
|
|
outlets.GET("/detail/:id", r.outletHandler.GetOutlet)
|
|
|
|
|
outlets.PUT("/detail/:id", r.outletHandler.UpdateOutlet)
|
2025-07-30 23:18:20 +07:00
|
|
|
outlets.GET("/printer-setting/:outlet_id", r.outletSettingHandler.GetPrinterSettings)
|
|
|
|
|
outlets.PUT("/printer-setting/:outlet_id", r.outletSettingHandler.UpdatePrinterSettings)
|
|
|
|
|
outlets.GET("/:outlet_id/tables/available", r.tableHandler.GetAvailableTables)
|
|
|
|
|
outlets.GET("/:outlet_id/tables/occupied", r.tableHandler.GetOccupiedTables)
|
2025-08-10 20:41:34 +07:00
|
|
|
// Reports
|
|
|
|
|
outlets.GET("/:outlet_id/reports/daily-transaction.pdf", r.reportHandler.GetDailyTransactionReportPDF)
|
2025-07-30 23:18:20 +07:00
|
|
|
}
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|