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 }