Files
digital-psychology/apps/api/internal/service/admin/entitlement.go
T
jackyu66gitandCursor c81f57a7d1 feat(ECR-018): Entitlement 用户权益只读并 Closed
聚合 GET /admin/users/:id/entitlements(Membership∪DeepAccess∪问答额度)与 admin-h5 权益 Tab;无 migration / 无真支付。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 19:26:15 +08:00

65 lines
1.8 KiB
Go

package admin
import (
"context"
"github.com/google/uuid"
"github.com/yuxingu/digital-psychology/apps/api/internal/repository"
)
// EntitlementFlags summarizes effective rights.
type EntitlementFlags struct {
ReportDetailViaMembership bool `json:"report_detail_via_membership"`
DeepAccessCount int `json:"deep_access_count"`
}
// UserEntitlement is the CommerceEntitlement ops read model.
type UserEntitlement struct {
UserID uuid.UUID `json:"user_id"`
Membership *repository.MembershipRow `json:"membership"`
AskPaidQuotaLeft int `json:"ask_paid_quota_left"`
Flags EntitlementFlags `json:"flags"`
DeepAccesses []repository.DeepAccessBrief `json:"deep_accesses"`
}
// GetUserEntitlement aggregates membership + deep access + quotas.
func (s *Service) GetUserEntitlement(ctx context.Context, userID uuid.UUID) (*UserEntitlement, error) {
ok, err := s.Repo.UserExists(ctx, userID)
if err != nil {
return nil, err
}
if !ok {
return nil, ErrUserNotFound
}
_, _, paidLeft, _, _, err := s.Repo.GetUserAccount(ctx, userID)
if err != nil {
return nil, err
}
mem, err := s.Reports.GetMembership(ctx, userID)
if err != nil {
return nil, err
}
count, err := s.Repo.CountDeepAccessForUser(ctx, userID)
if err != nil {
return nil, err
}
items, err := s.Repo.ListDeepAccessForUser(ctx, userID, 20)
if err != nil {
return nil, err
}
if items == nil {
items = []repository.DeepAccessBrief{}
}
return &UserEntitlement{
UserID: userID,
Membership: mem,
AskPaidQuotaLeft: paidLeft,
Flags: EntitlementFlags{
ReportDetailViaMembership: mem != nil && mem.Active,
DeepAccessCount: count,
},
DeepAccesses: items,
}, nil
}