endpoint user role

This commit is contained in:
renaldybrada
2026-02-25 10:43:54 +07:00
parent 6ac3798ea8
commit 35667518a7
9 changed files with 367 additions and 3 deletions
+67
View File
@@ -46,6 +46,53 @@ const docTemplate = `{
}
}
},
"/access/list-user": {
"get": {
"tags": [
"Access Role"
],
"summary": "Get List User And Role",
"parameters": [
{
"type": "string",
"description": "Search Keyword",
"name": "search",
"in": "query"
},
{
"type": "string",
"default": "10",
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "string",
"default": "0",
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/access.UserRoleResponse"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/shared.BaseErrorResponse"
}
}
}
}
},
"/access/sync-keycloak-role": {
"post": {
"tags": [
@@ -879,6 +926,26 @@ const docTemplate = `{
}
}
},
"access.UserRoleResponse": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"hak_akses": {
"type": "array",
"items": {
"type": "string"
}
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"antrianoperasi.CreatePasienOperasiRequest": {
"type": "object",
"required": [
+67
View File
@@ -40,6 +40,53 @@
}
}
},
"/access/list-user": {
"get": {
"tags": [
"Access Role"
],
"summary": "Get List User And Role",
"parameters": [
{
"type": "string",
"description": "Search Keyword",
"name": "search",
"in": "query"
},
{
"type": "string",
"default": "10",
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "string",
"default": "0",
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/access.UserRoleResponse"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/shared.BaseErrorResponse"
}
}
}
}
},
"/access/sync-keycloak-role": {
"post": {
"tags": [
@@ -873,6 +920,26 @@
}
}
},
"access.UserRoleResponse": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"hak_akses": {
"type": "array",
"items": {
"type": "string"
}
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"antrianoperasi.CreatePasienOperasiRequest": {
"type": "object",
"required": [
+44
View File
@@ -17,6 +17,19 @@ definitions:
- keycloak_id
- name
type: object
access.UserRoleResponse:
properties:
email:
type: string
hak_akses:
items:
type: string
type: array
id:
type: string
name:
type: string
type: object
antrianoperasi.CreatePasienOperasiRequest:
properties:
diagnosisItems:
@@ -469,6 +482,37 @@ paths:
summary: Get Pages By Keycloak Id
tags:
- Access Role
/access/list-user:
get:
parameters:
- description: Search Keyword
in: query
name: search
type: string
- default: "10"
description: Limit
in: query
name: limit
type: string
- default: "0"
description: Offset
in: query
name: offset
type: string
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/access.UserRoleResponse'
type: array
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/shared.BaseErrorResponse'
summary: Get List User And Role
tags:
- Access Role
/access/sync-keycloak-role:
post:
parameters:
+44
View File
@@ -104,3 +104,47 @@ func (h AccessHandler) GetPageByKeycloakId(c *gin.Context) {
Data: MapMenuModelToResponse(pageResult),
})
}
// ListUserRole godoc
// @Summary Get List User And Role
// @Tags Access Role
// @Param search query string false "Search Keyword"
// @Param limit query string false "Limit" default(10)
// @Param offset query string false "Offset" default(0)
// @Success 200 {object} []UserRoleResponse
// @Failure 500 {object} shared.BaseErrorResponse
// @Router /access/list-user [get]
func (h AccessHandler) ListUserRole(c *gin.Context) {
var query QueryListUserRole
if err := c.ShouldBindQuery(&query); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
res, err := h.repo.ListUserRole(c.Request.Context(), query)
if err != nil {
c.JSON(500, shared.BaseErrorResponse{
Success: false,
Code: 500,
Message: err.Error(),
})
return
}
c.JSON(200,
shared.ToBaseResponsePaginate(
res.Data, res.Paging, true, 200, "success get list user role",
))
}
func (h AccessHandler) ListRolePageSettings(c *gin.Context) {
}
func (h AccessHandler) DetailRolePageSettings(c *gin.Context) {
}
func (h AccessHandler) UpdateRolePageSettings(c *gin.Context) {
}
+4 -3
View File
@@ -26,9 +26,10 @@ type RoleUserModel struct {
}
type RoleUserPermissionModel struct {
ID string `db:"id"`
IdUser string `db:"id_user"`
IdPermission string `db:"id_permission"`
ID string `db:"id"`
IdUser string `db:"id_user"`
IdPermission string `db:"id_permission"`
PermissionName *string `db:"permission_name"`
}
type RolePagePermissionModel struct {
+120
View File
@@ -24,6 +24,7 @@ type IAccessRepository interface {
CreateUserPermission(c context.Context, req SyncKeycloakRoleRequest) error
UpdateUserPermission(c context.Context, userId string, req SyncKeycloakRoleRequest) error
GetAvailablePageByKeycloakId(c context.Context, keycloakId string) ([]RolePageModel, error)
ListUserRole(c context.Context, q QueryListUserRole) (ListUserRolePaginateResponse, error)
}
type accessRepo struct {
@@ -182,6 +183,81 @@ func (r accessRepo) GetAvailablePageByKeycloakId(c context.Context, keycloakId s
return result, nil
}
func (r accessRepo) ListUserRole(c context.Context, q QueryListUserRole) (ListUserRolePaginateResponse, error) {
var result ListUserRolePaginateResponse
query := queryUtils.DynamicQuery{
From: TBL_USER,
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "name"},
{Expression: "email"},
},
Sort: []queryUtils.SortField{
{Column: "created_at", Order: "DESC"},
},
}
if q.Search != "" {
searchFilters := []queryUtils.DynamicFilter{
{Column: "name", Operator: queryUtils.OpILike, Value: "%" + q.Search + "%"},
{Column: "email", Operator: queryUtils.OpILike, Value: "%" + q.Search + "%"},
}
query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: searchFilters, LogicOp: "OR"})
}
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
log.Printf("Unable to connect db : %s", err)
return result, err
}
// query count
countData, err := r.queryBuilder.ExecuteCount(c, dbconn, query)
if err != nil {
log.Printf("Unable to execute query count : %s ", err)
return result, err
}
result.Paging.Limit = q.Limit
result.Paging.Offset = q.Offset
result.Paging.Total = int(countData)
result.Paging.CalculatePagingInfo()
// query data
queryData := query
queryData.Limit = q.Limit
queryData.Offset = q.Offset
err = r.queryBuilder.ExecuteQuery(
c, dbconn, queryData, &result.Data)
if err != nil {
log.Printf("Unable to execute query data : %s", err)
return result, err
}
userIds := make([]string, 0, len(result.Data))
for _, item := range result.Data {
userIds = append(userIds, item.ID)
}
// fetch role
userPermission, err := r.getPermissionNameByUserIds(c, dbconn, userIds)
if err != nil {
return result, err
}
groupPermissionByUser := make(map[string][]string)
for _, p := range userPermission {
groupPermissionByUser[p.IdUser] = append(groupPermissionByUser[p.IdUser], *p.PermissionName)
}
// join result with role
for idx := range result.Data {
result.Data[idx].HakAkses = groupPermissionByUser[result.Data[idx].ID]
}
return result, nil
}
// PRIVATE FUNCTIONS
// Table user function
@@ -424,6 +500,50 @@ func (r accessRepo) getUserPermissionByUserId(c context.Context, db *sqlx.DB, us
return result, nil
}
func (r accessRepo) getPermissionNameByUserIds(c context.Context, db *sqlx.DB, userIds []string) ([]RoleUserPermissionModel, error) {
var result []RoleUserPermissionModel
query := queryUtils.DynamicQuery{
From: TBL_USER_PERMISSION,
Aliases: "up",
Fields: []queryUtils.SelectField{
{Expression: "up.id", Alias: "id"},
{Expression: "up.id_user", Alias: "id_user"},
{Expression: "up.id_permission", Alias: "id_permission"},
{Expression: "p.name", Alias: "permission_name"},
},
Joins: []queryUtils.Join{
{
Type: "LEFT",
Table: TBL_PERMISSION,
Alias: "p",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "p.id", Operator: queryUtils.OpEqual, Value: "up.id_permission",
},
},
},
},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "id_user", Operator: queryUtils.OpIn, Value: userIds},
}, LogicOp: "AND",
},
},
}
err := r.queryBuilder.ExecuteQuery(c, db, query, &result)
if err != nil {
log.Printf("error executing fetch user permission : %v", err)
return nil, err
}
return result, nil
}
// End Table user permission functions
// Table role page permission functions
+6
View File
@@ -12,3 +12,9 @@ type UpsertAccessPermissionRequest struct {
Status string `json:"status"`
Pages []string `json:"pages"`
}
type QueryListUserRole struct {
Search string `form:"search"`
Limit int `form:"limit,default=10"`
Offset int `form:"offset,default=0"`
}
+14
View File
@@ -1,5 +1,7 @@
package access
import "antrian-operasi/internal/shared"
type AvailableMenuChildResponse struct {
Title string `json:"title"`
Icon string `json:"icon"`
@@ -42,3 +44,15 @@ func MapMenuModelToResponse(pages []RolePageModel) []AvailableMenuResponse {
return result
}
type UserRoleResponse struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
HakAkses []string `json:"hak_akses"`
}
type ListUserRolePaginateResponse struct {
Data []UserRoleResponse
Paging shared.PaginationInfo
}
+1
View File
@@ -12,4 +12,5 @@ func RegisterRoutes(r *gin.RouterGroup, dbService database.Service) {
r.POST("/sync-keycloak-role", accessHandler.SyncKeycloakRole)
r.GET("/eligible-menu", accessHandler.GetPageByKeycloakId)
r.GET("/list-user", accessHandler.ListUserRole)
}