Files

682 lines
38 KiB
Go
Raw Permalink Normal View History

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"
"github.com/redis/go-redis/v9"
2025-07-18 20:10:29 +07:00
)
type Router struct {
2025-09-12 15:37:19 +07:00
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
reportHandler *handler.ReportHandler
tableHandler *handler.TableHandler
unitHandler *handler.UnitHandler
ingredientHandler *handler.IngredientHandler
productRecipeHandler *handler.ProductRecipeHandler
vendorHandler *handler.VendorHandler
purchaseOrderHandler *handler.PurchaseOrderHandler
2026-06-08 12:29:59 +07:00
purchaseCategoryHandler *handler.PurchaseCategoryHandler
2025-09-12 15:37:19 +07:00
unitConverterHandler *handler.IngredientUnitConverterHandler
chartOfAccountTypeHandler *handler.ChartOfAccountTypeHandler
chartOfAccountHandler *handler.ChartOfAccountHandler
accountHandler *handler.AccountHandler
orderIngredientTransactionHandler *handler.OrderIngredientTransactionHandler
2025-09-17 19:30:17 +07:00
gamificationHandler *handler.GamificationHandler
2025-09-17 23:55:11 +07:00
rewardHandler *handler.RewardHandler
campaignHandler *handler.CampaignHandler
2025-09-18 01:32:01 +07:00
customerAuthHandler *handler.CustomerAuthHandler
2025-09-18 02:01:50 +07:00
customerPointsHandler *handler.CustomerPointsHandler
2025-09-18 13:39:37 +07:00
spinGameHandler *handler.SpinGameHandler
2026-05-10 10:42:09 +07:00
userDeviceHandler *handler.UserDeviceHandler
2026-05-10 10:57:38 +07:00
notificationHandler *handler.NotificationHandler
2026-05-05 21:07:03 +07:00
selfOrderHandler *handler.SelfOrderHandler
2026-05-13 21:58:54 +07:00
productOutletPriceHandler *handler.ProductOutletPriceHandler
2026-05-25 14:59:40 +07:00
expenseHandler *handler.ExpenseHandler
2026-08-13 14:38:28 +07:00
cashAdvanceHandler *handler.CashAdvanceHandler
2025-09-12 15:37:19 +07:00
authMiddleware *middleware.AuthMiddleware
2025-09-18 02:01:50 +07:00
customerAuthMiddleware *middleware.CustomerAuthMiddleware
redisClient *redis.Client
2025-07-18 20:10:29 +07:00
}
2026-08-13 14:38:28 +07:00
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, analyticsService *service.AnalyticsServiceImpl, reportService service.ReportService, tableService *service.TableServiceImpl, tableValidator *validator.TableValidator, unitService handler.UnitService, ingredientService handler.IngredientService, productRecipeService service.ProductRecipeService, vendorService service.VendorService, vendorValidator validator.VendorValidator, purchaseOrderService service.PurchaseOrderService, purchaseOrderValidator validator.PurchaseOrderValidator, purchaseCategoryService service.PurchaseCategoryService, purchaseCategoryValidator validator.PurchaseCategoryValidator, unitConverterService service.IngredientUnitConverterService, unitConverterValidator validator.IngredientUnitConverterValidator, chartOfAccountTypeService service.ChartOfAccountTypeService, chartOfAccountTypeValidator validator.ChartOfAccountTypeValidator, chartOfAccountService service.ChartOfAccountService, chartOfAccountValidator validator.ChartOfAccountValidator, accountService service.AccountService, accountValidator validator.AccountValidator, orderIngredientTransactionService service.OrderIngredientTransactionService, orderIngredientTransactionValidator validator.OrderIngredientTransactionValidator, gamificationService service.GamificationService, gamificationValidator validator.GamificationValidator, rewardService service.RewardService, rewardValidator validator.RewardValidator, campaignService service.CampaignService, campaignValidator validator.CampaignValidator, customerAuthService service.CustomerAuthService, customerAuthValidator validator.CustomerAuthValidator, customerPointsService service.CustomerPointsService, spinGameService service.SpinGameService, customerAuthMiddleware *middleware.CustomerAuthMiddleware, userDeviceService service.UserDeviceService, userDeviceValidator validator.UserDeviceValidator, notificationService service.NotificationService, notificationValidator validator.NotificationValidator, productOutletPriceService service.ProductOutletPriceService, productOutletPriceValidator validator.ProductOutletPriceValidator, selfOrderHandler *handler.SelfOrderHandler, expenseService *service.ExpenseServiceImpl, expenseValidator *validator.ExpenseValidatorImpl, cashAdvanceService service.CashAdvanceService, cashAdvanceValidator validator.CashAdvanceValidator, redisClient *redis.Client) *Router {
2025-07-18 20:10:29 +07:00
return &Router{
2025-09-12 15:37:19 +07:00
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()),
reportHandler: handler.NewReportHandler(reportService, userService),
2026-05-10 14:13:20 +07:00
tableHandler: handler.NewTableHandler(tableService, tableValidator, cfg.Server.SelfOrderUrl),
2025-09-12 15:37:19 +07:00
unitHandler: handler.NewUnitHandler(unitService),
ingredientHandler: handler.NewIngredientHandler(ingredientService),
productRecipeHandler: handler.NewProductRecipeHandler(productRecipeService),
vendorHandler: handler.NewVendorHandler(vendorService, vendorValidator),
purchaseOrderHandler: handler.NewPurchaseOrderHandler(purchaseOrderService, purchaseOrderValidator),
2026-06-08 12:29:59 +07:00
purchaseCategoryHandler: handler.NewPurchaseCategoryHandler(purchaseCategoryService, purchaseCategoryValidator),
2025-09-12 15:37:19 +07:00
unitConverterHandler: handler.NewIngredientUnitConverterHandler(unitConverterService, unitConverterValidator),
chartOfAccountTypeHandler: handler.NewChartOfAccountTypeHandler(chartOfAccountTypeService, chartOfAccountTypeValidator),
chartOfAccountHandler: handler.NewChartOfAccountHandler(chartOfAccountService, chartOfAccountValidator),
accountHandler: handler.NewAccountHandler(accountService, accountValidator),
orderIngredientTransactionHandler: handler.NewOrderIngredientTransactionHandler(&orderIngredientTransactionService, orderIngredientTransactionValidator),
2025-09-17 19:30:17 +07:00
gamificationHandler: handler.NewGamificationHandler(gamificationService, gamificationValidator),
2025-09-17 23:55:11 +07:00
rewardHandler: handler.NewRewardHandler(rewardService, rewardValidator),
campaignHandler: handler.NewCampaignHandler(campaignService, campaignValidator),
2025-09-18 01:32:01 +07:00
customerAuthHandler: handler.NewCustomerAuthHandler(customerAuthService, customerAuthValidator),
2025-09-18 02:01:50 +07:00
customerPointsHandler: handler.NewCustomerPointsHandler(customerPointsService),
2025-09-18 13:39:37 +07:00
spinGameHandler: handler.NewSpinGameHandler(spinGameService),
2025-09-12 15:37:19 +07:00
authMiddleware: authMiddleware,
2025-09-18 02:01:50 +07:00
customerAuthMiddleware: customerAuthMiddleware,
2026-04-16 14:30:09 +07:00
productVariantHandler: handler.NewProductVariantHandler(productVariantService, productVariantValidator),
2026-05-10 10:42:09 +07:00
userDeviceHandler: handler.NewUserDeviceHandler(userDeviceService, userDeviceValidator),
2026-05-10 10:57:38 +07:00
notificationHandler: handler.NewNotificationHandler(notificationService, notificationValidator),
2026-05-05 21:07:03 +07:00
selfOrderHandler: selfOrderHandler,
2026-05-13 21:58:54 +07:00
productOutletPriceHandler: handler.NewProductOutletPriceHandler(productOutletPriceService, productOutletPriceValidator),
2026-05-25 14:59:40 +07:00
expenseHandler: handler.NewExpenseHandler(expenseService, expenseValidator),
2026-08-13 14:38:28 +07:00
cashAdvanceHandler: handler.NewCashAdvanceHandler(cashAdvanceService, cashAdvanceValidator),
redisClient: redisClient,
2025-07-18 20:10:29 +07:00
}
}
func (r *Router) Init() *gin.Engine {
gin.SetMode(gin.ReleaseMode)
engine := gin.New()
engine.Use(
middleware.JsonAPI(),
2025-09-01 16:14:15 +07:00
middleware.CORS(),
2025-07-18 20:10:29 +07:00
middleware.CorrelationID(),
middleware.Recover(),
middleware.HTTPStatLogger(),
middleware.PopulateContext(),
)
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)
}
2025-09-18 01:32:01 +07:00
// Customer authentication routes
customerAuth := v1.Group("/customer-auth")
{
customerAuth.POST("/check-phone", r.customerAuthHandler.CheckPhone)
customerAuth.POST("/register/start", r.customerAuthHandler.RegisterStart)
customerAuth.POST("/register/verify-otp", r.customerAuthHandler.RegisterVerifyOtp)
customerAuth.POST("/register/set-password", r.customerAuthHandler.RegisterSetPassword)
customerAuth.POST("/login", r.customerAuthHandler.Login)
customerAuth.POST("/resend-otp", r.customerAuthHandler.ResendOtp)
}
2025-09-18 02:01:50 +07:00
// Customer authenticated routes
customer := v1.Group("/customer")
customer.Use(r.customerAuthMiddleware.ValidateCustomerToken())
{
customer.GET("/points", r.customerPointsHandler.GetCustomerPoints)
customer.GET("/tokens", r.customerPointsHandler.GetCustomerTokens)
customer.GET("/wallet", r.customerPointsHandler.GetCustomerWallet)
2025-09-18 12:01:20 +07:00
customer.GET("/games", r.customerPointsHandler.GetCustomerGames)
customer.GET("/ferris-wheel", r.customerPointsHandler.GetFerrisWheelGame)
2025-09-18 13:39:37 +07:00
customer.POST("/spin", r.spinGameHandler.PlaySpinGame)
2025-09-18 02:01:50 +07:00
}
2026-05-05 21:07:03 +07:00
selfOrder := v1.Group("/self-order")
{
2026-05-08 18:41:14 +07:00
selfOrder.GET("/table/:token", r.selfOrderHandler.ValidateToken)
2026-05-06 11:56:11 +07:00
selfOrder.GET("/categories", r.selfOrderHandler.ListCategories)
2026-05-08 23:18:52 +07:00
selfOrder.GET("/menu", r.selfOrderHandler.GetMenu)
2026-05-08 18:41:14 +07:00
selfOrder.POST("/orders", r.selfOrderHandler.CreateOrder)
2026-05-10 19:56:34 +07:00
selfOrder.GET("/orders/:session_id", r.selfOrderHandler.GetOrdersBySession)
2026-05-05 21:07:03 +07:00
}
2025-07-18 20:10:29 +07:00
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)
2026-05-14 00:15:28 +07:00
products.GET("/all", r.productHandler.ListProductAll)
2025-07-18 20:10:29 +07:00
products.GET("/:id", r.productHandler.GetProduct)
products.PUT("/:id", r.productHandler.UpdateProduct)
products.DELETE("/:id", r.productHandler.DeleteProduct)
}
2026-05-13 21:58:54 +07:00
productOutletPrices := protected.Group("/product-outlet-prices")
productOutletPrices.Use(r.authMiddleware.RequireAdminOrManager())
{
productOutletPrices.POST("", r.productOutletPriceHandler.Upsert)
productOutletPrices.POST("/bulk", r.productOutletPriceHandler.BulkUpsert)
productOutletPrices.GET("/product/:product_id", r.productOutletPriceHandler.GetByProduct)
productOutletPrices.GET("/outlet/:outlet_id", r.productOutletPriceHandler.GetByOutlet)
productOutletPrices.GET("/product/:product_id/outlet/:outlet_id", r.productOutletPriceHandler.GetByProductAndOutlet)
productOutletPrices.DELETE("/:id", r.productOutletPriceHandler.Delete)
}
2026-04-16 14:30:09 +07:00
productVariants := protected.Group("/product-variants")
{
productVariants.POST("", r.productVariantHandler.CreateProductVariant)
productVariants.PUT("/:id", r.productVariantHandler.UpdateProductVariant)
productVariants.DELETE("/:id", r.productVariantHandler.DeleteProductVariant)
productVariants.GET("/:id", r.productVariantHandler.GetProductVariant)
}
2025-07-18 20:10:29 +07:00
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", middleware.IdempotencyMiddleware(r.redisClient), r.orderHandler.AddToOrder)
2025-07-18 20:10:29 +07:00
orders.PUT("/:id", r.orderHandler.UpdateOrder)
orders.PUT("/:id/customer", r.orderHandler.SetOrderCustomer)
orders.POST("/void", middleware.IdempotencyMiddleware(r.redisClient), r.orderHandler.VoidOrder)
orders.POST("/:id/refund", middleware.IdempotencyMiddleware(r.redisClient), 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("", middleware.IdempotencyMiddleware(r.redisClient), r.orderHandler.CreatePayment)
payments.POST("/:id/refund", middleware.IdempotencyMiddleware(r.redisClient), r.orderHandler.RefundPayment)
2025-07-18 20:10:29 +07:00
}
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)
2026-05-19 14:45:26 +07:00
analytics.GET("/purchasing", r.analyticsHandler.GetPurchasingAnalytics)
2025-07-18 20:10:29 +07:00
analytics.GET("/products", r.analyticsHandler.GetProductAnalytics)
2025-08-14 00:45:14 +07:00
analytics.GET("/categories", r.analyticsHandler.GetProductAnalyticsPerCategory)
2026-08-05 19:28:38 +07:00
analytics.GET("/parent-categories", r.analyticsHandler.GetProductAnalyticsPerParentCategory)
analytics.GET("/parent-categories/:parent_category_id", r.analyticsHandler.GetParentCategoryAnalyticsDetail)
2025-07-18 20:10:29 +07:00
analytics.GET("/dashboard", r.analyticsHandler.GetDashboardAnalytics)
analytics.GET("/profit-loss", r.analyticsHandler.GetProfitLossAnalytics)
2026-06-17 18:17:08 +07:00
analytics.GET("/exclusive-summary/period", r.analyticsHandler.GetExclusiveSummaryPeriod)
analytics.GET("/exclusive-summary/monthly", r.analyticsHandler.GetExclusiveSummaryMonthly)
2026-06-18 14:19:45 +07:00
analytics.GET("/exclusive-summary/mtd", r.analyticsHandler.GetExclusiveSummaryMTD)
2025-07-18 20:10:29 +07:00
}
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)
2026-05-09 01:01:25 +07:00
tables.GET("/:id/qr", r.tableHandler.GenerateQRCode)
2025-07-30 23:18:20 +07:00
}
2025-08-03 23:55:51 +07:00
ingredients := protected.Group("/ingredients")
2026-06-19 13:58:36 +07:00
ingredients.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2025-08-03 23:55:51 +07:00
{
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)
2026-04-27 21:17:12 +07:00
ingredients.POST("/:id/compositions", r.ingredientHandler.AddCompositions)
ingredients.PUT("/compositions/:composition_id", r.ingredientHandler.UpdateComposition)
ingredients.DELETE("/compositions/:composition_id", r.ingredientHandler.DeleteComposition)
2025-08-03 23:55:51 +07:00
}
2025-09-12 01:12:11 +07:00
vendors := protected.Group("/vendors")
2026-06-19 13:58:36 +07:00
vendors.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2025-09-12 01:12:11 +07:00
{
vendors.POST("", r.vendorHandler.CreateVendor)
vendors.GET("", r.vendorHandler.ListVendors)
vendors.GET("/active", r.vendorHandler.GetActiveVendors)
vendors.GET("/:id", r.vendorHandler.GetVendor)
vendors.PUT("/:id", r.vendorHandler.UpdateVendor)
vendors.DELETE("/:id", r.vendorHandler.DeleteVendor)
}
purchaseOrders := protected.Group("/purchase-orders")
2026-06-19 13:58:36 +07:00
purchaseOrders.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2025-09-12 01:12:11 +07:00
{
purchaseOrders.POST("", r.purchaseOrderHandler.CreatePurchaseOrder)
purchaseOrders.GET("", r.purchaseOrderHandler.ListPurchaseOrders)
purchaseOrders.GET("/status/:status", r.purchaseOrderHandler.GetPurchaseOrdersByStatus)
purchaseOrders.GET("/overdue", r.purchaseOrderHandler.GetOverduePurchaseOrders)
purchaseOrders.GET("/teams", r.purchaseOrderHandler.ListPurchaseTeams)
2025-09-12 01:12:11 +07:00
purchaseOrders.GET("/:id", r.purchaseOrderHandler.GetPurchaseOrder)
purchaseOrders.PUT("/:id", r.purchaseOrderHandler.UpdatePurchaseOrder)
purchaseOrders.PUT("/:id/status/:status", r.purchaseOrderHandler.UpdatePurchaseOrderStatus)
purchaseOrders.DELETE("/:id", r.purchaseOrderHandler.DeletePurchaseOrder)
}
2026-06-08 12:29:59 +07:00
purchaseCategories := protected.Group("/purchase-categories")
2026-06-19 13:58:36 +07:00
purchaseCategories.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2026-06-08 12:29:59 +07:00
{
purchaseCategories.POST("", r.purchaseCategoryHandler.CreatePurchaseCategory)
purchaseCategories.GET("", r.purchaseCategoryHandler.ListPurchaseCategories)
purchaseCategories.GET("/:id", r.purchaseCategoryHandler.GetPurchaseCategory)
purchaseCategories.PUT("/:id", r.purchaseCategoryHandler.UpdatePurchaseCategory)
purchaseCategories.DELETE("/:id", r.purchaseCategoryHandler.DeletePurchaseCategory)
}
2025-09-12 01:12:11 +07:00
unitConverters := protected.Group("/unit-converters")
2026-06-19 13:58:36 +07:00
unitConverters.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2025-09-12 01:12:11 +07:00
{
unitConverters.POST("", r.unitConverterHandler.CreateIngredientUnitConverter)
unitConverters.GET("", r.unitConverterHandler.ListIngredientUnitConverters)
unitConverters.GET("/ingredient/:ingredient_id", r.unitConverterHandler.GetConvertersForIngredient)
2025-09-12 15:37:19 +07:00
unitConverters.GET("/ingredient/:ingredient_id/units", r.unitConverterHandler.GetUnitsByIngredientID)
2025-09-12 01:12:11 +07:00
unitConverters.POST("/convert", r.unitConverterHandler.ConvertUnit)
unitConverters.GET("/:id", r.unitConverterHandler.GetIngredientUnitConverter)
unitConverters.PUT("/:id", r.unitConverterHandler.UpdateIngredientUnitConverter)
unitConverters.DELETE("/:id", r.unitConverterHandler.DeleteIngredientUnitConverter)
}
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-09-12 01:12:11 +07:00
// Accounting routes
chartOfAccountTypes := protected.Group("/chart-of-account-types")
chartOfAccountTypes.Use(r.authMiddleware.RequireAdminOrManager())
{
chartOfAccountTypes.POST("", r.chartOfAccountTypeHandler.CreateChartOfAccountType)
chartOfAccountTypes.GET("", r.chartOfAccountTypeHandler.ListChartOfAccountTypes)
chartOfAccountTypes.GET("/:id", r.chartOfAccountTypeHandler.GetChartOfAccountTypeByID)
chartOfAccountTypes.PUT("/:id", r.chartOfAccountTypeHandler.UpdateChartOfAccountType)
chartOfAccountTypes.DELETE("/:id", r.chartOfAccountTypeHandler.DeleteChartOfAccountType)
}
chartOfAccounts := protected.Group("/chart-of-accounts")
chartOfAccounts.Use(r.authMiddleware.RequireAdminOrManager())
{
chartOfAccounts.POST("", r.chartOfAccountHandler.CreateChartOfAccount)
chartOfAccounts.GET("", r.chartOfAccountHandler.ListChartOfAccounts)
chartOfAccounts.GET("/:id", r.chartOfAccountHandler.GetChartOfAccountByID)
chartOfAccounts.PUT("/:id", r.chartOfAccountHandler.UpdateChartOfAccount)
chartOfAccounts.DELETE("/:id", r.chartOfAccountHandler.DeleteChartOfAccount)
chartOfAccounts.GET("/organization/:organization_id", r.chartOfAccountHandler.GetChartOfAccountsByOrganization)
chartOfAccounts.GET("/organization/:organization_id/type/:type_id", r.chartOfAccountHandler.GetChartOfAccountsByType)
}
accounts := protected.Group("/accounts")
accounts.Use(r.authMiddleware.RequireAdminOrManager())
{
accounts.POST("", r.accountHandler.CreateAccount)
accounts.GET("", r.accountHandler.ListAccounts)
accounts.GET("/:id", r.accountHandler.GetAccountByID)
accounts.PUT("/:id", r.accountHandler.UpdateAccount)
accounts.DELETE("/:id", r.accountHandler.DeleteAccount)
accounts.GET("/organization/:organization_id", r.accountHandler.GetAccountsByOrganization)
accounts.GET("/chart-of-account/:chart_of_account_id", r.accountHandler.GetAccountsByChartOfAccount)
accounts.PUT("/:id/balance", r.accountHandler.UpdateAccountBalance)
accounts.GET("/:id/balance", r.accountHandler.GetAccountBalance)
}
2026-05-25 14:59:40 +07:00
expenses := protected.Group("/expenses")
2026-06-19 13:58:36 +07:00
expenses.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
2026-05-25 14:59:40 +07:00
{
expenses.POST("", r.expenseHandler.CreateExpense)
expenses.GET("", r.expenseHandler.ListExpenses)
2026-06-03 14:56:27 +07:00
expenses.GET("/analytics", r.expenseHandler.GetExpenseAnalytics)
2026-05-25 14:59:40 +07:00
expenses.GET("/:id", r.expenseHandler.GetExpense)
expenses.PUT("/:id", r.expenseHandler.UpdateExpense)
expenses.DELETE("/:id", r.expenseHandler.DeleteExpense)
}
2026-08-13 14:38:28 +07:00
cashAdvances := protected.Group("/cash-advances")
cashAdvances.Use(r.authMiddleware.RequireAdminOrManagerOrPurchasing())
{
cashAdvances.POST("", r.cashAdvanceHandler.CreateCashAdvance)
cashAdvances.GET("", r.cashAdvanceHandler.ListCashAdvances)
// Registered ahead of /:id so the picker path is not read as an id.
cashAdvances.GET("/teams", r.cashAdvanceHandler.ListCashAdvanceTeams)
cashAdvances.GET("/:id", r.cashAdvanceHandler.GetCashAdvance)
cashAdvances.PUT("/:id", r.cashAdvanceHandler.UpdateCashAdvance)
cashAdvances.PUT("/:id/status/:status", r.cashAdvanceHandler.UpdateCashAdvanceStatus)
cashAdvances.DELETE("/:id", r.cashAdvanceHandler.DeleteCashAdvance)
}
2025-09-12 15:37:19 +07:00
orderIngredientTransactions := protected.Group("/order-ingredient-transactions")
orderIngredientTransactions.Use(r.authMiddleware.RequireAdminOrManager())
{
orderIngredientTransactions.POST("", r.orderIngredientTransactionHandler.CreateOrderIngredientTransaction)
orderIngredientTransactions.GET("", r.orderIngredientTransactionHandler.ListOrderIngredientTransactions)
orderIngredientTransactions.GET("/:id", r.orderIngredientTransactionHandler.GetOrderIngredientTransactionByID)
orderIngredientTransactions.PUT("/:id", r.orderIngredientTransactionHandler.UpdateOrderIngredientTransaction)
orderIngredientTransactions.DELETE("/:id", r.orderIngredientTransactionHandler.DeleteOrderIngredientTransaction)
orderIngredientTransactions.GET("/order/:order_id", r.orderIngredientTransactionHandler.GetOrderIngredientTransactionsByOrder)
orderIngredientTransactions.GET("/order-item/:order_item_id", r.orderIngredientTransactionHandler.GetOrderIngredientTransactionsByOrderItem)
orderIngredientTransactions.GET("/ingredient/:ingredient_id", r.orderIngredientTransactionHandler.GetOrderIngredientTransactionsByIngredient)
orderIngredientTransactions.GET("/summary", r.orderIngredientTransactionHandler.GetOrderIngredientTransactionSummary)
orderIngredientTransactions.POST("/bulk", r.orderIngredientTransactionHandler.BulkCreateOrderIngredientTransactions)
}
2025-09-17 19:30:17 +07:00
gamification := protected.Group("/marketing")
gamification.Use(r.authMiddleware.RequireAdminOrManager())
{
//customerPoints := gamification.Group("/customer-points")
//{
// customerPoints.POST("", r.gamificationHandler.CreateCustomerPoints)
// customerPoints.GET("", r.gamificationHandler.ListCustomerPoints)
// customerPoints.GET("/:id", r.gamificationHandler.GetCustomerPoints)
// customerPoints.PUT("/:id", r.gamificationHandler.UpdateCustomerPoints)
// customerPoints.DELETE("/:id", r.gamificationHandler.DeleteCustomerPoints)
// customerPoints.GET("/customer/:customer_id", r.gamificationHandler.GetCustomerPointsByCustomerID)
// customerPoints.POST("/customer/:customer_id/add", r.gamificationHandler.AddCustomerPoints)
// customerPoints.POST("/customer/:customer_id/deduct", r.gamificationHandler.DeductCustomerPoints)
//}
// Customer Tokens
//customerTokens := gamification.Group("/customer-tokens")
//{
// customerTokens.POST("", r.gamificationHandler.CreateCustomerTokens)
// customerTokens.GET("", r.gamificationHandler.ListCustomerTokens)
// customerTokens.GET("/:id", r.gamificationHandler.GetCustomerTokens)
// customerTokens.PUT("/:id", r.gamificationHandler.UpdateCustomerTokens)
// customerTokens.DELETE("/:id", r.gamificationHandler.DeleteCustomerTokens)
// customerTokens.GET("/customer/:customer_id/type/:token_type", r.gamificationHandler.GetCustomerTokensByCustomerIDAndType)
// customerTokens.POST("/customer/:customer_id/type/:token_type/add", r.gamificationHandler.AddCustomerTokens)
// customerTokens.POST("/customer/:customer_id/type/:token_type/deduct", r.gamificationHandler.DeductCustomerTokens)
//}
// Tiers
tiers := gamification.Group("/tiers")
{
tiers.POST("", r.gamificationHandler.CreateTier)
tiers.GET("", r.gamificationHandler.ListTiers)
tiers.GET("/:id", r.gamificationHandler.GetTier)
tiers.PUT("/:id", r.gamificationHandler.UpdateTier)
tiers.DELETE("/:id", r.gamificationHandler.DeleteTier)
tiers.GET("/by-points/:points", r.gamificationHandler.GetTierByPoints)
}
// Games
games := gamification.Group("/games")
{
games.POST("", r.gamificationHandler.CreateGame)
games.GET("", r.gamificationHandler.ListGames)
games.GET("/active", r.gamificationHandler.GetActiveGames)
games.GET("/:id", r.gamificationHandler.GetGame)
games.PUT("/:id", r.gamificationHandler.UpdateGame)
games.DELETE("/:id", r.gamificationHandler.DeleteGame)
}
// Game Prizes
gamePrizes := gamification.Group("/game-prizes")
{
gamePrizes.POST("", r.gamificationHandler.CreateGamePrize)
gamePrizes.GET("", r.gamificationHandler.ListGamePrizes)
gamePrizes.GET("/:id", r.gamificationHandler.GetGamePrize)
gamePrizes.PUT("/:id", r.gamificationHandler.UpdateGamePrize)
gamePrizes.DELETE("/:id", r.gamificationHandler.DeleteGamePrize)
gamePrizes.GET("/game/:game_id", r.gamificationHandler.GetGamePrizesByGameID)
gamePrizes.GET("/game/:game_id/available", r.gamificationHandler.GetAvailablePrizes)
}
//// Game Plays
//gamePlays := gamification.Group("/game-plays")
//{
// gamePlays.POST("", r.gamificationHandler.CreateGamePlay)
// gamePlays.GET("", r.gamificationHandler.ListGamePlays)
// gamePlays.GET("/:id", r.gamificationHandler.GetGamePlay)
// gamePlays.POST("/play", r.gamificationHandler.PlayGame)
//}
// Omset Tracker
//omsetTracker := gamification.Group("/omset-tracker")
//{
// omsetTracker.POST("", r.gamificationHandler.CreateOmsetTracker)
// omsetTracker.GET("", r.gamificationHandler.ListOmsetTrackers)
// omsetTracker.GET("/:id", r.gamificationHandler.GetOmsetTracker)
// omsetTracker.PUT("/:id", r.gamificationHandler.UpdateOmsetTracker)
// omsetTracker.DELETE("/:id", r.gamificationHandler.DeleteOmsetTracker)
//}
2025-09-17 23:55:11 +07:00
// Rewards
rewards := gamification.Group("/rewards")
{
rewards.POST("", r.rewardHandler.CreateReward)
rewards.GET("", r.rewardHandler.ListRewards)
rewards.GET("/:id", r.rewardHandler.GetReward)
rewards.PUT("/:id", r.rewardHandler.UpdateReward)
rewards.DELETE("/:id", r.rewardHandler.DeleteReward)
rewards.PUT("/:id/stock/:stock", r.rewardHandler.UpdateRewardStock)
rewards.GET("/type/:type", r.rewardHandler.GetRewardsByType)
}
// Campaigns
campaigns := gamification.Group("/campaigns")
{
campaigns.POST("", r.campaignHandler.CreateCampaign)
campaigns.GET("", r.campaignHandler.ListCampaigns)
campaigns.GET("/active", r.campaignHandler.GetActiveCampaigns)
campaigns.GET("/app", r.campaignHandler.GetCampaignsForApp)
campaigns.GET("/:id", r.campaignHandler.GetCampaign)
campaigns.PUT("/:id", r.campaignHandler.UpdateCampaign)
campaigns.DELETE("/:id", r.campaignHandler.DeleteCampaign)
}
2025-09-18 13:39:37 +07:00
// Campaign Rules
campaignRules := gamification.Group("/campaign-rules")
{
campaignRules.POST("", r.campaignHandler.CreateCampaignRule)
campaignRules.GET("", r.campaignHandler.ListCampaignRules)
campaignRules.GET("/:id", r.campaignHandler.GetCampaignRule)
campaignRules.PUT("/:id", r.campaignHandler.UpdateCampaignRule)
campaignRules.DELETE("/:id", r.campaignHandler.DeleteCampaignRule)
campaignRules.GET("/campaign/:campaign_id", r.campaignHandler.GetCampaignRulesByCampaignID)
}
2025-09-17 19:30:17 +07:00
}
2025-07-30 23:18:20 +07:00
outlets := protected.Group("/outlets")
outlets.Use(r.authMiddleware.RequireAdminOrManager())
{
2026-04-16 19:23:36 +07:00
outlets.POST("", r.outletHandler.CreateOutlet)
2025-07-30 23:18:20 +07:00
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)
2026-06-19 13:31:33 +07:00
outlets.GET("/:outlet_id/reports/profit-loss.pdf", r.reportHandler.GetProfitLossReportPDF)
2025-07-30 23:18:20 +07:00
}
2026-05-10 10:42:09 +07:00
// User device routes - accessible by authenticated users for their own devices
userDevices := protected.Group("/user-devices")
{
userDevices.POST("/register", r.userDeviceHandler.RegisterDevice)
userDevices.GET("/me", r.userDeviceHandler.GetMyDevices)
userDevices.GET("/:id", r.userDeviceHandler.GetDevice)
userDevices.PUT("/:id", r.userDeviceHandler.UpdateDevice)
userDevices.DELETE("/:id", r.userDeviceHandler.DeleteDevice)
}
// Admin-only user device routes
adminUserDevices := protected.Group("/user-devices")
adminUserDevices.Use(r.authMiddleware.RequireAdminOrManager())
{
adminUserDevices.GET("", r.userDeviceHandler.ListDevices)
adminUserDevices.GET("/user/:user_id", r.userDeviceHandler.GetDevicesByUser)
}
2026-05-10 10:57:38 +07:00
// Notification routes - authenticated users manage their own notifications
notifications := protected.Group("/notifications")
{
notifications.GET("", r.notificationHandler.List)
notifications.GET("/:id", r.notificationHandler.GetByID)
notifications.PUT("/:id/read", r.notificationHandler.MarkAsRead)
notifications.PUT("/read-all", r.notificationHandler.MarkAllAsRead)
notifications.DELETE("/:id", r.notificationHandler.Delete)
}
// Admin notification routes - send and broadcast
adminNotifications := protected.Group("/notifications")
adminNotifications.Use(r.authMiddleware.RequireAdminOrManager())
{
adminNotifications.POST("/send", r.notificationHandler.Send)
adminNotifications.POST("/broadcast", r.notificationHandler.Broadcast)
}
2025-07-18 20:10:29 +07:00
}
}
}