From 42267aa1afc0d4c56bb42d94f988be0408896e42 Mon Sep 17 00:00:00 2001 From: renaldybrada Date: Wed, 25 Feb 2026 14:32:22 +0700 Subject: [PATCH] endpoint update page role settings --- docs/docs.go | 71 +++++++++++++++++++ docs/swagger.json | 71 +++++++++++++++++++ docs/swagger.yaml | 47 ++++++++++++ internal/domain/access/handler.go | 34 +++++++++ internal/domain/access/repository.go | 102 ++++++++++++++++++++++++++- internal/domain/access/request.go | 2 + internal/domain/access/response.go | 8 ++- internal/domain/access/routes.go | 1 + 8 files changed, 332 insertions(+), 4 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index eecc7df..23a1678 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -166,6 +166,44 @@ const docTemplate = `{ } } } + }, + "put": { + "tags": [ + "Access Role" + ], + "summary": "Update Role Page Settings", + "parameters": [ + { + "type": "string", + "description": "id role", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body Update Role Page", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/access.UpdateRolePageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/shared.BaseResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/shared.BaseErrorResponse" + } + } + } } }, "/access/sync-keycloak-role": { @@ -978,6 +1016,10 @@ const docTemplate = `{ "definitions": { "access.AccessPage": { "type": "object", + "required": [ + "id", + "is_active" + ], "properties": { "id": { "type": "string" @@ -990,11 +1032,17 @@ const docTemplate = `{ }, "parent_id": { "type": "string" + }, + "sort": { + "type": "integer" } } }, "access.DetailRolePageResponse": { "type": "object", + "required": [ + "id" + ], "properties": { "access_page": { "type": "array", @@ -1066,6 +1114,29 @@ const docTemplate = `{ } } }, + "access.UpdateRolePageRequest": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "access_page": { + "type": "array", + "items": { + "$ref": "#/definitions/access.AccessPage" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "boolean" + } + } + }, "access.UserRoleResponse": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index ad2923a..6fb8f4f 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -160,6 +160,44 @@ } } } + }, + "put": { + "tags": [ + "Access Role" + ], + "summary": "Update Role Page Settings", + "parameters": [ + { + "type": "string", + "description": "id role", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body Update Role Page", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/access.UpdateRolePageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/shared.BaseResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/shared.BaseErrorResponse" + } + } + } } }, "/access/sync-keycloak-role": { @@ -972,6 +1010,10 @@ "definitions": { "access.AccessPage": { "type": "object", + "required": [ + "id", + "is_active" + ], "properties": { "id": { "type": "string" @@ -984,11 +1026,17 @@ }, "parent_id": { "type": "string" + }, + "sort": { + "type": "integer" } } }, "access.DetailRolePageResponse": { "type": "object", + "required": [ + "id" + ], "properties": { "access_page": { "type": "array", @@ -1060,6 +1108,29 @@ } } }, + "access.UpdateRolePageRequest": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "access_page": { + "type": "array", + "items": { + "$ref": "#/definitions/access.AccessPage" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "boolean" + } + } + }, "access.UserRoleResponse": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 914d0ac..9fa930e 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -10,6 +10,11 @@ definitions: type: string parent_id: type: string + sort: + type: integer + required: + - id + - is_active type: object access.DetailRolePageResponse: properties: @@ -23,6 +28,8 @@ definitions: type: string status: type: boolean + required: + - id type: object access.ListRolePermissionPaginateResponse: properties: @@ -59,6 +66,21 @@ definitions: - keycloak_id - name type: object + access.UpdateRolePageRequest: + properties: + access_page: + items: + $ref: '#/definitions/access.AccessPage' + type: array + id: + type: string + name: + type: string + status: + type: boolean + required: + - id + type: object access.UserRoleResponse: properties: email: @@ -621,6 +643,31 @@ paths: summary: Detail Role Page Settings tags: - Access Role + put: + parameters: + - description: id role + in: path + name: id + required: true + type: string + - description: Body Update Role Page + in: body + name: body + required: true + schema: + $ref: '#/definitions/access.UpdateRolePageRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/shared.BaseResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/shared.BaseErrorResponse' + summary: Update Role Page Settings + tags: + - Access Role /access/sync-keycloak-role: post: parameters: diff --git a/internal/domain/access/handler.go b/internal/domain/access/handler.go index ba82a87..b4aa35d 100644 --- a/internal/domain/access/handler.go +++ b/internal/domain/access/handler.go @@ -195,6 +195,40 @@ func (h AccessHandler) DetailRolePageSettings(c *gin.Context) { )) } +// UpdateRolePageSettings godoc +// @Summary Update Role Page Settings +// @Tags Access Role +// @Param id path string true "id role" +// @Param body body UpdateRolePageRequest true "Body Update Role Page" +// @Success 200 {object} shared.BaseResponse +// @Failure 500 {object} shared.BaseErrorResponse +// @Router /access/role-permission/{id} [put] func (h AccessHandler) UpdateRolePageSettings(c *gin.Context) { + var req UpdateRolePageRequest + //bind json body + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(400, shared.BaseErrorResponse{ + Success: false, + Code: 400, + Message: "error bind json", + Errors: shared.ValidationError(err), + }) + return + } + + err := h.repo.UpdateRolePermission(c, req) + if err != nil { + c.JSON(500, shared.BaseErrorResponse{ + Success: false, + Code: 500, + Message: err.Error(), + }) + return + } + + c.JSON(200, + shared.ToBaseResponse( + "", true, 200, "success update role permission", + )) } diff --git a/internal/domain/access/repository.go b/internal/domain/access/repository.go index dd42015..e4aba98 100644 --- a/internal/domain/access/repository.go +++ b/internal/domain/access/repository.go @@ -27,6 +27,7 @@ type IAccessRepository interface { ListUserRole(c context.Context, q QueryListUserRole) (ListUserRolePaginateResponse, error) ListRolePermission(c context.Context, q QueryListRolePermission) (ListRolePermissionPaginateResponse, error) DetailRolePermission(c context.Context, permission_id string) (DetailRolePageResponse, error) + UpdateRolePermission(c context.Context, req UpdateRolePageRequest) error } type accessRepo struct { @@ -36,7 +37,7 @@ type accessRepo struct { func NewRepository(dbService database.Service) IAccessRepository { queryBuilder := queryUtils.NewQueryBuilder(queryUtils.DBTypePostgreSQL).SetAllowedColumns([]string{ - "id", "name", "is_active", "keycloak_id", "id_user", "id_permission", "email", "created_at", + "id", "name", "is_active", "keycloak_id", "id_user", "id_permission", "email", "created_at", "id_page", }).SetAllowedTables([]string{TBL_USER}) queryBuilder.SetSecurityOptions(false, 100) @@ -373,6 +374,7 @@ func (r accessRepo) DetailRolePermission(c context.Context, permission_id string ID: p.ID, Page: p.Name, IsActive: isActive, + Sort: p.Sort, ParentId: &p.ParentId.String, }) } @@ -380,6 +382,44 @@ func (r accessRepo) DetailRolePermission(c context.Context, permission_id string return result, nil } +func (r accessRepo) UpdateRolePermission(c context.Context, req UpdateRolePageRequest) error { + db, err := r.db.GetSQLXDB(DB_NAME) + if err != nil { + return err + } + + // START TRANSACTION + tx, err := db.BeginTx(c, nil) + if err != nil { + return err + } + + // delete all page permission by permission id + err = r.deletePageIdsByPermissionId(c, tx, req.ID) + if err != nil { + tx.Rollback() + return err + } + + // select active page + var pageIds []string + for _, page := range req.AccessPage { + if page.IsActive { + pageIds = append(pageIds, page.ID) + } + } + // inserting new permission + err = r.insertPagePermission(c, tx, req.ID, pageIds) + if err != nil { + tx.Rollback() + return err + } + + tx.Commit() + + return nil +} + // PRIVATE FUNCTIONS // Table user function @@ -698,6 +738,66 @@ func (r accessRepo) getPageIdsByPermissionIds(c context.Context, db *sqlx.DB, pe return result, nil } +func (r accessRepo) deletePageIdsByPermissionId(c context.Context, tx *sql.Tx, permissionId string) error { + filters := []queryUtils.FilterGroup{ + { + Filters: []queryUtils.DynamicFilter{ + {Column: "id_permission", Operator: queryUtils.OpEqual, Value: permissionId}, + }, + }, + } + sql, args, err := r.queryBuilder.BuildDeleteQuery(TBL_PAGE_PERMISSION, filters) + if err != nil { + log.Printf("Unable to create delete page permission query : %v", err) + return err + } + _, err = tx.ExecContext(c, sql, args...) + if err != nil { + log.Printf("Unable to executing delete page permission : %v", err) + return err + } + return nil +} + +func (r accessRepo) insertPagePermission(c context.Context, tx *sql.Tx, permissionId string, pageIds []string) error { + if len(pageIds) > 0 { + var valueUserPermission [][]interface{} + + for _, pageId := range pageIds { + id := uuid.New().String() + itemValues := []interface{}{id, permissionId, pageId} + + valueUserPermission = append(valueUserPermission, itemValues) + } + + insertPagePermissionQuery := queryUtils.InsertBulkData{ + Columns: []string{ + "id", "id_permission", "id_page", + }, + Values: valueUserPermission, + } + + returningCols := []string{ + "id", + } + sql, args, err := r.queryBuilder.BuildBulkInsertQuery(TBL_PAGE_PERMISSION, insertPagePermissionQuery, returningCols...) + if err != nil { + log.Printf("error building query insert page permission %s", err) + + return err + } + _, err = tx.ExecContext(c, sql, args...) + if err != nil { + log.Println(err) + return err + } + log.Printf(sql, args) + log.Printf("success insert page permission") + } + + return nil +} + // End role page permission functions // Table pages functions diff --git a/internal/domain/access/request.go b/internal/domain/access/request.go index 2dfc326..fc6667b 100644 --- a/internal/domain/access/request.go +++ b/internal/domain/access/request.go @@ -24,3 +24,5 @@ type QueryListRolePermission struct { Limit int `form:"limit,default=10"` Offset int `form:"offset,default=0"` } + +type UpdateRolePageRequest DetailRolePageResponse diff --git a/internal/domain/access/response.go b/internal/domain/access/response.go index 2155ef4..7a3005c 100644 --- a/internal/domain/access/response.go +++ b/internal/domain/access/response.go @@ -63,13 +63,15 @@ type ListRolePermissionPaginateResponse struct { } type AccessPage struct { - ID string `json:"id"` + ID string `json:"id" binding:"required"` Page string `json:"page"` - IsActive bool `json:"is_active"` + IsActive bool `json:"is_active" binding:"required"` + Sort int `json:"sort"` ParentId *string `json:"parent_id"` } + type DetailRolePageResponse struct { - ID string `json:"id" db:"id"` + ID string `json:"id" db:"id" binding:"required"` Name string `json:"name" db:"name"` Status bool `json:"status" db:"is_active"` AccessPage []AccessPage `json:"access_page"` diff --git a/internal/domain/access/routes.go b/internal/domain/access/routes.go index b382ea7..83a05e6 100644 --- a/internal/domain/access/routes.go +++ b/internal/domain/access/routes.go @@ -16,4 +16,5 @@ func RegisterRoutes(r *gin.RouterGroup, dbService database.Service) { r.GET("/role-permission", accessHandler.ListRolePageSettings) r.GET("/role-permission/:id", accessHandler.DetailRolePageSettings) + r.PUT("/role-permission/:id", accessHandler.UpdateRolePageSettings) }