mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-05-05 05:30:44 +08:00
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>
This commit is contained in:
@@ -528,8 +528,7 @@ func usageLogFromServiceUser(l *service.UsageLog) UsageLog {
|
|||||||
APIKeyID: l.APIKeyID,
|
APIKeyID: l.APIKeyID,
|
||||||
AccountID: l.AccountID,
|
AccountID: l.AccountID,
|
||||||
RequestID: l.RequestID,
|
RequestID: l.RequestID,
|
||||||
Model: l.Model,
|
Model: l.RequestedModel,
|
||||||
UpstreamModel: l.UpstreamModel,
|
|
||||||
ServiceTier: l.ServiceTier,
|
ServiceTier: l.ServiceTier,
|
||||||
ReasoningEffort: l.ReasoningEffort,
|
ReasoningEffort: l.ReasoningEffort,
|
||||||
InboundEndpoint: l.InboundEndpoint,
|
InboundEndpoint: l.InboundEndpoint,
|
||||||
@@ -586,6 +585,7 @@ func UsageLogFromServiceAdmin(l *service.UsageLog) *AdminUsageLog {
|
|||||||
}
|
}
|
||||||
return &AdminUsageLog{
|
return &AdminUsageLog{
|
||||||
UsageLog: usageLogFromServiceUser(l),
|
UsageLog: usageLogFromServiceUser(l),
|
||||||
|
UpstreamModel: l.UpstreamModel,
|
||||||
AccountRateMultiplier: l.AccountRateMultiplier,
|
AccountRateMultiplier: l.AccountRateMultiplier,
|
||||||
IPAddress: l.IPAddress,
|
IPAddress: l.IPAddress,
|
||||||
Account: AccountSummaryFromService(l.Account),
|
Account: AccountSummaryFromService(l.Account),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||||
@@ -106,6 +107,32 @@ func TestUsageLogFromService_IncludesServiceTierForUserAndAdmin(t *testing.T) {
|
|||||||
require.InDelta(t, 1.5, *adminDTO.AccountRateMultiplier, 1e-12)
|
require.InDelta(t, 1.5, *adminDTO.AccountRateMultiplier, 1e-12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUsageLogFromService_UsesRequestedModelAndKeepsUpstreamAdminOnly(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
upstreamModel := "claude-sonnet-4-20250514"
|
||||||
|
log := &service.UsageLog{
|
||||||
|
RequestID: "req_4",
|
||||||
|
Model: upstreamModel,
|
||||||
|
RequestedModel: "claude-sonnet-4",
|
||||||
|
UpstreamModel: &upstreamModel,
|
||||||
|
}
|
||||||
|
|
||||||
|
userDTO := UsageLogFromService(log)
|
||||||
|
adminDTO := UsageLogFromServiceAdmin(log)
|
||||||
|
|
||||||
|
require.Equal(t, "claude-sonnet-4", userDTO.Model)
|
||||||
|
require.Equal(t, "claude-sonnet-4", adminDTO.Model)
|
||||||
|
|
||||||
|
userJSON, err := json.Marshal(userDTO)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotContains(t, string(userJSON), "upstream_model")
|
||||||
|
|
||||||
|
adminJSON, err := json.Marshal(adminDTO)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Contains(t, string(adminJSON), `"upstream_model":"claude-sonnet-4-20250514"`)
|
||||||
|
}
|
||||||
|
|
||||||
func f64Ptr(value float64) *float64 {
|
func f64Ptr(value float64) *float64 {
|
||||||
return &value
|
return &value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,9 +334,6 @@ type UsageLog struct {
|
|||||||
AccountID int64 `json:"account_id"`
|
AccountID int64 `json:"account_id"`
|
||||||
RequestID string `json:"request_id"`
|
RequestID string `json:"request_id"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
// UpstreamModel is the actual model sent to the upstream provider after mapping.
|
|
||||||
// Omitted when no mapping was applied (requested model was used as-is).
|
|
||||||
UpstreamModel *string `json:"upstream_model,omitempty"`
|
|
||||||
// ServiceTier records the OpenAI service tier used for billing, e.g. "priority" / "flex".
|
// ServiceTier records the OpenAI service tier used for billing, e.g. "priority" / "flex".
|
||||||
ServiceTier *string `json:"service_tier,omitempty"`
|
ServiceTier *string `json:"service_tier,omitempty"`
|
||||||
// ReasoningEffort is the request's reasoning effort level.
|
// ReasoningEffort is the request's reasoning effort level.
|
||||||
@@ -396,6 +393,10 @@ type UsageLog struct {
|
|||||||
type AdminUsageLog struct {
|
type AdminUsageLog struct {
|
||||||
UsageLog
|
UsageLog
|
||||||
|
|
||||||
|
// UpstreamModel is the actual model sent to the upstream provider after mapping.
|
||||||
|
// Omitted when no mapping was applied (requested model was used as-is).
|
||||||
|
UpstreamModel *string `json:"upstream_model,omitempty"`
|
||||||
|
|
||||||
// AccountRateMultiplier 账号计费倍率快照(nil 表示按 1.0 处理)
|
// AccountRateMultiplier 账号计费倍率快照(nil 表示按 1.0 处理)
|
||||||
AccountRateMultiplier *float64 `json:"account_rate_multiplier"`
|
AccountRateMultiplier *float64 `json:"account_rate_multiplier"`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user