package repository import ( dbgen "Yimaru-Backend/gen/db" "Yimaru-Backend/internal/domain" "Yimaru-Backend/internal/ports" "context" "github.com/jackc/pgx/v5/pgtype" ) func NewRBACStore(s *Store) ports.RBACStore { return s } func (s *Store) CreateRole(ctx context.Context, name, description string, isSystem bool) (domain.RoleRecord, error) { r, err := s.queries.CreateRole(ctx, dbgen.CreateRoleParams{ Name: name, Description: description, IsSystem: isSystem, }) if err != nil { return domain.RoleRecord{}, err } return mapRole(r), nil } func (s *Store) GetRoleByID(ctx context.Context, id int64) (domain.RoleRecord, error) { r, err := s.queries.GetRoleByID(ctx, id) if err != nil { return domain.RoleRecord{}, err } return mapRole(r), nil } func (s *Store) GetRoleByName(ctx context.Context, name string) (domain.RoleRecord, error) { r, err := s.queries.GetRoleByName(ctx, name) if err != nil { return domain.RoleRecord{}, err } return mapRole(r), nil } func (s *Store) ListRoles(ctx context.Context, filter domain.RoleListFilter) ([]domain.RoleRecord, int64, error) { var queryParam pgtype.Text if filter.Query != "" { queryParam = pgtype.Text{String: filter.Query, Valid: true} } var isSystemParam pgtype.Bool if filter.IsSystem != nil { isSystemParam = pgtype.Bool{Bool: *filter.IsSystem, Valid: true} } limit := int32(filter.PageSize) if limit <= 0 { limit = 20 } offset := int32(filter.Page * filter.PageSize) rows, err := s.queries.ListRoles(ctx, dbgen.ListRolesParams{ Query: queryParam, IsSystem: isSystemParam, Limit: pgtype.Int4{Int32: limit, Valid: true}, Offset: pgtype.Int4{Int32: offset, Valid: true}, }) if err != nil { return nil, 0, err } if len(rows) == 0 { return []domain.RoleRecord{}, 0, nil } totalCount := rows[0].TotalCount roles := make([]domain.RoleRecord, len(rows)) for i, r := range rows { rec := domain.RoleRecord{ ID: r.ID, Name: r.Name, Description: r.Description, IsSystem: r.IsSystem, CreatedAt: r.CreatedAt.Time, } if r.UpdatedAt.Valid { rec.UpdatedAt = &r.UpdatedAt.Time } roles[i] = rec } return roles, totalCount, nil } func (s *Store) UpdateRole(ctx context.Context, id int64, name, description string) error { return s.queries.UpdateRole(ctx, dbgen.UpdateRoleParams{ ID: id, Name: name, Description: description, }) } func (s *Store) DeleteRole(ctx context.Context, id int64) error { return s.queries.DeleteRole(ctx, id) } func (s *Store) UpsertPermission(ctx context.Context, seed domain.PermissionSeed) (domain.Permission, error) { p, err := s.queries.UpsertPermission(ctx, dbgen.UpsertPermissionParams{ Key: seed.Key, Name: seed.Name, Description: seed.Description, GroupName: seed.GroupName, }) if err != nil { return domain.Permission{}, err } return mapPermission(p), nil } func (s *Store) ListPermissions(ctx context.Context) ([]domain.Permission, error) { rows, err := s.queries.ListPermissions(ctx) if err != nil { return nil, err } perms := make([]domain.Permission, len(rows)) for i, p := range rows { perms[i] = mapPermission(p) } return perms, nil } func (s *Store) ListPermissionGroups(ctx context.Context) ([]string, error) { return s.queries.ListPermissionGroups(ctx) } func (s *Store) GetPermissionByKey(ctx context.Context, key string) (domain.Permission, error) { p, err := s.queries.GetPermissionByKey(ctx, key) if err != nil { return domain.Permission{}, err } return mapPermission(p), nil } func (s *Store) SetRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error { if err := s.queries.SetRolePermissions(ctx, roleID); err != nil { return err } if len(permissionIDs) > 0 { return s.queries.BulkAssignPermissionsToRole(ctx, dbgen.BulkAssignPermissionsToRoleParams{ RoleID: roleID, Column2: permissionIDs, }) } return nil } func (s *Store) GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error) { rows, err := s.queries.GetRolePermissions(ctx, roleID) if err != nil { return nil, err } perms := make([]domain.Permission, len(rows)) for i, p := range rows { perms[i] = mapPermission(p) } return perms, nil } func (s *Store) GetAllRolesWithPermissions(ctx context.Context) (map[string]map[string]struct{}, error) { rows, err := s.queries.GetAllRolesWithPermissions(ctx) if err != nil { return nil, err } result := make(map[string]map[string]struct{}) for _, row := range rows { if _, ok := result[row.RoleName]; !ok { result[row.RoleName] = make(map[string]struct{}) } result[row.RoleName][row.PermissionKey] = struct{}{} } return result, nil } func mapRole(r dbgen.Role) domain.RoleRecord { rec := domain.RoleRecord{ ID: r.ID, Name: r.Name, Description: r.Description, IsSystem: r.IsSystem, CreatedAt: r.CreatedAt.Time, } if r.UpdatedAt.Valid { rec.UpdatedAt = &r.UpdatedAt.Time } return rec } func mapPermission(p dbgen.Permission) domain.Permission { return domain.Permission{ ID: p.ID, Key: p.Key, Name: p.Name, Description: p.Description, GroupName: p.GroupName, CreatedAt: p.CreatedAt.Time, } }