package controlplane import ( "context" "encoding/json" "fmt" ) func (s *Store) Overview(ctx context.Context) (Overview, error) { var result Overview err := s.db.QueryRow(ctx, ` SELECT (SELECT generation FROM control_state WHERE singleton = TRUE), (SELECT count(*) FROM tenants WHERE status = 'active'), (SELECT count(*) FROM projects WHERE status = 'active'), (SELECT count(*) FROM api_keys WHERE status = 'active'), (SELECT count(*) FROM providers WHERE enabled = TRUE), (SELECT count(*) FROM models WHERE enabled = TRUE)`, ).Scan(&result.Generation, &result.Tenants, &result.Projects, &result.APIKeys, &result.Providers, &result.Models) if err != nil { return Overview{}, fmt.Errorf("query control-plane overview: %w", err) } return result, nil } func (s *Store) ListTenants(ctx context.Context) ([]Tenant, error) { return s.ListTenantsFor(ctx, "") } func (s *Store) ListTenantsFor(ctx context.Context, tenantID string) ([]Tenant, error) { query := `SELECT id::text, slug, name, status, created_at FROM tenants` args := []any{} if tenantID != "" { query += ` WHERE id=$1` args = append(args, tenantID) } query += ` ORDER BY created_at DESC` rows, err := s.db.Query(ctx, query, args...) if err != nil { return nil, fmt.Errorf("query tenants: %w", err) } defer rows.Close() result := make([]Tenant, 0) for rows.Next() { var item Tenant if err := rows.Scan(&item.ID, &item.Slug, &item.Name, &item.Status, &item.CreatedAt); err != nil { return nil, fmt.Errorf("scan tenant: %w", err) } result = append(result, item) } return result, rows.Err() } func (s *Store) ListProjects(ctx context.Context) ([]Project, error) { return s.ListProjectsFor(ctx, "") } func (s *Store) ListProjectsFor(ctx context.Context, tenantID string) ([]Project, error) { query := `SELECT id::text, tenant_id::text, slug, name, status, created_at FROM projects` args := []any{} if tenantID != "" { query += ` WHERE tenant_id=$1` args = append(args, tenantID) } query += ` ORDER BY created_at DESC` rows, err := s.db.Query(ctx, query, args...) if err != nil { return nil, fmt.Errorf("query projects: %w", err) } defer rows.Close() result := make([]Project, 0) for rows.Next() { var item Project if err := rows.Scan(&item.ID, &item.TenantID, &item.Slug, &item.Name, &item.Status, &item.CreatedAt); err != nil { return nil, fmt.Errorf("scan project: %w", err) } result = append(result, item) } return result, rows.Err() } func (s *Store) ListAPIKeys(ctx context.Context) ([]APIKey, error) { return s.ListAPIKeysFor(ctx, "") } func (s *Store) ListAPIKeysFor(ctx context.Context, tenantID string) ([]APIKey, error) { query := ` SELECT id::text, tenant_id::text, project_id::text, name, key_prefix, scopes, status, created_at FROM api_keys` args := []any{} if tenantID != "" { query += ` WHERE tenant_id=$1` args = append(args, tenantID) } query += ` ORDER BY created_at DESC` rows, err := s.db.Query(ctx, query, args...) if err != nil { return nil, fmt.Errorf("query API keys: %w", err) } defer rows.Close() result := make([]APIKey, 0) for rows.Next() { var item APIKey var scopesJSON []byte if err := rows.Scan(&item.ID, &item.TenantID, &item.ProjectID, &item.Name, &item.KeyPrefix, &scopesJSON, &item.Status, &item.CreatedAt); err != nil { return nil, fmt.Errorf("scan API key: %w", err) } if err := json.Unmarshal(scopesJSON, &item.Scopes); err != nil { return nil, fmt.Errorf("decode API key scopes: %w", err) } result = append(result, item) } return result, rows.Err() } func (s *Store) OverviewFor(ctx context.Context, tenantID string) (Overview, error) { if tenantID == "" { return s.Overview(ctx) } var result Overview err := s.db.QueryRow(ctx, `SELECT (SELECT generation FROM control_state WHERE singleton=TRUE), (SELECT count(*) FROM tenants WHERE id=$1 AND status='active'), (SELECT count(*) FROM projects WHERE tenant_id=$1 AND status='active'), (SELECT count(*) FROM api_keys WHERE tenant_id=$1 AND status='active'), 0, (SELECT count(*) FROM models WHERE enabled=TRUE)`, tenantID, ).Scan(&result.Generation, &result.Tenants, &result.Projects, &result.APIKeys, &result.Providers, &result.Models) if err != nil { return Overview{}, fmt.Errorf("query tenant overview: %w", err) } return result, nil } func (s *Store) ResourceTenantID(ctx context.Context, resource, id string) (string, error) { var query string switch resource { case "project": query = `SELECT tenant_id::text FROM projects WHERE id=$1` case "api_key": query = `SELECT tenant_id::text FROM api_keys WHERE id=$1` case "console_user": query = `SELECT COALESCE(tenant_id::text,'') FROM console_users WHERE id=$1` default: return "", ErrNotFound } var tenantID string if err := s.db.QueryRow(ctx, query, id).Scan(&tenantID); err != nil { return "", ErrNotFound } return tenantID, nil } func (s *Store) ListProviders(ctx context.Context) ([]Provider, error) { rows, err := s.db.Query(ctx, ` SELECT p.id::text, p.name, p.protocol, p.base_url, p.enabled, count(r.id), p.created_at FROM providers p LEFT JOIN model_routes r ON r.provider_id = p.id GROUP BY p.id ORDER BY p.created_at DESC`) if err != nil { return nil, fmt.Errorf("query providers: %w", err) } defer rows.Close() result := make([]Provider, 0) for rows.Next() { var item Provider if err := rows.Scan(&item.ID, &item.Name, &item.Protocol, &item.BaseURL, &item.Enabled, &item.RouteCount, &item.CreatedAt); err != nil { return nil, fmt.Errorf("scan provider: %w", err) } result = append(result, item) } return result, rows.Err() } func (s *Store) ListModels(ctx context.Context) ([]Model, error) { rows, err := s.db.Query(ctx, ` SELECT id::text, public_id, owned_by, input_price_micros_per_million, output_price_micros_per_million, cache_read_price_micros_per_million, cache_write_price_micros_per_million, enabled, created_at FROM models ORDER BY public_id`) if err != nil { return nil, fmt.Errorf("query models: %w", err) } models := make([]Model, 0) positions := make(map[string]int) for rows.Next() { var item Model if err := rows.Scan(&item.ID, &item.PublicID, &item.OwnedBy, &item.InputPriceMicrosPerMillion, &item.OutputPriceMicrosPerMillion, &item.CacheReadPriceMicrosPerMillion, &item.CacheWritePriceMicrosPerMillion, &item.Enabled, &item.CreatedAt); err != nil { rows.Close() return nil, fmt.Errorf("scan model: %w", err) } item.Routes = []Route{} positions[item.ID] = len(models) models = append(models, item) } if err := rows.Err(); err != nil { rows.Close() return nil, err } rows.Close() routeRows, err := s.db.Query(ctx, ` SELECT r.id::text, r.model_id::text, r.provider_id::text, p.name, p.protocol, r.upstream_model, r.priority, r.weight, r.enabled FROM model_routes r JOIN providers p ON p.id = r.provider_id ORDER BY r.priority, r.created_at`) if err != nil { return nil, fmt.Errorf("query model routes: %w", err) } defer routeRows.Close() for routeRows.Next() { var route Route var modelID string if err := routeRows.Scan(&route.ID, &modelID, &route.ProviderID, &route.ProviderName, &route.Protocol, &route.UpstreamModel, &route.Priority, &route.Weight, &route.Enabled); err != nil { return nil, fmt.Errorf("scan model route: %w", err) } if position, ok := positions[modelID]; ok { models[position].Routes = append(models[position].Routes, route) } } return models, routeRows.Err() }