| package main |
|
|
| import ( |
| "io" |
| "log" |
| "net/http" |
|
|
| "service-warungpos-go/config" |
| "service-warungpos-go/controllers" |
| "service-warungpos-go/middleware" |
| "service-warungpos-go/models" |
|
|
| "github.com/gin-gonic/gin" |
| ) |
|
|
| func main() { |
| log.Println("Starting XOGM Go Service...") |
|
|
| |
| config.LoadConfig() |
|
|
| |
| config.ConnectDatabase() |
|
|
| |
| log.Println("Running Auto-Migration...") |
| err := config.DB.AutoMigrate( |
| &models.Company{}, |
| &models.Branch{}, |
| &models.User{}, |
| &models.Category{}, |
| &models.Product{}, |
| &models.BranchProduct{}, |
| &models.Order{}, |
| &models.OrderItem{}, |
| &models.OTP{}, |
| &models.Setting{}, |
| &models.Member{}, |
| &models.PointRule{}, |
| &models.WalletTransaction{}, |
| &models.TopupRequest{}, |
| &models.Voucher{}, |
| &models.PointHistory{}, |
| &models.UserSession{}, |
| ) |
| if err != nil { |
| log.Fatalf("Gagal melakukan Auto-Migration: %v", err) |
| } |
| log.Println("Auto-Migration Selesai dengan Sukses!") |
|
|
| |
| controllers.SeedDefaultAdmin() |
| controllers.SeedDefaultSetting() |
|
|
| |
|
|
| |
| r := gin.New() |
|
|
| |
| r.Use(gin.Logger()) |
| r.Use(gin.Recovery()) |
| r.Use(middleware.CORSMiddleware()) |
|
|
| |
| r.GET("/", func(c *gin.Context) { |
| c.JSON(http.StatusOK, gin.H{ |
| "service": "XOGM Go API (Go Version)", |
| "version": "1.0.0", |
| "status": "running", |
| "docs": "/docs", |
| }) |
| }) |
|
|
| r.GET("/health", func(c *gin.Context) { |
| c.JSON(http.StatusOK, gin.H{"status": "healthy"}) |
| }) |
|
|
| r.GET("/api/ip", func(c *gin.Context) { |
| resp, err := http.Get("https://api.ipify.org") |
| if err != nil { |
| c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal mendapatkan IP outbound: " + err.Error()}) |
| return |
| } |
| defer resp.Body.Close() |
| ipBytes, err := io.ReadAll(resp.Body) |
| if err != nil { |
| c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal membaca IP response: " + err.Error()}) |
| return |
| } |
| c.JSON(http.StatusOK, gin.H{ |
| "public_ip": string(ipBytes), |
| "info": "Gunakan IP ini untuk di-whitelist di Tripay", |
| }) |
| }) |
|
|
| |
| api := r.Group("/api") |
| { |
| |
| auth := api.Group("/auth") |
| { |
| auth.POST("/login", controllers.Login) |
| auth.POST("/register-tenant", controllers.RegisterTenant) |
| auth.POST("/verify-otp", controllers.VerifyOTP) |
| auth.POST("/resend-otp", controllers.ResendOTP) |
| auth.POST("/forgot-password", controllers.ForgotPassword) |
| auth.POST("/reset-password", controllers.ResetPassword) |
|
|
| |
| auth.Use(middleware.GetCurrentUser()) |
| { |
| auth.GET("/me", controllers.GetMe) |
| auth.POST("/logout", controllers.Logout) |
| auth.POST("/register", middleware.RequireSuperAdmin(), controllers.Register) |
| auth.GET("/users", middleware.RequireSuperAdmin(), controllers.ListUsers) |
| auth.PUT("/users/:user_id", middleware.RequireSuperAdmin(), controllers.UpdateUser) |
|
|
|
|
|
|
| |
| auth.GET("/kasir", middleware.RequireOwner(), controllers.ListKasir) |
| auth.POST("/kasir", middleware.RequireOwner(), controllers.CreateKasir) |
| auth.PUT("/kasir/:user_id", middleware.RequireOwner(), controllers.UpdateKasir) |
| } |
| } |
|
|
| |
| companies := api.Group("/companies") |
| { |
| companies.Use(middleware.GetCurrentUser()) |
| { |
| companies.GET("/me", controllers.GetMyCompany) |
| companies.PUT("/me/points", controllers.UpdateMyCompanyPoints) |
| companies.GET("/", middleware.RequireSuperAdmin(), controllers.ListCompanies) |
| companies.GET("/:company_id", middleware.RequireSuperAdmin(), controllers.GetCompany) |
| companies.POST("/", middleware.RequireSuperAdmin(), controllers.CreateCompany) |
| companies.PUT("/:company_id", middleware.RequireSuperAdmin(), controllers.UpdateCompany) |
| companies.PUT("/:company_id/toggle-active", middleware.RequireSuperAdmin(), controllers.ToggleActiveCompany) |
| companies.DELETE("/:company_id", middleware.RequireSuperAdmin(), controllers.DeleteCompany) |
| companies.PUT("/:company_id/reject", middleware.RequireSuperAdmin(), controllers.RejectCompany) |
| companies.PUT("/:company_id/approve", middleware.RequireSuperAdmin(), controllers.ApproveCompany) |
| } |
| } |
|
|
| branches := api.Group("/branches") |
| { |
| branches.Use(middleware.GetCurrentUser(), middleware.RequireOwner()) |
| { |
| branches.GET("/", controllers.ListBranches) |
| branches.POST("/", controllers.CreateBranch) |
| branches.PUT("/:branch_id", controllers.UpdateBranch) |
| branches.DELETE("/:branch_id", controllers.DeleteBranch) |
| branches.PUT("/:branch_id/toggle", controllers.ToggleBranchStatus) |
| branches.GET("/:branch_id/products", controllers.GetBranchProducts) |
| branches.PUT("/:branch_id/products/:product_id", controllers.ToggleProductAvailability) |
| } |
| } |
|
|
| |
| members := api.Group("/members") |
| { |
| members.Use(middleware.GetCurrentUser(), middleware.RequireTenantContext()) |
| { |
| members.GET("/check", controllers.CheckMember) |
| members.GET("/", controllers.ListMembers) |
| members.POST("/", controllers.CreateMember) |
| members.PUT("/:member_id", controllers.UpdateMember) |
| members.PUT("/:member_id/points", middleware.RequireOwner(), controllers.SetPoints) |
| members.GET("/:member_id/points/history", controllers.GetPointHistory) |
| members.DELETE("/:member_id", middleware.RequireOwner(), controllers.DeleteMember) |
| } |
| } |
|
|
| |
| products := api.Group("/products") |
| { |
| products.Use(middleware.GetCurrentUser()) |
| { |
| products.POST("/upload-image", middleware.RequireOwner(), controllers.UploadProductImage) |
| products.GET("/", middleware.RequireTenantContext(), controllers.ListProducts) |
| products.GET("/:product_id", middleware.RequireTenantContext(), controllers.GetProduct) |
| products.POST("/", middleware.RequireOwner(), controllers.CreateProduct) |
| products.PUT("/:product_id", middleware.RequireOwner(), controllers.UpdateProduct) |
| products.DELETE("/:product_id", middleware.RequireOwner(), controllers.DeleteProduct) |
| } |
| } |
|
|
| categories := api.Group("/categories") |
| { |
| categories.Use(middleware.GetCurrentUser()) |
| { |
| categories.GET("/", middleware.RequireTenantContext(), controllers.ListCategories) |
| categories.GET("/:category_id", middleware.RequireTenantContext(), controllers.GetCategory) |
| categories.POST("/", middleware.RequireOwner(), controllers.CreateCategory) |
| categories.PUT("/:category_id", middleware.RequireOwner(), controllers.UpdateCategory) |
| categories.DELETE("/:category_id", middleware.RequireOwner(), controllers.DeleteCategory) |
| } |
| } |
|
|
| |
| orders := api.Group("/orders") |
| { |
| orders.Use(middleware.GetCurrentUser(), middleware.RequireTenantContext()) |
| { |
| orders.GET("/", controllers.ListOrders) |
| orders.GET("/:order_id", controllers.GetOrder) |
| orders.POST("/", controllers.CreateOrder) |
| orders.POST("/pay/cash", controllers.PayCash) |
| orders.POST("/pay/midtrans", controllers.PayTripay) |
| } |
| } |
|
|
| vouchers := api.Group("/vouchers") |
| { |
| vouchers.Use(middleware.GetCurrentUser()) |
| { |
| vouchers.GET("/", controllers.GetVouchers) |
| vouchers.POST("/", controllers.CreateVoucher) |
| vouchers.PUT("/:id", controllers.UpdateVoucher) |
| vouchers.DELETE("/:id", controllers.DeleteVoucher) |
| } |
| } |
|
|
| |
| payments := api.Group("/payments") |
| { |
| |
| payments.POST("/webhook", controllers.TripayWebhook) |
|
|
| payments.Use(middleware.GetCurrentUser(), middleware.RequireTenantContext()) |
| { |
| payments.POST("/cash", controllers.PayCash) |
| payments.POST("/midtrans", controllers.PayTripay) |
| payments.POST("/tripay", controllers.PayTripay) |
| payments.GET("/:order_id/status", controllers.GetPaymentStatus) |
| payments.POST("/:order_id/cancel", controllers.CancelMidtransOrder) |
| } |
| } |
|
|
| |
| reports := api.Group("/reports") |
| { |
| reports.Use(middleware.GetCurrentUser(), middleware.RequireTenantContext()) |
| { |
| reports.GET("/daily", controllers.DailyReport) |
| reports.GET("/summary", controllers.SummaryReport) |
| } |
| } |
|
|
| |
| fees := api.Group("/fees") |
| { |
| fees.Use(middleware.GetCurrentUser(), middleware.RequireSuperAdmin()) |
| { |
| fees.GET("/report", controllers.GetFeeReport) |
| fees.PUT("/companies/:company_id/set-fee", controllers.SetCompanyFee) |
| } |
| } |
|
|
| |
| wallet := api.Group("/wallet") |
| { |
| wallet.Use(middleware.GetCurrentUser(), middleware.RequireTenantContext()) |
| { |
| wallet.GET("", controllers.GetWalletDetail) |
| wallet.POST("/topup/manual", controllers.RequestTopupManual) |
| wallet.POST("/topup/qris", controllers.RequestTopupQris) |
| } |
| } |
|
|
| |
| adminTopups := api.Group("/admin/topups") |
| { |
| adminTopups.Use(middleware.GetCurrentUser(), middleware.RequireSuperAdmin()) |
| { |
| adminTopups.GET("", controllers.AdminGetPendingTopups) |
| adminTopups.POST("/:id/approve", controllers.AdminApproveTopup) |
| adminTopups.POST("/:id/reject", controllers.AdminRejectTopup) |
| } |
| } |
|
|
| adminCompanies := api.Group("/admin/companies") |
| { |
| adminCompanies.Use(middleware.GetCurrentUser(), middleware.RequireSuperAdmin()) |
| { |
| adminCompanies.POST("/:id/adjust-wallet", controllers.AdminAdjustWallet) |
| adminCompanies.PUT("/:id/settings", controllers.AdminUpdateCompanySettings) |
| } |
| } |
| } |
|
|
| |
| serverPort := config.GlobalConfig.Port |
| if serverPort == "" { |
| serverPort = "8003" |
| } |
|
|
| log.Printf("XOGM Go Server berjalan di port: %s", serverPort) |
| if err := r.Run(":" + serverPort); err != nil { |
| log.Fatalf("Gagal menjalankan server Gin: %v", err) |
| } |
| } |
| |
|
|