Skip to content

Commit 095200b

Browse files
refactor(dto): split admin usage upstream model exposure
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 2c667a1 commit 095200b

3 files changed

Lines changed: 33 additions & 5 deletions

File tree

backend/internal/handler/dto/mappers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,7 @@ func usageLogFromServiceUser(l *service.UsageLog) UsageLog {
528528
APIKeyID: l.APIKeyID,
529529
AccountID: l.AccountID,
530530
RequestID: l.RequestID,
531-
Model: l.Model,
532-
UpstreamModel: l.UpstreamModel,
531+
Model: l.RequestedModel,
533532
ServiceTier: l.ServiceTier,
534533
ReasoningEffort: l.ReasoningEffort,
535534
InboundEndpoint: l.InboundEndpoint,
@@ -586,6 +585,7 @@ func UsageLogFromServiceAdmin(l *service.UsageLog) *AdminUsageLog {
586585
}
587586
return &AdminUsageLog{
588587
UsageLog: usageLogFromServiceUser(l),
588+
UpstreamModel: l.UpstreamModel,
589589
AccountRateMultiplier: l.AccountRateMultiplier,
590590
IPAddress: l.IPAddress,
591591
Account: AccountSummaryFromService(l.Account),

backend/internal/handler/dto/mappers_usage_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dto
22

33
import (
4+
"encoding/json"
45
"testing"
56

67
"github.com/Wei-Shaw/sub2api/internal/service"
@@ -106,6 +107,32 @@ func TestUsageLogFromService_IncludesServiceTierForUserAndAdmin(t *testing.T) {
106107
require.InDelta(t, 1.5, *adminDTO.AccountRateMultiplier, 1e-12)
107108
}
108109

110+
func TestUsageLogFromService_UsesRequestedModelAndKeepsUpstreamAdminOnly(t *testing.T) {
111+
t.Parallel()
112+
113+
upstreamModel := "claude-sonnet-4-20250514"
114+
log := &service.UsageLog{
115+
RequestID: "req_4",
116+
Model: upstreamModel,
117+
RequestedModel: "claude-sonnet-4",
118+
UpstreamModel: &upstreamModel,
119+
}
120+
121+
userDTO := UsageLogFromService(log)
122+
adminDTO := UsageLogFromServiceAdmin(log)
123+
124+
require.Equal(t, "claude-sonnet-4", userDTO.Model)
125+
require.Equal(t, "claude-sonnet-4", adminDTO.Model)
126+
127+
userJSON, err := json.Marshal(userDTO)
128+
require.NoError(t, err)
129+
require.NotContains(t, string(userJSON), "upstream_model")
130+
131+
adminJSON, err := json.Marshal(adminDTO)
132+
require.NoError(t, err)
133+
require.Contains(t, string(adminJSON), `"upstream_model":"claude-sonnet-4-20250514"`)
134+
}
135+
109136
func f64Ptr(value float64) *float64 {
110137
return &value
111138
}

backend/internal/handler/dto/types.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,6 @@ type UsageLog struct {
334334
AccountID int64 `json:"account_id"`
335335
RequestID string `json:"request_id"`
336336
Model string `json:"model"`
337-
// UpstreamModel is the actual model sent to the upstream provider after mapping.
338-
// Omitted when no mapping was applied (requested model was used as-is).
339-
UpstreamModel *string `json:"upstream_model,omitempty"`
340337
// ServiceTier records the OpenAI service tier used for billing, e.g. "priority" / "flex".
341338
ServiceTier *string `json:"service_tier,omitempty"`
342339
// ReasoningEffort is the request's reasoning effort level.
@@ -396,6 +393,10 @@ type UsageLog struct {
396393
type AdminUsageLog struct {
397394
UsageLog
398395

396+
// UpstreamModel is the actual model sent to the upstream provider after mapping.
397+
// Omitted when no mapping was applied (requested model was used as-is).
398+
UpstreamModel *string `json:"upstream_model,omitempty"`
399+
399400
// AccountRateMultiplier 账号计费倍率快照(nil 表示按 1.0 处理)
400401
AccountRateMultiplier *float64 `json:"account_rate_multiplier"`
401402

0 commit comments

Comments
 (0)