295 lines
12 KiB
Go
295 lines
12 KiB
Go
package routes
|
|
|
|
import (
|
|
"lost-and-found/internal/controllers"
|
|
"lost-and-found/internal/middleware"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// SetupRoutes configures all application routes
|
|
func SetupRoutes(router *gin.Engine, db *gorm.DB, logger *zap.Logger) {
|
|
// Initialize controllers
|
|
authController := controllers.NewAuthController(db, logger)
|
|
userController := controllers.NewUserController(db)
|
|
itemController := controllers.NewItemController(db)
|
|
lostItemController := controllers.NewLostItemController(db)
|
|
claimController := controllers.NewClaimController(db)
|
|
matchController := controllers.NewMatchController(db)
|
|
categoryController := controllers.NewCategoryController(db)
|
|
archiveController := controllers.NewArchiveController(db)
|
|
adminController := controllers.NewAdminController(db)
|
|
reportController := controllers.NewReportController(db)
|
|
uploadController := controllers.NewUploadController(db)
|
|
managerController := controllers.NewManagerController(db)
|
|
roleController := controllers.NewRoleController(db)
|
|
notificationController := controllers.NewNotificationController(db)
|
|
aiController := controllers.NewAIController(db)
|
|
|
|
// API group
|
|
api := router.Group("/api")
|
|
{
|
|
// ==========================================
|
|
// 1. Public Routes (No Auth)
|
|
// ==========================================
|
|
api.POST("/register", authController.Register)
|
|
api.POST("/login", authController.Login)
|
|
api.POST("/refresh-token", authController.RefreshToken)
|
|
|
|
api.GET("/categories", categoryController.GetAllCategories)
|
|
api.GET("/categories/:id", categoryController.GetCategoryByID)
|
|
|
|
// Optional Auth for Items (Public can view, Manager sees details)
|
|
itemsGroup := api.Group("/items")
|
|
itemsGroup.Use(middleware.OptionalJWTMiddleware(db))
|
|
{
|
|
itemsGroup.GET("", itemController.GetAllItems)
|
|
itemsGroup.GET("/:id", itemController.GetItemByID)
|
|
}
|
|
|
|
// ==========================================
|
|
// 2. Authenticated Routes (Basic User Access)
|
|
// ==========================================
|
|
// Middleware: Cek Token Valid & User Active
|
|
authenticated := api.Group("")
|
|
authenticated.Use(middleware.JWTMiddleware(db))
|
|
{
|
|
|
|
authenticated.POST("/ai/chat", aiController.Chat)
|
|
authenticated.GET("/ai/history", aiController.GetHistory)
|
|
authenticated.DELETE("/ai/history", aiController.ClearHistory)
|
|
// Profile (Siapapun yang login bisa akses ini)
|
|
authenticated.GET("/me", authController.GetMe)
|
|
authenticated.GET("/user/profile", userController.GetProfile)
|
|
authenticated.PUT("/user/profile", userController.UpdateProfile)
|
|
authenticated.POST("/user/change-password", userController.ChangePassword)
|
|
authenticated.GET("/user/stats", userController.GetStats)
|
|
|
|
authenticated.POST("/lost-items/:id/direct-claim", lostItemController.DirectClaimToOwner)
|
|
authenticated.POST("/user/lost-items/:id/direct-claim", lostItemController.DirectClaimToOwner)
|
|
authenticated.POST("/claims/:id/respond", claimController.UserApproveClaim)
|
|
authenticated.POST("/claims/:id/complete", claimController.UserConfirmCompletion)
|
|
|
|
// --- User Features (Permission: item:create) ---
|
|
authenticated.POST("/items",
|
|
middleware.RequirePermission("item:create"),
|
|
itemController.CreateItem)
|
|
|
|
authenticated.GET("/user/items",
|
|
middleware.RequirePermission("item:read"),
|
|
itemController.GetItemsByReporter)
|
|
|
|
// --- Lost Items (Permission: item:create) ---
|
|
// Asumsi: Hak akses lapor kehilangan sama dengan lapor temuan
|
|
authenticated.POST("/lost-items",
|
|
middleware.RequirePermission("item:create"),
|
|
lostItemController.CreateLostItem)
|
|
|
|
authenticated.GET("/user/lost-items", lostItemController.GetLostItemsByUser)
|
|
authenticated.GET("/lost-items", lostItemController.GetAllLostItems)
|
|
authenticated.GET("/lost-items/:id", lostItemController.GetLostItemByID)
|
|
authenticated.PUT("/lost-items/:id", lostItemController.UpdateLostItem)
|
|
authenticated.PATCH("/lost-items/:id/status", lostItemController.UpdateLostItemStatus)
|
|
|
|
// ✅ FIX: Delete Lost Item menggunakan controller yang benar
|
|
authenticated.DELETE("/lost-items/:id",
|
|
middleware.RequirePermission("lost_item:delete"), // Permission baru
|
|
lostItemController.DeleteLostItem)
|
|
|
|
// --- Claims (Permission: claim:create) ---
|
|
authenticated.POST("/claims",
|
|
middleware.RequirePermission("claim:create"),
|
|
middleware.IdempotencyMiddleware(), // Prevent double submit
|
|
claimController.CreateClaim)
|
|
|
|
authenticated.GET("/user/claims",
|
|
middleware.RequirePermission("claim:read"),
|
|
claimController.GetClaimsByUser)
|
|
|
|
// ✅ FIX: Tambahkan endpoint update dan delete claim user
|
|
authenticated.PUT("/claims/:id",
|
|
middleware.RequirePermission("claim:create"), // User boleh edit claim sendiri
|
|
claimController.UpdateClaim)
|
|
|
|
authenticated.DELETE("/claims/:id",
|
|
middleware.RequirePermission("claim:create"), // User boleh delete claim sendiri
|
|
claimController.DeleteClaim)
|
|
|
|
|
|
// --- Matching ---
|
|
authenticated.GET("/lost-items/:id/matches", matchController.GetMatchesForLostItem)
|
|
authenticated.POST("/lost-items/:id/find-similar", matchController.FindSimilarItems)
|
|
// --- Notifications ---
|
|
authenticated.GET("/notifications", notificationController.GetUserNotifications)
|
|
authenticated.PATCH("/notifications/:id/read", notificationController.MarkAsRead)
|
|
authenticated.PATCH("/notifications/read-all", notificationController.MarkAllAsRead)
|
|
|
|
authenticated.POST("/user/claims/:id/respond", claimController.UserApproveClaim)
|
|
authenticated.POST("/user/claims/:id/complete", claimController.UserConfirmCompletion)
|
|
|
|
// --- Uploads ---
|
|
upload := authenticated.Group("/upload")
|
|
{
|
|
upload.POST("/item-image", uploadController.UploadItemImage)
|
|
upload.POST("/claim-proof", uploadController.UploadClaimProof)
|
|
upload.POST("/multiple", uploadController.UploadMultipleImages)
|
|
upload.DELETE("/delete", uploadController.DeleteImage)
|
|
upload.GET("/info", uploadController.GetImageInfo)
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// 3. Protected Management Routes (Permission Based)
|
|
// ==========================================
|
|
// Area ini menggantikan Group Manager/Admin yang lama.
|
|
// Sekarang dikelompokkan berdasarkan FITUR, bukan ROLE.
|
|
management := api.Group("")
|
|
management.Use(middleware.JWTMiddleware(db))
|
|
{
|
|
// --- ITEM MANAGEMENT (Permission: item:update, item:delete) ---
|
|
management.PUT("/items/:id",
|
|
middleware.RequirePermission("item:update"),
|
|
itemController.UpdateItem)
|
|
|
|
management.PATCH("/items/:id/status",
|
|
middleware.RequirePermission("item:update"),
|
|
itemController.UpdateItemStatus)
|
|
|
|
management.DELETE("/items/:id",
|
|
middleware.RequirePermission("item:delete"),
|
|
itemController.DeleteItem)
|
|
|
|
management.GET("/items/:id/revisions",
|
|
middleware.RequirePermission("item:verify"),
|
|
itemController.GetItemRevisionHistory)
|
|
|
|
management.GET("/items/:id/matches",
|
|
middleware.RequirePermission("item:verify"),
|
|
matchController.GetMatchesForItem)
|
|
|
|
// --- CLAIM VERIFICATION (Permission: claim:approve, claim:reject) ---
|
|
management.GET("/claims",
|
|
middleware.RequirePermission("claim:read"), // Manager view all claims
|
|
claimController.GetAllClaims)
|
|
|
|
management.GET("/claims/:id",
|
|
middleware.RequirePermission("claim:read"),
|
|
claimController.GetClaimByID)
|
|
|
|
management.POST("/claims/:id/verify",
|
|
middleware.RequirePermission("claim:approve"),
|
|
middleware.IdempotencyMiddleware(),
|
|
claimController.VerifyClaim)
|
|
|
|
management.GET("/claims/:id/verification",
|
|
middleware.RequirePermission("claim:read"),
|
|
claimController.GetClaimVerification)
|
|
|
|
// ✅ FIX: Ganti endpoint CloseClaim -> CloseCase
|
|
management.POST("/claims/:id/close",
|
|
middleware.RequirePermission("claim:approve"),
|
|
claimController.CloseCase)
|
|
|
|
// ✅ FIX: Ganti endpoint ReopenClaim -> ReopenCase
|
|
management.POST("/claims/:id/reopen",
|
|
middleware.RequirePermission("claim:approve"),
|
|
claimController.ReopenCase)
|
|
|
|
// ✅ FIX: Ganti endpoint CancelApproval -> CancelClaimApproval
|
|
management.POST("/claims/:id/cancel-approval",
|
|
middleware.RequirePermission("claim:approve"),
|
|
claimController.CancelClaimApproval)
|
|
|
|
// --- ARCHIVES (Permission: item:read - for historical data) ---
|
|
management.GET("/archives",
|
|
middleware.RequirePermission("item:read"),
|
|
archiveController.GetAllArchives)
|
|
|
|
management.GET("/archives/:id",
|
|
middleware.RequirePermission("item:read"),
|
|
archiveController.GetArchiveByID)
|
|
|
|
management.GET("/archives/stats",
|
|
middleware.RequirePermission("item:read"),
|
|
archiveController.GetArchiveStats)
|
|
|
|
// --- REPORTS (Permission: report:export) ---
|
|
management.POST("/reports/export",
|
|
middleware.RequirePermission("report:export"),
|
|
reportController.ExportReport)
|
|
|
|
// --- DASHBOARD (Permission: user:read - as proxy for dashboard access) ---
|
|
management.GET("/manager/dashboard",
|
|
middleware.RequirePermission("item:verify"),
|
|
managerController.GetDashboardStats)
|
|
|
|
management.GET("/admin/dashboard",
|
|
middleware.RequirePermission("user:read"),
|
|
adminController.GetDashboardStats)
|
|
|
|
// --- USER MANAGEMENT (Permission: user:read, user:update, user:block) ---
|
|
// Biasa dilakukan oleh Admin
|
|
management.GET("/admin/users",
|
|
middleware.RequirePermission("user:read"),
|
|
userController.GetAllUsers)
|
|
|
|
management.GET("/admin/users/:id",
|
|
middleware.RequirePermission("user:read"),
|
|
userController.GetUserByID)
|
|
|
|
management.PATCH("/admin/users/:id/role",
|
|
middleware.RequirePermission("user:update"),
|
|
userController.UpdateUserRole)
|
|
|
|
management.POST("/admin/users/:id/block",
|
|
middleware.RequirePermission("user:block"),
|
|
userController.BlockUser)
|
|
|
|
management.POST("/admin/users/:id/unblock",
|
|
middleware.RequirePermission("user:block"),
|
|
userController.UnblockUser)
|
|
|
|
management.DELETE("/admin/users/:id",
|
|
middleware.RequirePermission("user:block"), // Menggunakan permission block untuk delete
|
|
userController.DeleteUser)
|
|
|
|
// --- AUDIT LOGS (Permission: user:read - biasanya Admin) ---
|
|
management.GET("/admin/audit-logs",
|
|
middleware.RequirePermission("user:read"),
|
|
adminController.GetAuditLogs)
|
|
|
|
// --- CATEGORY MANAGEMENT (Permission: item:update - Admin Only usually) ---
|
|
// Note: Anda mungkin perlu menambahkan permission 'category:create' di seed.sql
|
|
// Untuk sekarang kita gunakan 'item:update' atau 'user:update' sebagai proxy
|
|
management.POST("/categories",
|
|
middleware.RequirePermission("user:update"),
|
|
categoryController.CreateCategory)
|
|
|
|
management.PUT("/categories/:id",
|
|
middleware.RequirePermission("user:update"),
|
|
categoryController.UpdateCategory)
|
|
|
|
management.DELETE("/categories/:id",
|
|
middleware.RequirePermission("user:update"),
|
|
categoryController.DeleteCategory)
|
|
|
|
// ✅ Endpoint baru untuk test Procedure SQL
|
|
management.POST("/admin/archive/trigger",
|
|
middleware.RequireRole("admin"), // Hanya admin
|
|
adminController.TriggerAutoArchive)
|
|
|
|
management.GET("/admin/dashboard/fast",
|
|
middleware.RequireRole("admin", "manager"),
|
|
adminController.GetFastDashboardStats)
|
|
|
|
management.GET("/admin/roles", middleware.RequireRole("admin"), roleController.GetRoles)
|
|
management.GET("/admin/permissions", middleware.RequireRole("admin"), roleController.GetPermissions)
|
|
management.POST("/admin/roles", middleware.RequireRole("admin"), roleController.CreateRole)
|
|
management.PUT("/admin/roles/:id", middleware.RequireRole("admin"), roleController.UpdateRole)
|
|
management.DELETE("/admin/roles/:id", middleware.RequireRole("admin"), roleController.DeleteRole)
|
|
}
|
|
}
|
|
}
|