feat(ECR-013A): Admin RBAC 实现并 Closed

角色权限、RequirePermission、/me permissions 与 migration 000015;
Reviewer Approve → Closed。Next:ECR-013B Contract Definition。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 17:19:45 +08:00
co-authored by Cursor
parent 85ed0901bb
commit b5a05941d9
35 changed files with 1518 additions and 49 deletions
+5 -17
View File
@@ -6,7 +6,6 @@ import (
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"time"
"github.com/google/uuid"
@@ -54,12 +53,6 @@ type LoginResult struct {
Admin AdminMe `json:"admin"`
}
// AdminMe is the public admin profile.
type AdminMe struct {
ID uuid.UUID `json:"id"`
Username string `json:"username"`
}
var (
ErrBadCredentials = errString("invalid credentials")
ErrInvalidPlan = errString("invalid plan")
@@ -90,10 +83,14 @@ func (s *Service) Login(ctx context.Context, username, password string) (*LoginR
if err := s.Repo.CreateSession(ctx, acc.ID, token, exp); err != nil {
return nil, err
}
me, err := s.Me(ctx, acc.ID)
if err != nil {
return nil, err
}
return &LoginResult{
Token: token,
ExpiresAt: exp,
Admin: AdminMe{ID: acc.ID, Username: acc.Username},
Admin: *me,
}, nil
}
@@ -110,15 +107,6 @@ func (s *Service) Logout(ctx context.Context, token string) error {
return s.Repo.DeleteSession(ctx, token)
}
// Me returns the current admin profile.
func (s *Service) Me(ctx context.Context, adminID uuid.UUID) (*AdminMe, error) {
acc, err := s.Repo.FindAccountByID(ctx, adminID)
if err != nil || acc == nil {
return nil, errors.New("admin not found")
}
return &AdminMe{ID: acc.ID, Username: acc.Username}, nil
}
// ListUsers lists terminal users.
func (s *Service) ListUsers(ctx context.Context, q string, limit, offset int) ([]repository.UserListItem, error) {
return s.Repo.ListUsers(ctx, q, limit, offset)