Changeset 0.10.1 (#57)

This commit is contained in:
2026-02-24 16:51:08 +00:00
parent ea03f956ca
commit 13772ebd6c
11 changed files with 472 additions and 159 deletions

View File

@@ -285,6 +285,7 @@ type GlobalConfigStore interface {
type UsageStore interface {
Log(ctx context.Context, entry *models.UsageEntry) error
QueryByUser(ctx context.Context, userID string, opts UsageQueryOptions) ([]models.UsageAggregate, error)
QueryByUserPersonal(ctx context.Context, userID string, opts UsageQueryOptions) ([]models.UsageAggregate, error)
QueryByTeam(ctx context.Context, teamID string, opts UsageQueryOptions) ([]models.UsageAggregate, error)
QueryByTeamProviders(ctx context.Context, teamID string, opts UsageQueryOptions) ([]models.UsageAggregate, error)
QueryByModel(ctx context.Context, opts UsageQueryOptions) ([]models.UsageAggregate, error)

View File

@@ -40,6 +40,16 @@ func (s *UsageStore) QueryByUser(ctx context.Context, userID string, opts store.
return s.query(ctx, where, args, opts)
}
// QueryByUserPersonal returns aggregated usage for a user's own (BYOK) providers only.
func (s *UsageStore) QueryByUserPersonal(ctx context.Context, userID string, opts store.UsageQueryOptions) ([]models.UsageAggregate, error) {
where := []string{
"user_id = $1",
"provider_config_id IN (SELECT id FROM provider_configs WHERE scope = 'personal' AND owner_id = $1)",
}
args := []interface{}{userID}
return s.query(ctx, where, args, opts)
}
// QueryByTeam returns aggregated usage for all members of a team (admin view).
func (s *UsageStore) QueryByTeam(ctx context.Context, teamID string, opts store.UsageQueryOptions) ([]models.UsageAggregate, error) {
where := []string{"user_id IN (SELECT user_id FROM team_members WHERE team_id = $1)"}
@@ -104,11 +114,15 @@ func (s *UsageStore) GetTeamProviderTotals(ctx context.Context, teamID string, o
return &t, err
}
// GetPersonalTotals returns aggregate totals for a specific user (all scopes).
// GetPersonalTotals returns aggregate totals for a user's own provider usage.
// Only includes usage against personal (BYOK) providers — global provider
// costs are the org's responsibility, not the user's.
func (s *UsageStore) GetPersonalTotals(ctx context.Context, userID string, opts store.UsageQueryOptions) (*models.UsageTotals, error) {
baseWhere := []string{"user_id = $1"}
baseWhere := []string{
"user_id = $1",
"provider_config_id IN (SELECT id FROM provider_configs WHERE scope = 'personal' AND owner_id = $1)",
}
baseArgs := []interface{}{userID}
// Don't exclude BYOK for personal view
opts.ExcludeBYOK = false
where, args := s.buildFilters(baseWhere, baseArgs, opts)