add dukcapil

This commit is contained in:
Aditya Siregar
2026-05-07 04:01:32 +07:00
parent 9a975d146e
commit bc64eb20ea
235 changed files with 1197 additions and 28187 deletions
-2
View File
@@ -4,6 +4,4 @@ import "github.com/gin-gonic/gin"
type AuthHandler interface {
Login(c *gin.Context)
RefreshToken(c *gin.Context)
GetProfile(c *gin.Context)
}
+7
View File
@@ -0,0 +1,7 @@
package router
import "github.com/gin-gonic/gin"
type DukcapilHandler interface {
FaceMatch(c *gin.Context)
}
-182
View File
@@ -11,186 +11,4 @@ type UserHandler interface {
CreateUser(c *gin.Context)
UpdateUser(c *gin.Context)
DeleteUser(c *gin.Context)
GetProfile(c *gin.Context)
GetUserProfile(c *gin.Context)
UpdateProfile(c *gin.Context)
ChangePassword(c *gin.Context)
ChangeUserPassword(c *gin.Context)
ListTitles(c *gin.Context)
GetActiveUsersForMention(c *gin.Context)
}
type FileHandler interface {
UploadProfileAvatar(c *gin.Context)
UploadDocument(c *gin.Context)
UploadDocumentFinal(c *gin.Context)
}
type RBACHandler interface {
CreatePermission(c *gin.Context)
UpdatePermission(c *gin.Context)
DeletePermission(c *gin.Context)
ListPermissions(c *gin.Context)
CreateRole(c *gin.Context)
UpdateRole(c *gin.Context)
DeleteRole(c *gin.Context)
ListRoles(c *gin.Context)
// New methods
GetPermissionsGrouped(c *gin.Context)
CreateOrUpdateRole(c *gin.Context)
GetRoleDetail(c *gin.Context)
}
type MasterHandler interface {
// labels
CreateLabel(c *gin.Context)
UpdateLabel(c *gin.Context)
DeleteLabel(c *gin.Context)
ListLabels(c *gin.Context)
// priorities
CreatePriority(c *gin.Context)
UpdatePriority(c *gin.Context)
DeletePriority(c *gin.Context)
ListPriorities(c *gin.Context)
// institutions
CreateInstitution(c *gin.Context)
UpdateInstitution(c *gin.Context)
DeleteInstitution(c *gin.Context)
ListInstitutions(c *gin.Context)
// disposition actions
CreateDispositionAction(c *gin.Context)
UpdateDispositionAction(c *gin.Context)
DeleteDispositionAction(c *gin.Context)
ListDispositionActions(c *gin.Context)
// departments
ListDepartments(c *gin.Context)
CreateDepartment(c *gin.Context)
GetDepartment(c *gin.Context)
UpdateDepartment(c *gin.Context)
DeleteDepartment(c *gin.Context)
GetOrganizationalChart(c *gin.Context)
GetOrganizationalChartByID(c *gin.Context)
}
type LetterHandler interface {
CreateIncomingLetter(c *gin.Context)
GetIncomingLetter(c *gin.Context)
ListIncomingLetters(c *gin.Context)
SearchIncomingLetters(c *gin.Context)
GetLetterUnreadCounts(c *gin.Context)
MarkIncomingLetterAsRead(c *gin.Context)
MarkOutgoingLetterAsRead(c *gin.Context)
UpdateIncomingLetter(c *gin.Context)
DeleteIncomingLetter(c *gin.Context)
BulkDeleteIncomingLetters(c *gin.Context)
BulkArchiveIncomingLetters(c *gin.Context)
ArchiveIncomingLetter(c *gin.Context)
CreateDispositions(c *gin.Context)
GetEnhancedDispositionsByLetter(c *gin.Context)
GetDepartmentDispositionStatus(c *gin.Context)
UpdateDispositionStatus(c *gin.Context)
GetLetterCTA(c *gin.Context)
CreateDiscussion(c *gin.Context)
UpdateDiscussion(c *gin.Context)
}
type LetterOutgoingHandler interface {
CreateOutgoingLetter(c *gin.Context)
GetOutgoingLetter(c *gin.Context)
ListOutgoingLetters(c *gin.Context)
SearchOutgoingLetters(c *gin.Context)
UpdateOutgoingLetter(c *gin.Context)
DeleteOutgoingLetter(c *gin.Context)
BulkDeleteOutgoingLetters(c *gin.Context)
SubmitForApproval(c *gin.Context)
ApproveOutgoingLetter(c *gin.Context)
RejectOutgoingLetter(c *gin.Context)
ReviseOutgoingLetter(c *gin.Context)
SendOutgoingLetter(c *gin.Context)
ArchiveOutgoingLetter(c *gin.Context)
GetLetterApprovalInfo(c *gin.Context)
GetLetterApprovals(c *gin.Context)
AddRecipients(c *gin.Context)
UpdateRecipient(c *gin.Context)
RemoveRecipient(c *gin.Context)
AddAttachments(c *gin.Context)
RemoveAttachment(c *gin.Context)
AddFinalAttachments(c *gin.Context)
RemoveFinalAttachment(c *gin.Context)
CreateDiscussion(c *gin.Context)
UpdateDiscussion(c *gin.Context)
DeleteDiscussion(c *gin.Context)
GetApprovalDiscussions(c *gin.Context)
GetApprovalTimeline(c *gin.Context)
BulkArchiveOutgoingLetters(c *gin.Context)
}
type AdminApprovalFlowHandler interface {
CreateApprovalFlow(c *gin.Context)
GetApprovalFlow(c *gin.Context)
GetApprovalFlowByDepartment(c *gin.Context)
UpdateApprovalFlow(c *gin.Context)
DeleteApprovalFlow(c *gin.Context)
ListApprovalFlows(c *gin.Context)
ListApprovalFlowsByDepartment(c *gin.Context)
ActivateApprovalFlow(c *gin.Context)
DeactivateApprovalFlow(c *gin.Context)
CloneApprovalFlow(c *gin.Context)
}
type DispositionRouteHandler interface {
Create(c *gin.Context)
BulkCreateOrUpdate(c *gin.Context)
Update(c *gin.Context)
Get(c *gin.Context)
ListByFromDept(c *gin.Context)
SetActive(c *gin.Context)
ListGrouped(c *gin.Context)
ListAll(c *gin.Context)
}
type OnlyOfficeHandler interface {
ProcessCallback(c *gin.Context)
GetEditorConfig(c *gin.Context)
GetOnlyOfficeConfig(c *gin.Context)
LockDocument(c *gin.Context)
UnlockDocument(c *gin.Context)
GetDocumentSession(c *gin.Context)
}
type AnalyticsHandler interface {
GetDashboard(c *gin.Context)
GetLetterVolume(c *gin.Context)
GetStatusDistribution(c *gin.Context)
GetPriorityDistribution(c *gin.Context)
GetDepartmentStats(c *gin.Context)
GetMonthlyTrend(c *gin.Context)
GetApprovalMetrics(c *gin.Context)
}
type NotificationHandler interface {
TriggerNotification(c *gin.Context)
BulkTriggerNotification(c *gin.Context)
GetSubscriber(c *gin.Context)
UpdateSubscriberChannel(c *gin.Context)
TriggerNotificationForCurrentUser(c *gin.Context)
GetCurrentUserSubscriber(c *gin.Context)
UpdateCurrentUserSubscriberChannel(c *gin.Context)
}
type RepositoryAttachmentHandler interface {
CreateAttachment(c *gin.Context)
DeleteAttachment(c *gin.Context)
GetAttachment(c *gin.Context)
ListAttachment(c *gin.Context)
}
-9
View File
@@ -1,13 +1,4 @@
package router
import "github.com/gin-gonic/gin"
type AuthMiddleware interface {
RequireAuth() gin.HandlerFunc
RequireRole(allowedRoles ...string) gin.HandlerFunc
RequireAdminOrManager() gin.HandlerFunc
RequireAdmin() gin.HandlerFunc
RequireSuperAdmin() gin.HandlerFunc
RequireActiveUser() gin.HandlerFunc
RequirePermissions(required ...string) gin.HandlerFunc
}
+21 -269
View File
@@ -1,29 +1,19 @@
package router
import (
"eslogad-be/config"
"eslogad-be/internal/middleware"
"go-backend-template/config"
"go-backend-template/internal/middleware"
"github.com/gin-gonic/gin"
)
type Router struct {
config *config.Config
authHandler AuthHandler
healthHandler HealthHandler
authMiddleware AuthMiddleware
userHandler UserHandler
fileHandler FileHandler
rbacHandler RBACHandler
masterHandler MasterHandler
letterHandler LetterHandler
letterOutgoingHandler LetterOutgoingHandler
adminApprovalFlowHandler AdminApprovalFlowHandler
dispRouteHandler DispositionRouteHandler
onlyOfficeHandler OnlyOfficeHandler
analyticsHandler AnalyticsHandler
notificationHandler NotificationHandler
repositoryAttachmentHandler RepositoryAttachmentHandler
config *config.Config
authHandler AuthHandler
healthHandler HealthHandler
authMiddleware AuthMiddleware
userHandler UserHandler
dukcapilHandler DukcapilHandler
}
func NewRouter(
@@ -32,35 +22,15 @@ func NewRouter(
authMiddleware AuthMiddleware,
healthHandler HealthHandler,
userHandler UserHandler,
fileHandler FileHandler,
rbacHandler RBACHandler,
masterHandler MasterHandler,
letterHandler LetterHandler,
letterOutgoingHandler LetterOutgoingHandler,
adminApprovalFlowHandler AdminApprovalFlowHandler,
dispRouteHandler DispositionRouteHandler,
onlyOfficeHandler OnlyOfficeHandler,
analyticsHandler AnalyticsHandler,
notificationHandler NotificationHandler,
repositoryAttachmentHandler RepositoryAttachmentHandler,
dukcapilHandler DukcapilHandler,
) *Router {
return &Router{
config: cfg,
authHandler: authHandler,
authMiddleware: authMiddleware,
healthHandler: healthHandler,
userHandler: userHandler,
fileHandler: fileHandler,
rbacHandler: rbacHandler,
masterHandler: masterHandler,
letterHandler: letterHandler,
letterOutgoingHandler: letterOutgoingHandler,
adminApprovalFlowHandler: adminApprovalFlowHandler,
dispRouteHandler: dispRouteHandler,
onlyOfficeHandler: onlyOfficeHandler,
analyticsHandler: analyticsHandler,
notificationHandler: notificationHandler,
repositoryAttachmentHandler: repositoryAttachmentHandler,
config: cfg,
authHandler: authHandler,
authMiddleware: authMiddleware,
healthHandler: healthHandler,
userHandler: userHandler,
dukcapilHandler: dukcapilHandler,
}
}
@@ -85,235 +55,17 @@ func (r *Router) addAppRoutes(rg *gin.Engine) {
v1 := rg.Group("/api/v1")
{
auth := v1.Group("/auth")
{
auth.POST("/login", r.authHandler.Login)
auth.POST("/refresh", r.authHandler.RefreshToken)
auth.GET("/profile", r.authHandler.GetProfile)
}
users := v1.Group("/users")
users.Use(r.authMiddleware.RequireAuth())
{
users.POST("", r.userHandler.CreateUser)
users.GET("", r.userHandler.ListUsers)
users.PUT("/:id", r.userHandler.UpdateUser)
users.DELETE("/:id", r.userHandler.DeleteUser)
users.GET("/profile", r.userHandler.GetProfile)
users.GET("/:id/profile", r.userHandler.GetUserProfile)
users.PUT("/profile", r.userHandler.UpdateProfile)
users.PUT("/:id/password", r.userHandler.ChangePassword)
users.PUT("/:id/user-password", r.userHandler.ChangeUserPassword)
users.GET("/titles", r.userHandler.ListTitles)
users.GET("/mention", r.userHandler.GetActiveUsersForMention)
users.POST("/profile/avatar", r.fileHandler.UploadProfileAvatar)
}
files := v1.Group("/files")
files.Use(r.authMiddleware.RequireAuth())
{
files.POST("/documents", r.fileHandler.UploadDocument)
files.POST("/documents/final", r.fileHandler.UploadDocumentFinal)
}
rbac := v1.Group("/rbac")
rbac.Use(r.authMiddleware.RequireAuth())
{
rbac.GET("/permissions", r.rbacHandler.ListPermissions)
rbac.POST("/permissions", r.rbacHandler.CreatePermission)
rbac.PUT("/permissions/:id", r.rbacHandler.UpdatePermission)
rbac.DELETE("/permissions/:id", r.rbacHandler.DeletePermission)
rbac.GET("/roles", r.rbacHandler.ListRoles)
rbac.POST("/roles", r.rbacHandler.CreateRole)
rbac.PUT("/roles/:id", r.rbacHandler.UpdateRole)
rbac.DELETE("/roles/:id", r.rbacHandler.DeleteRole)
}
roles := v1.Group("/roles")
roles.Use(r.authMiddleware.RequireAuth())
{
roles.POST("", r.rbacHandler.CreateOrUpdateRole)
roles.GET("/permissions", r.rbacHandler.GetPermissionsGrouped)
roles.GET("/:id", r.rbacHandler.GetRoleDetail)
}
master := v1.Group("/master")
master.Use(r.authMiddleware.RequireAuth())
{
master.GET("/labels", r.masterHandler.ListLabels)
master.POST("/labels", r.masterHandler.CreateLabel)
master.PUT("/labels/:id", r.masterHandler.UpdateLabel)
master.DELETE("/labels/:id", r.masterHandler.DeleteLabel)
master.GET("/priorities", r.masterHandler.ListPriorities)
master.POST("/priorities", r.masterHandler.CreatePriority)
master.PUT("/priorities/:id", r.masterHandler.UpdatePriority)
master.DELETE("/priorities/:id", r.masterHandler.DeletePriority)
master.GET("/institutions", r.masterHandler.ListInstitutions)
master.POST("/institutions", r.masterHandler.CreateInstitution)
master.PUT("/institutions/:id", r.masterHandler.UpdateInstitution)
master.DELETE("/institutions/:id", r.masterHandler.DeleteInstitution)
master.GET("/disposition-actions", r.masterHandler.ListDispositionActions)
master.POST("/disposition-actions", r.masterHandler.CreateDispositionAction)
master.PUT("/disposition-actions/:id", r.masterHandler.UpdateDispositionAction)
master.DELETE("/disposition-actions/:id", r.masterHandler.DeleteDispositionAction)
master.POST("/departments", r.masterHandler.CreateDepartment)
master.GET("/departments", r.masterHandler.ListDepartments)
master.GET("/departments/chart", r.masterHandler.GetOrganizationalChart)
master.GET("/departments/:id", r.masterHandler.GetDepartment)
master.GET("/departments/:id/chart", r.masterHandler.GetOrganizationalChartByID)
master.PUT("/departments/:id", r.masterHandler.UpdateDepartment)
master.DELETE("/departments/:id", r.masterHandler.DeleteDepartment)
}
lettersch := v1.Group("/letters")
lettersch.Use(r.authMiddleware.RequireAuth())
{
lettersch.GET("/unread-counts", r.letterHandler.GetLetterUnreadCounts)
lettersch.GET("/incoming", r.letterHandler.ListIncomingLetters)
lettersch.GET("/incoming/search", r.letterHandler.SearchIncomingLetters)
lettersch.POST("/incoming", r.letterHandler.CreateIncomingLetter)
lettersch.GET("/incoming/cta/:letter_id", r.letterHandler.GetLetterCTA)
lettersch.GET("/incoming/:id", r.letterHandler.GetIncomingLetter)
lettersch.PUT("/incoming/:id", r.letterHandler.UpdateIncomingLetter)
lettersch.PUT("/incoming/:id/read", r.letterHandler.MarkIncomingLetterAsRead)
lettersch.DELETE("/incoming/:id", r.letterHandler.DeleteIncomingLetter)
lettersch.DELETE("/incoming/delete", r.letterHandler.BulkDeleteIncomingLetters)
lettersch.POST("/incoming/archive", r.letterHandler.BulkArchiveIncomingLetters)
lettersch.PUT("/incoming/:id/archive", r.letterHandler.ArchiveIncomingLetter)
lettersch.POST("/outgoing", r.letterOutgoingHandler.CreateOutgoingLetter)
lettersch.GET("/outgoing/search", r.letterOutgoingHandler.SearchOutgoingLetters)
lettersch.GET("/outgoing/:id", r.letterOutgoingHandler.GetOutgoingLetter)
lettersch.GET("/outgoing", r.letterOutgoingHandler.ListOutgoingLetters)
lettersch.PUT("/outgoing/:id", r.letterOutgoingHandler.UpdateOutgoingLetter)
lettersch.PUT("/outgoing/:id/read", r.letterHandler.MarkOutgoingLetterAsRead)
lettersch.DELETE("/outgoing/:id", r.letterOutgoingHandler.DeleteOutgoingLetter)
lettersch.DELETE("/outgoing/delete", r.letterOutgoingHandler.BulkDeleteOutgoingLetters)
lettersch.POST("/outgoing/:id/submit", r.letterOutgoingHandler.SubmitForApproval)
lettersch.POST("/outgoing/:id/approve", r.letterOutgoingHandler.ApproveOutgoingLetter)
lettersch.POST("/outgoing/:id/reject", r.letterOutgoingHandler.RejectOutgoingLetter)
lettersch.POST("/outgoing/:id/revise", r.letterOutgoingHandler.ReviseOutgoingLetter)
lettersch.POST("/outgoing/:id/send", r.letterOutgoingHandler.SendOutgoingLetter)
lettersch.POST("/outgoing/:id/archive", r.letterOutgoingHandler.ArchiveOutgoingLetter)
lettersch.POST("/outgoing/archive", r.letterOutgoingHandler.BulkArchiveOutgoingLetters)
lettersch.GET("/outgoing/:id/cta", r.letterOutgoingHandler.GetLetterApprovalInfo)
lettersch.GET("/outgoing/:id/approvals", r.letterOutgoingHandler.GetLetterApprovals)
lettersch.POST("/outgoing/:id/recipients", r.letterOutgoingHandler.AddRecipients)
lettersch.PUT("/outgoing/:id/recipients/:recipient_id", r.letterOutgoingHandler.UpdateRecipient)
lettersch.DELETE("/outgoing/:id/recipients/:recipient_id", r.letterOutgoingHandler.RemoveRecipient)
lettersch.POST("/outgoing/:id/attachments", r.letterOutgoingHandler.AddAttachments)
lettersch.DELETE("/outgoing/:id/attachments/:attachment_id", r.letterOutgoingHandler.RemoveAttachment)
lettersch.POST("/outgoing/:id/attachments/final", r.letterOutgoingHandler.AddFinalAttachments)
lettersch.DELETE("/outgoing/:id/attachments/final/:attachment_id", r.letterOutgoingHandler.RemoveFinalAttachment)
lettersch.POST("/outgoing/:id/discussions", r.letterOutgoingHandler.CreateDiscussion)
lettersch.PUT("/outgoing/discussions/:discussion_id", r.letterOutgoingHandler.UpdateDiscussion)
lettersch.DELETE("/outgoing/discussions/:discussion_id", r.letterOutgoingHandler.DeleteDiscussion)
lettersch.GET("/outgoing/:id/approval-discussions", r.letterOutgoingHandler.GetApprovalDiscussions)
lettersch.GET("/outgoing/:id/timeline", r.letterOutgoingHandler.GetApprovalTimeline)
lettersch.POST("/dispositions/:letter_id", r.letterHandler.CreateDispositions)
lettersch.GET("/dispositions/:letter_id", r.letterHandler.GetEnhancedDispositionsByLetter)
lettersch.GET("/dispositions/:letter_id/department/status", r.letterHandler.GetDepartmentDispositionStatus)
lettersch.PUT("/dispositions/:letter_id/status", r.letterHandler.UpdateDispositionStatus)
lettersch.POST("/discussions/:letter_id", r.letterHandler.CreateDiscussion)
lettersch.PUT("/discussions/:letter_id/:discussion_id", r.letterHandler.UpdateDiscussion)
}
droutes := v1.Group("/disposition-routes")
droutes.Use(r.authMiddleware.RequireAuth())
{
droutes.POST("", r.dispRouteHandler.Create) // Create with upsert logic
droutes.PUT("/bulk", r.dispRouteHandler.BulkCreateOrUpdate) // Explicit bulk create/update
droutes.GET("", r.dispRouteHandler.ListAll) // List all routes with details
droutes.GET("/grouped", r.dispRouteHandler.ListGrouped) // List grouped by from_department_id
droutes.GET("/department", r.dispRouteHandler.ListByFromDept)
droutes.GET("/:id", r.dispRouteHandler.Get)
droutes.PUT("/:id", r.dispRouteHandler.Update)
droutes.PUT("/:id/active", r.dispRouteHandler.SetActive)
}
repoattachsch := v1.Group("/repository-attachments")
repoattachsch.Use(r.authMiddleware.RequireAuth())
{
repoattachsch.POST("", r.repositoryAttachmentHandler.CreateAttachment)
repoattachsch.GET("", r.repositoryAttachmentHandler.ListAttachment)
repoattachsch.DELETE("/:id", r.repositoryAttachmentHandler.DeleteAttachment)
repoattachsch.GET("/:id", r.repositoryAttachmentHandler.GetAttachment)
}
admin := v1.Group("/setting")
admin.Use(r.authMiddleware.RequireAuth())
{
approvalFlows := admin.Group("/approval-flows")
if r.authHandler != nil {
auth := v1.Group("/auth")
{
approvalFlows.POST("", r.adminApprovalFlowHandler.CreateApprovalFlow)
approvalFlows.GET("", r.adminApprovalFlowHandler.ListApprovalFlows)
approvalFlows.GET("/department", r.adminApprovalFlowHandler.ListApprovalFlowsByDepartment)
approvalFlows.GET("/:id", r.adminApprovalFlowHandler.GetApprovalFlow)
approvalFlows.GET("/department/:department_id", r.adminApprovalFlowHandler.GetApprovalFlowByDepartment)
approvalFlows.PUT("/:id", r.adminApprovalFlowHandler.UpdateApprovalFlow)
approvalFlows.DELETE("/:id", r.adminApprovalFlowHandler.DeleteApprovalFlow)
approvalFlows.POST("/:id/activate", r.adminApprovalFlowHandler.ActivateApprovalFlow)
approvalFlows.POST("/:id/deactivate", r.adminApprovalFlowHandler.DeactivateApprovalFlow)
approvalFlows.POST("/:id/clone", r.adminApprovalFlowHandler.CloneApprovalFlow)
auth.POST("/login", r.authHandler.Login)
}
}
onlyoffice := v1.Group("/onlyoffice")
{
onlyoffice.POST("/callback/:key", r.onlyOfficeHandler.ProcessCallback)
onlyofficeAuth := onlyoffice.Group("")
onlyofficeAuth.Use(r.authMiddleware.RequireAuth())
if r.dukcapilHandler != nil {
dukcapil := v1.Group("/dukcapil")
{
onlyofficeAuth.POST("/config", r.onlyOfficeHandler.GetEditorConfig)
onlyofficeAuth.GET("/settings", r.onlyOfficeHandler.GetOnlyOfficeConfig)
onlyofficeAuth.POST("/lock/:id", r.onlyOfficeHandler.LockDocument)
onlyofficeAuth.POST("/unlock/:id", r.onlyOfficeHandler.UnlockDocument)
onlyofficeAuth.GET("/session/:key", r.onlyOfficeHandler.GetDocumentSession)
}
}
analytics := v1.Group("/analytics")
analytics.Use(r.authMiddleware.RequireAuth())
{
analytics.GET("/dashboard", r.analyticsHandler.GetDashboard)
analytics.GET("/volume", r.analyticsHandler.GetLetterVolume)
analytics.GET("/status-distribution", r.analyticsHandler.GetStatusDistribution)
analytics.GET("/priority-distribution", r.analyticsHandler.GetPriorityDistribution)
analytics.GET("/department-stats", r.analyticsHandler.GetDepartmentStats)
analytics.GET("/monthly-trend", r.analyticsHandler.GetMonthlyTrend)
analytics.GET("/approval-metrics", r.analyticsHandler.GetApprovalMetrics)
}
notifications := v1.Group("/notifications")
notifications.Use(r.authMiddleware.RequireAuth())
{
notifications.POST("/me/trigger", r.notificationHandler.TriggerNotificationForCurrentUser)
notifications.GET("/me/subscriber", r.notificationHandler.GetCurrentUserSubscriber)
notifications.PUT("/me/channel", r.notificationHandler.UpdateCurrentUserSubscriberChannel)
notifAdmin := notifications.Group("")
notifAdmin.Use(r.authMiddleware.RequirePermissions("notification.admin"))
{
notifAdmin.POST("/trigger", r.notificationHandler.TriggerNotification)
notifAdmin.POST("/bulk-trigger", r.notificationHandler.BulkTriggerNotification)
notifAdmin.GET("/subscribers/:userId", r.notificationHandler.GetSubscriber)
notifAdmin.PUT("/subscribers/channel", r.notificationHandler.UpdateSubscriberChannel)
dukcapil.POST("/face-match", r.dukcapilHandler.FaceMatch)
}
}
}