Ctrl K
ComunidadGuías…

controller/model_management_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package controller

import (
	"bytes"
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"testing"

	"github.com/QuantumNous/new-api/common"
	"github.com/QuantumNous/new-api/constant"
	"github.com/QuantumNous/new-api/model"
	"github.com/QuantumNous/new-api/pkg/billingexpr"
	"github.com/QuantumNous/new-api/pkg/jsplugin"
	"github.com/QuantumNous/new-api/relaykit/dto"
	"github.com/QuantumNous/new-api/relaykit/types"
	"github.com/QuantumNous/new-api/service"
	"github.com/QuantumNous/new-api/setting/billing_setting"
	"github.com/QuantumNous/new-api/setting/config"
	"github.com/QuantumNous/new-api/setting/ratio_setting"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gorm.io/gorm"
)

func modelManagementDB(t *testing.T, kind, dsn string) *gorm.DB {
	t.Helper()
	database, isolatedDSN := newAuditTestDatabase(t, kind, dsn)
	previousDB, previousLogDB := model.DB, model.LOG_DB
	previousMain, previousLog := common.MainDatabaseType(), common.LogDatabaseType()
	previousMaster, previousSQLite := common.IsMasterNode, common.SQLitePath
	previousRedis, previousMemory := common.RedisEnabled, common.MemoryCacheEnabled
	previousOptions := common.OptionMap
	previousConfig := config.GlobalConfig.ExportAllConfigs()
	restoreRatios := []struct {
		value   string
		restore func(string) error
	}{
		{ratio_setting.ModelPrice2JSONString(), ratio_setting.UpdateModelPriceByJSONString},
		{ratio_setting.ModelRatio2JSONString(), ratio_setting.UpdateModelRatioByJSONString},
		{ratio_setting.CompletionRatio2JSONString(), ratio_setting.UpdateCompletionRatioByJSONString},
		{ratio_setting.CacheRatio2JSONString(), ratio_setting.UpdateCacheRatioByJSONString},
		{ratio_setting.CreateCacheRatio2JSONString(), ratio_setting.UpdateCreateCacheRatioByJSONString},
		{ratio_setting.ImageRatio2JSONString(), ratio_setting.UpdateImageRatioByJSONString},
		{ratio_setting.AudioRatio2JSONString(), ratio_setting.UpdateAudioRatioByJSONString},
		{ratio_setting.AudioCompletionRatio2JSONString(), ratio_setting.UpdateAudioCompletionRatioByJSONString},
	}
	common.IsMasterNode = false
	common.RedisEnabled, common.MemoryCacheEnabled = false, false
	common.OptionMap = map[string]string{}
	if kind == "sqlite" {
		common.SQLitePath = isolatedDSN
		isolatedDSN = "local"
	}
	t.Setenv("SQL_DSN", isolatedDSN)
	t.Setenv("LOG_SQL_DSN", "")
	require.NoError(t, model.InitDB())
	database = model.DB
	model.LOG_DB = database
	require.NoError(t, database.AutoMigrate(&model.Model{}, &model.Vendor{}, &model.Channel{}, &model.Ability{}, &model.Option{}, &model.User{}, &model.AuditLog{}))
	for _, value := range restoreRatios {
		require.NoError(t, value.restore("{}"))
	}
	config.UpdateConfigFromMap(config.GlobalConfig.Get("billing_setting"), map[string]string{"billing_mode": "{}", "billing_expr": "{}", "plugin_billing_expr": "{}"})
	var version string
	query := "SELECT version()"
	if kind == "sqlite" {
		query = "SELECT sqlite_version()"
	}
	require.NoError(t, database.Raw(query).Scan(&version).Error)
	t.Logf("database version: %s", version)
	t.Cleanup(func() {
		for _, value := range restoreRatios {
			require.NoError(t, value.restore(value.value))
		}
		config.UpdateConfigFromMap(config.GlobalConfig.Get("billing_setting"), map[string]string{"billing_mode": previousConfig["billing_setting.billing_mode"], "billing_expr": previousConfig["billing_setting.billing_expr"], "plugin_billing_expr": previousConfig[billing_setting.PluginBillingExprOption]})
		common.OptionMap = previousOptions
		common.IsMasterNode, common.SQLitePath = previousMaster, previousSQLite
		common.RedisEnabled, common.MemoryCacheEnabled = previousRedis, previousMemory
		common.SetDatabaseTypes(previousMain, previousLog)
		connection, err := database.DB()
		if err == nil {
			require.NoError(t, connection.Close())
		}
		model.DB, model.LOG_DB = previousDB, previousLogDB
	})
	return database
}

func modelManagementRequest(t *testing.T, handler gin.HandlerFunc, method, path string, body any, output any) *httptest.ResponseRecorder {
	t.Helper()
	encoded, err := common.Marshal(body)
	require.NoError(t, err)
	recorder := httptest.NewRecorder()
	context, _ := gin.CreateTestContext(recorder)
	context.Request = httptest.NewRequest(method, path, bytes.NewReader(encoded))
	context.Set("role", common.RoleRootUser)
	handler(context)
	if output != nil {
		require.NoError(t, common.Unmarshal(recorder.Body.Bytes(), output), recorder.Body.String())
	}
	return recorder
}

func TestModelPricingConversionDatabaseMatrix(t *testing.T) {
	previousQuota := common.QuotaPerUnit
	common.QuotaPerUnit = 500000
	t.Cleanup(func() { common.QuotaPerUnit = previousQuota })
	for _, dialect := range []struct{ kind, env string }{{"sqlite", ""}, {"mysql", "TEST_MYSQL_DSN"}, {"postgres", "TEST_POSTGRES_DSN"}} {
		t.Run(dialect.kind, func(t *testing.T) {
			if dialect.env != "" && os.Getenv(dialect.env) == "" {
				t.Skip("set " + dialect.env + " to run this database")
			}
			db := modelManagementDB(t, dialect.kind, os.Getenv(dialect.env))
			contract, err := os.ReadFile("../pkg/billingexpr/testdata/frontend_simulation.json")
			require.NoError(t, err)
			var fixtures []struct {
				Name, Expression string
				Conversion       *struct {
					ModelName string              `json:"model_name"`
					Pricing   model.PricingValues `json:"pricing"`
				}
			}
			require.NoError(t, common.Unmarshal(contract, &fixtures))
			for _, fixture := range fixtures {
				if fixture.Conversion == nil {
					continue
				}
				t.Run("frontend_contract/"+fixture.Name, func(t *testing.T) {
					var response struct {
						Success bool
						Data    model.ModelPricingConversion
					}
					modelManagementRequest(t, PreviewModelPricingConversion, http.MethodPost, "/api/option/model_pricing/convert", fixture.Conversion, &response)
					require.True(t, response.Success)
					assert.Equal(t, fixture.Expression, response.Data.Expression)
				})
			}
			// The preview must resolve the draft, even when the running process
			// still has a different saved output multiplier for that model.
			require.NoError(t, ratio_setting.UpdateCompletionRatioByJSONString(`{"conversion-defaults":99}`))
			for _, tc := range []struct {
				name               string
				draft              model.PricingValues
				expression, reason string
			}{
				{"conversion-defaults", model.PricingValues{"ModelRatio": float64(2)}, `tier("base", p * 4 + c * 4)`, ""},
				{"gpt-4-32k", model.PricingValues{"ModelRatio": 30.0, "CacheRatio": 1.0}, `tier("base", p * 60 + c * 120)`, ""},
				{"conversion-free-cache", model.PricingValues{"ModelRatio": 0.0, "CacheRatio": 0.0}, `tier("base", p * 0 + c * 0 + cr * 0)`, ""},
				{"claude-3-7-sonnet-20250219", model.PricingValues{"ModelRatio": float64(1.5), "CacheRatio": float64(0.1), "CreateCacheRatio": float64(1.25)}, `tier("base", p * 3 + c * 15 + cr * 0.3 + cc * 3.75 + cc1h * 6)`, ""},
				{"conversion-image-default", model.PricingValues{"ModelRatio": float64(2), "ImageRatio": float64(1)}, `tier("base", p * 4 + c * 4)`, ""},
				{"conversion-image-free", model.PricingValues{"ModelRatio": float64(2), "ImageRatio": float64(0)}, `tier("base", p * 4 + c * 4 + cr * 4 + img * 0)`, ""},
				{"deepseek-chat", model.PricingValues{"ModelRatio": float64(0.135), "CacheRatio": float64(0.25)}, `tier("base", p * 0.27 + c * 0.27 + cr * 0.0675)`, ""},
				{"gpt-4o-custom", model.PricingValues{"ModelRatio": float64(2)}, `tier("base", p * 4 + c * 16)`, ""},
				{"gemini-2.5-pro-custom", model.PricingValues{"ModelRatio": float64(2)}, `tier("base", p * 4 + c * 32)`, ""},
				{"vendor/claude-sonnet-4", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(0)}, `tier("base", p * 4 + c * 0 + cr * 4 + cc * 5 + cc1h * 8)`, ""},
				{"conversion-custom", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(3), "CacheRatio": float64(0), "CreateCacheRatio": float64(1.5), "ImageRatio": float64(2)}, `tier("base", p * 4 + c * 12 + cr * 0 + cc * 6 + img * 8)`, ""},
				{"deepseek-reasoner", model.PricingValues{"ModelRatio": 0.275, "CacheRatio": 0.25}, `tier("base", p * 0.55 + c * 0.55 + cr * 0.1375)`, ""},
				{"gpt-5.6-sol", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(2)}, `tier("base", p * 4 + c * 8)`, ""},
				{"gpt-5.5", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(2)}, `tier("base", p * 4 + c * 8)`, ""},
				{"gpt-6-astra", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(2)}, `tier("base", p * 4 + c * 8)`, ""},
				{"conversion-free", model.PricingValues{"ModelPrice": float64(0)}, `tier("request", fixed(0))`, ""},
				{"conversion-fixed", model.PricingValues{"ModelPrice": float64(0.25), "ModelRatio": float64(7)}, `tier("request", fixed(0.25))`, ""},
				{"gpt-4o-2024-05-13", model.PricingValues{"ModelRatio": float64(2), "CompletionRatio": float64(99)}, `tier("base", p * 4 + c * 12)`, ""},
				{"gpt-image-2", model.PricingValues{"ModelPrice": float64(1)}, `tier("image", fixed(1)) * image_count`, ""},
				// Bailian image models are served by the alibaba task plugin, so their pricing is a task usage expression.
				{"qwen-image-3.0-pro", model.PricingValues{"ModelPrice": float64(1)}, "", "Task pricing must be converted manually using the task usage schema."},
				{"wan2.7-image-pro", model.PricingValues{"ModelPrice": float64(1)}, "", "Task pricing must be converted manually using the task usage schema."},
				{"video-summarizer", model.PricingValues{"ModelPrice": float64(1)}, `tier("request", fixed(1))`, ""},
				{"sora-transcript-helper", model.PricingValues{"ModelPrice": float64(1)}, `tier("request", fixed(1))`, ""},
				{"gpt-realtime", model.PricingValues{"ModelRatio": float64(1)}, "", "Realtime pricing must be converted manually."},
				{"conversion-audio", model.PricingValues{"ModelRatio": float64(1), "AudioRatio": float64(2)}, `tier("base", p * 2 + c * 2 + ai * 4 + ao * 4)`, ""},
			} {
				t.Run(tc.name, func(t *testing.T) {
					before, err := model.GetModelPricingSnapshot([]string{tc.name})
					require.NoError(t, err)
					var response struct {
						Success bool
						Data    model.ModelPricingConversion
					}
					modelManagementRequest(t, PreviewModelPricingConversion, http.MethodPost, "/api/option/model_pricing/convert", map[string]any{"model_name": tc.name, "pricing": tc.draft}, &response)
					require.True(t, response.Success)
					assert.Equal(t, tc.expression, response.Data.Expression)
					assert.Equal(t, tc.reason, response.Data.UnsupportedReason)
					if tc.name == "claude-3-7-sonnet-20250219" {
						// Both providers include images in input; Claude reports cache
						// separately and does not report an image token breakdown.
						for _, usage := range []dto.Usage{
							{PromptTokens: 1000, CompletionTokens: 100, UsageSemantic: "openai", PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200, CachedCreationTokens: 50, ImageTokens: 300}},
							{PromptTokens: 750, CompletionTokens: 100, UsageSemantic: "anthropic", ClaudeCacheCreation5mTokens: 50, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200, CachedCreationTokens: 50}},
						} {
							tokens := service.BuildTieredTokenParams(&usage, usage.UsageSemantic == "anthropic", billingexpr.UsedVars(response.Data.Expression))
							cost, _, err := billingexpr.RunExpr(response.Data.Expression, tokens)
							require.NoError(t, err)
							assert.Equal(t, float64(750), tokens.P)
							assert.Equal(t, 3997.5, cost, "image input must remain billed exactly once")
						}
						usage := dto.Usage{PromptTokens: 750, CompletionTokens: 100, UsageSemantic: "anthropic", ClaudeCacheCreation5mTokens: 30, ClaudeCacheCreation1hTokens: 20, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200, CachedCreationTokens: 50}}
						tokens := service.BuildTieredTokenParams(&usage, true, billingexpr.UsedVars(response.Data.Expression))
						cost, _, err := billingexpr.RunExpr(response.Data.Expression, tokens)
						require.NoError(t, err)
						assert.Equal(t, 4042.5, cost, "mixed TTLs preserve both legacy cache-write prices")
					}
					if tc.name == "deepseek-chat" {
						for _, usage := range []dto.Usage{
							{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200}},
							{PromptTokens: 800, CompletionTokens: 100, UsageSemantic: "anthropic", PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 200}},
						} {
							tokens := service.BuildTieredTokenParams(&usage, usage.UsageSemantic == "anthropic", billingexpr.UsedVars(response.Data.Expression))
							cost, _, err := billingexpr.RunExpr(response.Data.Expression, tokens)
							require.NoError(t, err)
							assert.Equal(t, 256.5, cost, "cache reads remain billed across both response formats")
						}
					}
					after, err := model.GetModelPricingSnapshot([]string{tc.name})
					require.NoError(t, err)
					assert.Equal(t, before.Entries, after.Entries, "preview must not write pricing")
					if tc.expression == "" {
						return
					}
					pricing := tc.draft
					pricing["billing_setting.billing_mode"] = "tiered_expr"
					pricing["billing_setting.billing_expr"] = tc.expression
					change := model.ModelPricingChange{ModelName: tc.name, ExpectedVersion: before.Entries[0].Version, Pricing: pricing}
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
					after, err = model.GetModelPricingSnapshot([]string{tc.name})
					require.NoError(t, err)
					assert.Equal(t, pricing, after.Entries[0].Configured)
					assert.ErrorIs(t, model.UpdateModelPricing([]model.ModelPricingChange{change}), model.ErrModelPricingConflict)
					change.ExpectedVersion = after.Entries[0].Version
					change.Pricing["billing_setting.billing_mode"] = "ratio"
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
					after, err = model.GetModelPricingSnapshot([]string{tc.name})
					require.NoError(t, err)
					assert.Equal(t, "ratio", after.Entries[0].Effective["billing_setting.billing_mode"])
					if _, fixed := pricing["ModelPrice"]; !fixed {
						var preview struct {
							Success bool
							Data    model.ModelPricingDescription
						}
						modelManagementRequest(t, PreviewModelPricing, http.MethodPost, "/api/option/model_pricing/preview", map[string]any{"model_name": tc.name, "pricing": pricing}, &preview)
						require.True(t, preview.Success)
						assert.Equal(t, after.Entries[0].Effective, preview.Data.Effective)
						require.NotEmpty(t, response.Data.Effective)
						for field, value := range response.Data.Effective {
							assert.Equal(t, value, preview.Data.Effective[field], "conversion preview field %s", field)
						}
						cache, _ := ratio_setting.GetCacheRatio(tc.name)
						createCache, _ := ratio_setting.GetCreateCacheRatio(tc.name)
						image, _ := ratio_setting.GetImageRatio(tc.name)
						assert.Equal(t, ratio_setting.GetCompletionRatio(tc.name), preview.Data.Effective["CompletionRatio"])
						assert.Equal(t, cache, preview.Data.Effective["CacheRatio"])
						assert.Equal(t, createCache, preview.Data.Effective["CreateCacheRatio"])
						assert.Equal(t, image, preview.Data.Effective["ImageRatio"])
					}
				})
			}
			require.NoError(t, (&model.Channel{Name: "Mapped image", Models: "conversion-alias", Type: 1, ModelMapping: common.GetPointer(`{"conversion-alias":"conversion-hop","conversion-hop":"gpt-image-2"}`)}).Insert())
			preview, err := model.PreviewModelPricingConversion("conversion-alias", model.PricingValues{"ModelPrice": float64(1)})
			require.NoError(t, err)
			assert.Equal(t, `tier("image", fixed(1)) * image_count`, preview.Expression)
			assert.Empty(t, preview.UnsupportedReason)

			t.Run("cache_writes_follow_configured_prices_and_claude_names", func(t *testing.T) {
				for _, tc := range []struct {
					name       string
					configured *float64
					mode       model.CacheWriteMode
				}{
					{"unrecognized-model", nil, model.CacheWriteNone},
					{"gpt-5.6-terra", nil, model.CacheWriteNone},
					{"gpt-5.6-terra", common.GetPointer(1.25), model.CacheWriteOpenAITTL},
					{"custom-GPT-alias", common.GetPointer(0.0), model.CacheWriteOpenAITTL},
					{"vendor/claude-sonnet-4-6-high", nil, model.CacheWriteClaudeTTL},
					{"custom-CLAUDE-alias", common.GetPointer(0.0), model.CacheWriteClaudeTTL},
					{"deepseek-reasoner", common.GetPointer(0.0), model.CacheWriteStandard},
					{"custom-cache", common.GetPointer(1.5), model.CacheWriteStandard},
				} {
					t.Run(tc.name+"/"+string(tc.mode), func(t *testing.T) {
						draft := model.PricingValues{"ModelRatio": 2.0, "CompletionRatio": 2.0, "CacheRatio": 0.25, "billing_setting.billing_mode": "ratio"}
						if tc.configured != nil {
							draft["CreateCacheRatio"] = *tc.configured
						}
						var response struct {
							Success bool
							Data    model.ModelPricingConversion
						}
						modelManagementRequest(t, PreviewModelPricingConversion, http.MethodPost, "/api/option/model_pricing/convert", map[string]any{"model_name": tc.name, "pricing": draft}, &response)
						require.True(t, response.Success)
						require.NotEmpty(t, response.Data.Expression)
						assert.Equal(t, tc.mode, response.Data.CacheWriteMode)
						var prices struct {
							Success bool
							Data    model.ModelPricingDescription
						}
						modelManagementRequest(t, PreviewModelPricing, http.MethodPost, "/api/option/model_pricing/preview", map[string]any{"model_name": tc.name, "pricing": draft}, &prices)
						require.True(t, prices.Success)
						assert.Equal(t, response.Data.Effective, prices.Data.Effective)
						assert.Equal(t, response.Data.CacheWriteMode, prices.Data.CacheWriteMode)
						vars := billingexpr.UsedVars(response.Data.Expression)
						assert.Equal(t, tc.mode != model.CacheWriteNone, vars["cc"])
						assert.Equal(t, tc.mode == model.CacheWriteClaudeTTL, vars["cc1h"])
						assert.Equal(t, tc.mode == model.CacheWriteOpenAITTL, vars["cc12h"])
						if tc.configured != nil && *tc.configured == 0 {
							cost, _, err := billingexpr.RunExpr(response.Data.Expression, billingexpr.TokenParams{CC: 100, CC1h: 100, CC12h: 100})
							require.NoError(t, err)
							assert.Zero(t, cost, "explicit zero cache prices must stay free")
						}
					})
				}
				// GPT names price the 12h write at twice the configured write price.
				openai, err := model.PreviewModelPricingConversion("gpt-5.6-terra", model.PricingValues{"ModelRatio": 5.0, "CompletionRatio": 5.0, "CacheRatio": 0.1, "CreateCacheRatio": 1.25})
				require.NoError(t, err)
				assert.Equal(t, model.CacheWriteOpenAITTL, openai.CacheWriteMode)
				assert.Equal(t, `tier("base", p * 10 + c * 50 + cr * 1 + cc * 12.5 + cc12h * 25)`, openai.Expression)
				// The billing name remains authoritative for cache terms.
				require.NoError(t, (&model.Channel{Name: "Cache alias", Type: 1, Models: "opaque-cache-alias", ModelMapping: common.GetPointer(`{"opaque-cache-alias":"claude-sonnet-4-6"}`)}).Insert())
				alias, err := model.PreviewModelPricingConversion("opaque-cache-alias", model.PricingValues{"ModelRatio": 2.0})
				require.NoError(t, err)
				assert.Equal(t, `tier("base", p * 4 + c * 4)`, alias.Expression)
			})

			t.Run("same_price_cache_reads_preserve_overlapping_categories", func(t *testing.T) {
				for _, tc := range []struct {
					field, term             string
					ratio                   float64
					details                 dto.InputTokenDetails
					cost, unpricedCacheCost float64
				}{
					{"CreateCacheRatio", "cc * 75", 1.25, dto.InputTokenDetails{CachedTokens: 800, CacheWriteTokens: 500}, 97500, 79500},
					{"ImageRatio", "img * 120", 2, dto.InputTokenDetails{CachedTokens: 600, ImageTokens: 500}, 108000, 102000},
				} {
					t.Run(tc.field, func(t *testing.T) {
						converted, err := model.PreviewModelPricingConversion("overlapping-cache", model.PricingValues{"ModelRatio": 30.0, "CompletionRatio": 2.0, "CacheRatio": 1.0, tc.field: tc.ratio})
						require.NoError(t, err)
						assert.Equal(t, `tier("base", p * 60 + c * 120 + cr * 60 + `+tc.term+`)`, converted.Expression)
						usage := dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: tc.details}
						params := service.BuildTieredTokenParams(&usage, false, billingexpr.UsedVars(converted.Expression))
						cost, _, err := billingexpr.RunExpr(converted.Expression, params)
						require.NoError(t, err)
						assert.Equal(t, tc.cost, cost, "preserve the existing overlapping-category charge")
						unpriced := `tier("base", p * 60 + c * 120 + ` + tc.term + `)`
						params = service.BuildTieredTokenParams(&usage, false, billingexpr.UsedVars(unpriced))
						cost, _, err = billingexpr.RunExpr(unpriced, params)
						require.NoError(t, err)
						assert.Equal(t, tc.unpricedCacheCost, cost, "existing expressions without cr retain their OpenAI normalization")
					})
				}
			})
			t.Run("media_prices_and_request_adjustments", func(t *testing.T) {
				for _, quantity := range []string{"129", "-1", "0.5", "18446744073709551615"} {
					recorder := httptest.NewRecorder()
					ctx, _ := gin.CreateTestContext(recorder)
					ctx.Request = httptest.NewRequest(http.MethodPost, "/v1/images/generations", strings.NewReader(`{"model":"z-image","parameters":{"n":`+quantity+`}}`))
					ctx.Request.Header.Set("Content-Type", "application/json")
					Relay(ctx, types.RelayFormatOpenAIImage)
					assert.Equal(t, http.StatusBadRequest, recorder.Code, recorder.Body.String())
				}
				conflicting, err := model.PreviewModelPricingConversion("gemini-2.5-flash-conflict", model.PricingValues{"ModelRatio": 0.15, "AudioRatio": 10.0})
				require.NoError(t, err)
				assert.Contains(t, conflicting.UnsupportedReason, "Gemini and OpenAI audio prices differ")
				aliName := "z-image-media-conversion"
				require.NoError(t, (&model.Channel{Name: aliName, Models: aliName, Type: 17, Status: common.ChannelStatusEnabled}).Insert())
				aliConversion, err := model.PreviewModelPricingConversion(aliName, model.PricingValues{"ModelPrice": 0.04})
				require.NoError(t, err)
				require.Empty(t, aliConversion.UnsupportedReason)
				// Ali image billing lives in the alibaba task plugin, where prompt_extend is a
				// usage fact; the legacy conversion no longer adds a per-channel request multiplier.
				assert.Equal(t, `tier("image", fixed(0.04)) * image_count`, aliConversion.Expression)
				assert.Empty(t, aliConversion.BillingDetails.RequestRules)
				quantity := 3
				aliCost, _, err := billingexpr.RunExprWithRequest(aliConversion.Expression, billingexpr.TokenParams{}, billingexpr.RequestInput{ImageCount: &quantity, Body: []byte(`{"parameters":{"prompt_extend":true}}`)})
				require.NoError(t, err)
				assert.Equal(t, 120000.0, aliCost)
				for _, tc := range []struct {
					name    string
					pricing model.PricingValues
					usage   dto.Usage
					want    float64
				}{
					{"gemini-2.5-flash", model.PricingValues{"ModelRatio": 0.15, "CompletionRatio": 2.0, "CacheRatio": 0.1}, dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 100, AudioTokens: 200}}, 473},
					{"gemini-2.5-flash-zero", model.PricingValues{"ModelRatio": 0.0}, dto.Usage{PromptTokens: 1000, PromptTokensDetails: dto.InputTokenDetails{AudioTokens: 200}}, 200},
					{"media-audio", model.PricingValues{"ModelRatio": 1.0, "CompletionRatio": 3.0, "AudioRatio": 2.0, "AudioCompletionRatio": 4.0}, dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{TextTokens: 800, AudioTokens: 200}, CompletionTokenDetails: dto.OutputTokenDetails{TextTokens: 50, AudioTokens: 50}}, 3500},
					{"media-free-audio", model.PricingValues{"ModelRatio": 1.0, "AudioRatio": 0.0}, dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{AudioTokens: 200}, CompletionTokenDetails: dto.OutputTokenDetails{AudioTokens: 100}}, 1600},
					{"media-audio-cache", model.PricingValues{"ModelRatio": 1.0, "CompletionRatio": 3.0, "AudioRatio": 2.0, "CacheRatio": 0.1}, dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 400, AudioTokens: 200}, CompletionTokenDetails: dto.OutputTokenDetails{AudioTokens: 50}}, 2900},
					{"media-text-cache", model.PricingValues{"ModelRatio": 1.0, "CompletionRatio": 3.0, "AudioRatio": 2.0, "CacheRatio": 0.1}, dto.Usage{PromptTokens: 1000, CompletionTokens: 100, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 400}}, 1880},
					{"gemini-2.5-flash-overlap", model.PricingValues{"ModelRatio": 1.0}, dto.Usage{PromptTokens: 1000, PromptTokensDetails: dto.InputTokenDetails{CachedTokens: 800, AudioTokens: 500}}, 2100},
				} {
					t.Run(tc.name, func(t *testing.T) {
						converted, err := model.PreviewModelPricingConversion(tc.name, tc.pricing)
						require.NoError(t, err)
						require.Empty(t, converted.UnsupportedReason)
						require.NotNil(t, converted.BillingDetails.AudioInputPrice)
						params := service.BuildTieredTokenParams(&tc.usage, false, billingexpr.UsedVars(converted.Expression))
						cost, _, err := billingexpr.RunExpr(converted.Expression, params)
						require.NoError(t, err)
						assert.InDelta(t, tc.want, cost, 1e-9)
					})
				}
				converted, err := model.PreviewModelPricingConversion("dall-e-3", model.PricingValues{"ModelPrice": 0.04})
				require.NoError(t, err)
				require.Empty(t, converted.UnsupportedReason)
				assert.NotContains(t, converted.Expression, "256x256")
				assert.NotContains(t, converted.Expression, "512x512")
				smallImage, err := model.PreviewModelPricingConversion("dall-e-2", model.PricingValues{"ModelPrice": 0.02})
				require.NoError(t, err)
				require.Empty(t, smallImage.UnsupportedReason)
				assert.NotContains(t, smallImage.Expression, "1792")
				smallCost, _, err := billingexpr.RunExprWithRequest(smallImage.Expression, billingexpr.TokenParams{}, billingexpr.RequestInput{Body: []byte(`{"size":"256x256"}`), ImageCount: &quantity})
				require.NoError(t, err)
				assert.Equal(t, 24000.0, smallCost)
				for _, tc := range []struct {
					size, quality string
					count         int
					cost          float64
				}{
					{"1024x1024", "standard", 3, 120000},
					{"1024x1024", "hd", 2, 160000},
					{"1024x1792", "hd", 3, 360000},
				} {
					body, err := common.Marshal(map[string]any{"size": tc.size, "quality": tc.quality})
					require.NoError(t, err)
					cost, _, err := billingexpr.RunExprWithRequest(converted.Expression, billingexpr.TokenParams{}, billingexpr.RequestInput{Body: body, ImageCount: &tc.count})
					require.NoError(t, err)
					assert.InDelta(t, tc.cost, cost, 1e-9)
				}
				for _, channelType := range []int{20, 58} {
					name := fmt.Sprintf("gemini-3.5-flash-media-%d", channelType)
					require.NoError(t, (&model.Channel{Name: name, Models: name, Type: channelType}).Insert())
					require.NoError(t, db.Create(&model.Model{ModelName: name, Endpoints: `{"custom-text":"/v1/custom"}`}).Error)
					converted, err := model.PreviewModelPricingConversion(name, model.PricingValues{"ModelRatio": 0.75, "CompletionRatio": 6.0, "CacheRatio": 0.1})
					require.NoError(t, err)
					assert.Empty(t, converted.UnsupportedReason)
					assert.Equal(t, `tier("base", p * 1.5 + c * 9 + cr * 0.15)`, converted.Expression)
					assert.Nil(t, converted.BillingDetails.AudioInputPrice)
				}
			})
			require.NoError(t, db.Create(&model.Model{ModelName: "conversion-metadata", Endpoints: `{"image-generation":"/v1/images/generations"}`}).Error)
			preview, err = model.PreviewModelPricingConversion("conversion-metadata", model.PricingValues{"ModelPrice": float64(1)})
			require.NoError(t, err)
			assert.Equal(t, `tier("image", fixed(1)) * image_count`, preview.Expression)
			assert.Empty(t, preview.UnsupportedReason)
			for _, tc := range []struct {
				name, rule string
				nameRule   int
				endpoint   constant.EndpointType
			}{
				{"catalog-image-prefix-opaque", "catalog-image-prefix-", model.NameRulePrefix, constant.EndpointTypeImageGeneration},
				{"opaque-catalog-image-suffix", "-catalog-image-suffix", model.NameRuleSuffix, constant.EndpointTypeImageGeneration},
				{"before-catalog-image-middle-after", "catalog-image-middle", model.NameRuleContains, constant.EndpointTypeImageGeneration},
				{"opaque-catalog-video", "opaque-catalog-video", model.NameRuleExact, constant.EndpointTypeOpenAIVideo},
			} {
				t.Run("endpoint_metadata/"+tc.name, func(t *testing.T) {
					endpoints, err := common.Marshal(map[string]string{string(tc.endpoint): "/v1/fixture"})
					require.NoError(t, err)
					require.NoError(t, db.Create(&model.Model{ModelName: tc.rule, NameRule: tc.nameRule, Endpoints: string(endpoints)}).Error)
					converted, err := model.PreviewModelPricingConversion(tc.name, model.PricingValues{"ModelPrice": 1.0})
					require.NoError(t, err)
					if tc.endpoint == constant.EndpointTypeOpenAIVideo {
						assert.Empty(t, converted.Expression)
						assert.Equal(t, "Video pricing must be converted manually.", converted.UnsupportedReason)
					} else {
						assert.Equal(t, `tier("image", fixed(1)) * image_count`, converted.Expression)
					}
				})
			}
			sora := &model.Channel{Name: "Opaque video route", Models: "opaque-video-route", Type: constant.ChannelTypeSora, Group: "a,b"}
			require.NoError(t, sora.Insert())
			video, err := model.PreviewModelPricingConversion("opaque-video-route", model.PricingValues{"ModelPrice": 1.0})
			require.NoError(t, err)
			assert.Equal(t, "Video pricing must be converted manually.", video.UnsupportedReason)
		})
	}
}

func TestModelManagementDatabaseMatrix(t *testing.T) {
	_, err := jsplugin.DefaultRegistry.Register(`
export const meta = {apiVersion: 1, key: "model-management-task", name: "Management task fixture", version: "1.0.0", author: {name: "Test"}, models: ["matrix-task"], fetchMode: "per_task", usageSchema: {seconds: {type: "number", unit: "second"}}};
export function buildSubmitRequest() { return {}; }
export function parseSubmitResponse() { return {}; }
export function buildQueryRequest() { return {}; }
export function parseTaskResult() { return {}; }
`, jsplugin.Options{})
	require.NoError(t, err)
	t.Cleanup(func() { jsplugin.DefaultRegistry.Unregister("model-management-task") })
	for _, dialect := range []struct{ kind, env string }{{"sqlite", ""}, {"mysql", "TEST_MYSQL_DSN"}, {"postgres", "TEST_POSTGRES_DSN"}} {
		t.Run(dialect.kind, func(t *testing.T) {
			if dialect.env != "" && os.Getenv(dialect.env) == "" {
				t.Skip("set " + dialect.env + " to run this database")
			}
			db := modelManagementDB(t, dialect.kind, os.Getenv(dialect.env))

			t.Run("square_states_follow_catalog_policy", func(t *testing.T) {
				records := []model.Model{
					{ModelName: "square-visible", Status: 1},
					{ModelName: "square-hidden", Status: 0},
					{ModelName: "square-catalog", Status: 1},
					{ModelName: "square-hidden-catalog", Status: 0},
					{ModelName: "square-partial-", NameRule: model.NameRulePrefix, Status: 1},
					{ModelName: "square-partial-hidden", Status: 0},
					{ModelName: "square-hidden-", NameRule: model.NameRulePrefix, Status: 0},
					{ModelName: "square-hidden-override", Status: 1},
					{ModelName: "square-off-", NameRule: model.NameRulePrefix, Status: 0},
					{ModelName: "square-empty", NameRule: model.NameRulePrefix, Status: 1},
					{ModelName: "square-empty-hidden", NameRule: model.NameRulePrefix, Status: 0},
					{ModelName: "-ending", NameRule: model.NameRuleSuffix, Status: 1},
					{ModelName: "square-prefix-", NameRule: model.NameRulePrefix, Status: 0},
					{ModelName: "square-contains", NameRule: model.NameRuleContains, Status: 0},
				}
				ids := make([]int, 0, len(records))
				for i := range records {
					require.NoError(t, records[i].Insert())
					ids = append(ids, records[i].Id)
				}
				active := model.Channel{Name: "Square active", Type: 1, Key: "fixture", Group: "default", Status: common.ChannelStatusEnabled,
					Models: "square-visible,square-hidden,square-bare,square-partial-on,square-partial-hidden,square-hidden-child,square-hidden-override,square-prefix-ending,square-contains-ending"}
				inactive := model.Channel{Name: "Square inactive", Type: 1, Key: "fixture", Group: "default", Status: common.ChannelStatusManuallyDisabled,
					Models: "square-disabled,square-partial-off,square-off-child"}
				for _, channel := range []*model.Channel{&active, &inactive} {
					require.NoError(t, channel.Insert())
				}
				t.Cleanup(func() {
					require.NoError(t, db.Where("channel_id IN ?", []int{active.Id, inactive.Id}).Delete(&model.Ability{}).Error)
					require.NoError(t, db.Where("id IN ?", []int{active.Id, inactive.Id}).Delete(&model.Channel{}).Error)
					require.NoError(t, db.Unscoped().Where("id IN ?", ids).Delete(&model.Model{}).Error)
					model.RefreshPricing()
				})
				var response struct {
					Success bool
					Data    struct{ Items []model.Model }
				}
				modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=square-&page_size=100", nil, &response)
				require.True(t, response.Success)
				byName := make(map[string]model.Model)
				for _, row := range response.Data.Items {
					byName[row.ModelName] = row
				}
				catalog := make(map[string]bool)
				model.RefreshPricing()
				for _, row := range model.GetPricing() {
					catalog[row.ModelName] = true
				}
				expected := map[string]model.ModelSquareState{
					"square-visible":         model.ModelSquareVisible,
					"square-hidden":          model.ModelSquareHidden,
					"square-catalog":         model.ModelSquareUnavailable,
					"square-hidden-catalog":  model.ModelSquareHidden,
					"square-bare":            model.ModelSquareVisible,
					"square-disabled":        model.ModelSquareUnavailable,
					"square-partial-":        model.ModelSquarePartial,
					"square-partial-hidden":  model.ModelSquareHidden,
					"square-partial-on":      model.ModelSquareVisible,
					"square-partial-off":     model.ModelSquareUnavailable,
					"square-hidden-":         model.ModelSquarePartial,
					"square-hidden-child":    model.ModelSquareHidden,
					"square-hidden-override": model.ModelSquareVisible,
					"square-off-":            model.ModelSquareHidden,
					"square-off-child":       model.ModelSquareHidden,
					"square-empty":           model.ModelSquareUnavailable,
					"square-empty-hidden":    model.ModelSquareHidden,
					"square-prefix-ending":   model.ModelSquareHidden,
					"square-contains-ending": model.ModelSquareVisible,
					"square-contains":        model.ModelSquareVisible,
					"square-prefix-":         model.ModelSquareHidden,
				}
				for name, state := range expected {
					row, exists := byName[name]
					require.True(t, exists, name)
					assert.Equal(t, state, row.SquareState, name)
					if row.NameRule == model.NameRuleExact {
						assert.Equal(t, state == model.ModelSquareVisible, catalog[name], name)
					}
				}
				assert.Zero(t, byName["square-bare"].Id)
				assert.Zero(t, byName["square-hidden-child"].Id)
				t.Run("filter_square_state_before_pagination", func(t *testing.T) {
					type filteredResponse struct {
						Success bool
						Data    struct {
							Items []model.Model
							Total int
						}
					}
					for _, state := range []model.ModelSquareState{model.ModelSquareVisible, model.ModelSquareUnavailable, model.ModelSquareHidden, model.ModelSquarePartial} {
						t.Run(string(state), func(t *testing.T) {
							expectedNames := []string{}
							for name, expectedState := range expected {
								if expectedState == state {
									expectedNames = append(expectedNames, name)
								}
							}
							actualNames := []string{}
							for page := 1; page <= (len(expectedNames)+1)/2; page++ {
								var result filteredResponse
								path := fmt.Sprintf("/api/models/search?include_channel_models=true&keyword=square-&square_state=%s&page_size=2&p=%d", state, page)
								modelManagementRequest(t, SearchModelsMeta, "GET", path, nil, &result)
								require.True(t, result.Success)
								assert.Equal(t, len(expectedNames), result.Data.Total)
								for _, row := range result.Data.Items {
									assert.Equal(t, state, row.SquareState)
									actualNames = append(actualNames, row.ModelName)
								}
							}
							assert.ElementsMatch(t, expectedNames, actualNames)
							var beyondLastPage filteredResponse
							modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=square-&square_state="+string(state)+"&page_size=2&p=99", nil, &beyondLastPage)
							require.True(t, beyondLastPage.Success)
							assert.Equal(t, len(expectedNames), beyondLastPage.Data.Total)
							assert.Empty(t, beyondLastPage.Data.Items)
						})
					}
					for _, test := range []struct {
						name    string
						handler gin.HandlerFunc
						query   string
						names   []string
					}{
						{"list", GetAllModelsMeta, "?include_channel_models=true&square_state=visible", []string{"square-visible", "square-bare", "square-partial-on", "square-hidden-override", "square-contains-ending", "square-contains"}},
						{"metadata_only", SearchModelsMeta, "?keyword=square-&square_state=visible", []string{"square-visible", "square-hidden-override", "square-contains"}},
						{"keyword", SearchModelsMeta, "?include_channel_models=true&keyword=square-partial&square_state=hidden", []string{"square-partial-hidden"}},
						{"policy", SearchModelsMeta, "?include_channel_models=true&keyword=square-&square_state=partial&status=disabled", []string{"square-hidden-"}},
						{"vendor_and_sync", SearchModelsMeta, "?include_channel_models=true&keyword=square-&square_state=partial&vendor=0&sync_official=no", []string{"square-hidden-", "square-partial-"}},
						{"no_matches", SearchModelsMeta, "?include_channel_models=true&keyword=square-bare&square_state=hidden", []string{}},
					} {
						t.Run(test.name, func(t *testing.T) {
							var result filteredResponse
							modelManagementRequest(t, test.handler, "GET", "/api/models/"+test.query+"&page_size=100", nil, &result)
							require.True(t, result.Success)
							names := []string{}
							for _, row := range result.Data.Items {
								names = append(names, row.ModelName)
							}
							assert.Equal(t, len(test.names), result.Data.Total)
							assert.ElementsMatch(t, test.names, names)
						})
					}
					for _, handler := range []gin.HandlerFunc{GetAllModelsMeta, SearchModelsMeta} {
						var result filteredResponse
						recorder := modelManagementRequest(t, handler, "GET", "/api/models/?square_state=unknown", nil, &result)
						assert.Equal(t, http.StatusBadRequest, recorder.Code)
						assert.False(t, result.Success)
					}
					for _, query := range []string{"p=-1", "page_size=-1"} {
						recorder := modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?square_state=visible&"+query, nil, nil)
						assert.Equal(t, http.StatusBadRequest, recorder.Code)
					}
					var oversizedPage filteredResponse
					modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?square_state=visible&keyword=square-&p="+strconv.Itoa(int(^uint(0)>>1)), nil, &oversizedPage)
					require.True(t, oversizedPage.Success)
					assert.Equal(t, 3, oversizedPage.Data.Total)
					assert.Empty(t, oversizedPage.Data.Items)
				})
				var detail struct {
					Success bool
					Data    model.Model
				}
				modelManagementRequest(t, func(c *gin.Context) {
					c.Params = gin.Params{{Key: "id", Value: strconv.Itoa(records[4].Id)}}
					GetModelMeta(c)
				}, "GET", "/api/models/"+strconv.Itoa(records[4].Id), nil, &detail)
				require.True(t, detail.Success)
				assert.Equal(t, model.ModelSquarePartial, detail.Data.SquareState)
			})
			t.Run("channel_model_listing", func(t *testing.T) {
				exact := model.Model{ModelName: "listing-exact", Status: 1, SyncOfficial: 1}
				catalog := model.Model{ModelName: "listing-catalog", Status: 1}
				rule := model.Model{ModelName: "listing-rule-", NameRule: model.NameRulePrefix, Status: 1}
				for _, item := range []*model.Model{&exact, &catalog, &rule} {
					require.NoError(t, item.Insert())
				}
				active := model.Channel{Name: "Listing active", Type: 1, Key: "fixture", Models: "listing-exact, listing-new,listing-rule-child,listing-new, ,", Group: "default", Status: common.ChannelStatusEnabled}
				inactive := model.Channel{Name: "Listing inactive", Type: 1, Key: "fixture", Models: "listing-new,listing-disabled", Group: "default", Status: common.ChannelStatusManuallyDisabled}
				for _, channel := range []*model.Channel{&active, &inactive} {
					require.NoError(t, channel.Insert())
				}
				t.Cleanup(func() {
					require.NoError(t, db.Where("channel_id IN ?", []int{active.Id, inactive.Id}).Delete(&model.Ability{}).Error)
					require.NoError(t, db.Where("id IN ?", []int{active.Id, inactive.Id}).Delete(&model.Channel{}).Error)
					require.NoError(t, db.Unscoped().Where("model_name LIKE ?", "listing-%").Delete(&model.Model{}).Error)
					model.RefreshPricing()
				})
				type listingResponse struct {
					Success bool
					Data    struct {
						Items []model.Model
						Total int
					}
				}
				var response listingResponse
				modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=listing-", nil, &response)
				require.True(t, response.Success)
				require.Equal(t, 6, response.Data.Total)
				names := make([]string, 0)
				byName := make(map[string]model.Model)
				for _, item := range response.Data.Items {
					names = append(names, item.ModelName)
					byName[item.ModelName] = item
				}
				assert.Equal(t, []string{"listing-rule-", "listing-catalog", "listing-exact", "listing-disabled", "listing-new", "listing-rule-child"}, names)
				assert.True(t, byName[exact.ModelName].HasMetadata)
				assert.False(t, byName["listing-new"].HasMetadata)
				assert.Zero(t, byName["listing-new"].Id)
				assert.Equal(t, 2, byName["listing-new"].ConfiguredChannelCount)
				assert.Equal(t, 1, byName["listing-disabled"].ConfiguredChannelCount)
				assert.Empty(t, byName["listing-disabled"].BoundChannels)
				assert.Zero(t, byName[catalog.ModelName].ConfiguredChannelCount)
				for _, tc := range []struct {
					query string
					total int
					names []string
				}{
					{"&p=2&page_size=2", 6, []string{"listing-exact", "listing-disabled"}},
					{"&p=9&page_size=2", 6, []string{}},
					{"&status=enabled", 3, []string{"listing-rule-", "listing-catalog", "listing-exact"}},
					{"&sync_official=no", 2, []string{"listing-rule-", "listing-catalog"}},
					{"&vendor=0", 6, []string{"listing-rule-", "listing-catalog", "listing-exact", "listing-disabled", "listing-new", "listing-rule-child"}},
					{"&vendor=999", 0, []string{}},
				} {
					var page listingResponse
					modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=listing-"+tc.query, nil, &page)
					require.True(t, page.Success)
					assert.Equal(t, tc.total, page.Data.Total)
					actual := make([]string, 0)
					for _, item := range page.Data.Items {
						actual = append(actual, item.ModelName)
					}
					assert.Equal(t, tc.names, actual)
				}
				var legacy listingResponse
				modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?keyword=listing-", nil, &legacy)
				assert.Equal(t, 3, legacy.Data.Total)
				var count int64
				require.NoError(t, db.Model(&model.Model{}).Where("model_name LIKE ?", "listing-%").Count(&count).Error)
				assert.EqualValues(t, 3, count)
				prices, err := model.GetModelPricingSnapshot([]string{"listing-new"})
				require.NoError(t, err)
				require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: "listing-new", ExpectedVersion: prices.Entries[0].Version, Pricing: model.PricingValues{"ModelPrice": float64(0)}}}))
				t.Cleanup(func() {
					snapshot, err := model.GetModelPricingSnapshot([]string{"listing-new"})
					require.NoError(t, err)
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: "listing-new", ExpectedVersion: snapshot.Entries[0].Version, Reset: true}}))
				})
				require.NoError(t, db.Model(&model.Model{}).Where("model_name = ?", "listing-new").Count(&count).Error)
				assert.Zero(t, count)
				for _, price := range model.GetPricing() {
					assert.NotEqual(t, catalog.ModelName, price.ModelName)
				}
				created := model.Model{ModelName: "listing-new", Status: 1}
				require.NoError(t, created.Insert())
				var after listingResponse
				modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=listing-new", nil, &after)
				require.Len(t, after.Data.Items, 1)
				assert.Equal(t, created.Id, after.Data.Items[0].Id)
				require.NoError(t, created.Delete())
				after = listingResponse{}
				modelManagementRequest(t, SearchModelsMeta, "GET", "/api/models/search?include_channel_models=true&keyword=listing-new", nil, &after)
				require.Len(t, after.Data.Items, 1)
				assert.False(t, after.Data.Items[0].HasMetadata)
				require.NoError(t, db.Callback().Query().Before("gorm:query").Register("fail_listing_channels", func(tx *gorm.DB) {
					if tx.Statement.Table == "channels" {
						tx.AddError(errors.New("channel lookup failed"))
					}
				}))
				var failed listingResponse
				modelManagementRequest(t, GetAllModelsMeta, "GET", "/api/models/?include_channel_models=true", nil, &failed)
				require.NoError(t, db.Callback().Query().Remove("fail_listing_channels"))
				assert.False(t, failed.Success, "a channel lookup failure must not look like an empty configuration")

			})

			t.Run("pricing_saves_zero_switches_modes_and_rejects_stale_batches", func(t *testing.T) {
				before, err := model.GetModelPricingSnapshot([]string{"matrix-priced", "matrix-other"})
				require.NoError(t, err)
				changes := []model.ModelPricingChange{
					{ModelName: "matrix-priced", ExpectedVersion: before.EmptyVersion, Pricing: model.PricingValues{"ModelPrice": float64(0), "billing_setting.billing_mode": "ratio"}},
					{ModelName: "matrix-other", ExpectedVersion: before.EmptyVersion, Pricing: model.PricingValues{"ModelRatio": float64(1), "CreateCacheRatio": 1.25}},
				}
				require.NoError(t, model.UpdateModelPricing(changes))
				loaded, err := model.GetModelPricingSnapshot([]string{"matrix-priced"})
				require.NoError(t, err)
				assert.Equal(t, float64(0), loaded.Entries[0].Effective["ModelPrice"])
				stale := changes[0]
				changes[0].ExpectedVersion = loaded.Entries[0].Version
				changes[0].Pricing = model.PricingValues{"billing_setting.billing_mode": "tiered_expr", "billing_setting.billing_expr": `tier("base", p * 2 + c * 8 + cr * 0 + cc * 2.5)`, "ModelRatio": float64(1)}
				require.NoError(t, model.UpdateModelPricing(changes[:1]))
				loaded, err = model.GetModelPricingSnapshot([]string{"matrix-priced", "matrix-other"})
				require.NoError(t, err)
				assert.Equal(t, 1.25, loaded.Entries[0].Configured["CreateCacheRatio"])
				assert.Equal(t, "tiered_expr", loaded.Entries[1].Effective["billing_setting.billing_mode"])
				_, oldFixed := loaded.Entries[1].Configured["ModelPrice"]
				assert.False(t, oldFixed)
				other := model.ModelPricingChange{ModelName: "matrix-other", ExpectedVersion: loaded.Entries[0].Version, Pricing: model.PricingValues{"ModelRatio": float64(9)}}
				err = model.UpdateModelPricing([]model.ModelPricingChange{other, stale})
				assert.ErrorIs(t, err, model.ErrModelPricingConflict)
				after, err := model.GetModelPricingSnapshot([]string{"matrix-priced", "matrix-other"})
				require.NoError(t, err)
				assert.Equal(t, loaded.Entries, after.Entries)
				invalid := other
				invalid.Pricing = model.PricingValues{"ModelPrice": float64(-1)}
				assert.Error(t, model.UpdateModelPricing([]model.ModelPricingChange{invalid}))
				// A physical failure after earlier option writes must roll back all
				// rows and leave the previously published runtime price intact.
				writes := 0
				require.NoError(t, db.Callback().Update().Before("gorm:update").Register("fail_pricing_matrix", func(tx *gorm.DB) {
					if tx.Statement.Table == "options" {
						writes++
						if writes == 3 {
							tx.AddError(errors.New("injected write failure"))
						}
					}
				}))
				err = model.UpdateModelPricing([]model.ModelPricingChange{other})
				require.Error(t, err)
				require.NoError(t, db.Callback().Update().Remove("fail_pricing_matrix"))
				after, err = model.GetModelPricingSnapshot([]string{"matrix-priced", "matrix-other"})
				require.NoError(t, err)
				assert.Equal(t, loaded.Entries, after.Entries)
				ratio, _, _ := ratio_setting.GetModelRatio("matrix-other")
				assert.Equal(t, float64(1), ratio)
				// Two saves based on the same version cannot both succeed.
				var wg sync.WaitGroup
				results := make(chan error, 2)
				for _, value := range []float64{3, 4} {
					wg.Add(1)
					go func(value float64) {
						defer wg.Done()
						change := other
						change.Pricing = model.PricingValues{"ModelRatio": value}
						results <- model.UpdateModelPricing([]model.ModelPricingChange{change})
					}(value)
				}
				wg.Wait()
				close(results)
				successes, conflicts := 0, 0
				for err := range results {
					if err == nil {
						successes++
					} else if errors.Is(err, model.ErrModelPricingConflict) {
						conflicts++
					} else {
						require.NoError(t, err)
					}
				}
				assert.Equal(t, 1, successes)
				assert.Equal(t, 1, conflicts)
			})
			t.Run("task_usage_and_builtin_reset", func(t *testing.T) {
				snapshot, err := model.GetModelPricingSnapshot([]string{"matrix-task"})
				require.NoError(t, err)
				assert.Contains(t, snapshot.Entries[0].UsageSchema, "seconds")
				expression := `tier("base", u("seconds") * 0.25)`
				change := model.ModelPricingChange{ModelName: "matrix-task", ExpectedVersion: snapshot.Entries[0].Version, Pricing: model.PricingValues{"billing_setting.billing_mode": "tiered_expr", "billing_setting.billing_expr": expression}}
				require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
				snapshot, err = model.GetModelPricingSnapshot([]string{"matrix-task"})
				require.NoError(t, err)
				assert.Equal(t, expression, snapshot.Entries[0].Effective["billing_setting.billing_expr"])
				change.ExpectedVersion = snapshot.Entries[0].Version
				change.Pricing["billing_setting.billing_expr"] = `tier("base", u("undeclared") * 1)`
				assert.Error(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
				{
					const name = "gpt-6-astra"
					builtin, exists := billing_setting.GetBuiltinBillingExpr(name)
					require.True(t, exists)
					before, err := model.GetModelPricingSnapshot([]string{name})
					require.NoError(t, err)
					require.Empty(t, before.Entries[0].Configured)
					change = model.ModelPricingChange{ModelName: name, ExpectedVersion: before.Entries[0].Version, Pricing: model.PricingValues{"ModelPrice": float64(0)}}
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
					custom, err := model.GetModelPricingSnapshot([]string{name})
					require.NoError(t, err)
					assert.Equal(t, float64(0), custom.Entries[0].Effective["ModelPrice"])
					change.ExpectedVersion, change.Pricing, change.Reset = custom.Entries[0].Version, nil, true
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
					reset, err := model.GetModelPricingSnapshot([]string{name})
					require.NoError(t, err)
					assert.Empty(t, reset.Entries[0].Configured)
					assert.Equal(t, builtin, reset.Entries[0].Effective["billing_setting.billing_expr"])
				}
			})
			t.Run("concurrent_import_creates_one_record", func(t *testing.T) {
				update := model.MetadataSyncUpdate{MetadataSyncSelection: model.MetadataSyncSelection{ModelName: "matrix-concurrent-import", RecordVersion: model.MetadataRecordVersion(nil, nil, nil), Create: true}, Values: model.MetadataValues{Description: "Imported", Status: 1}}
				var wg sync.WaitGroup
				results := make(chan error, 2)
				for range 2 {
					wg.Go(func() {
						_, err := model.ApplyMetadataSync([]model.MetadataSyncUpdate{update}, nil)
						results <- err
					})
				}
				wg.Wait()
				close(results)
				successes, conflicts := 0, 0
				for err := range results {
					if err == nil {
						successes++
					} else if errors.Is(err, model.ErrMetadataSyncConflict) {
						conflicts++
					} else {
						require.NoError(t, err)
					}
				}
				assert.Equal(t, 1, successes)
				assert.Equal(t, 1, conflicts)
				var count int64
				require.NoError(t, db.Model(&model.Model{}).Where("model_name = ?", update.ModelName).Count(&count).Error)
				assert.EqualValues(t, 1, count)
			})
			t.Run("metadata_keeps_pricing_and_channel_identity", func(t *testing.T) {
				active := model.Channel{Name: "Active route", Type: 1, Status: common.ChannelStatusEnabled}
				disabled := model.Channel{Name: "Disabled route", Type: 1, Status: common.ChannelStatusManuallyDisabled}
				require.NoError(t, db.Create(&active).Error)
				require.NoError(t, db.Create(&disabled).Error)
				require.NoError(t, db.Create(&[]model.Ability{
					{Model: "matrix-hidden-unpriced", Group: "available", ChannelId: active.Id, Enabled: true},
					{Model: "matrix-hidden-unpriced", Group: "disabled", ChannelId: disabled.Id, Enabled: true},
					{Model: "matrix-hidden-unpriced", Group: "inactive", ChannelId: active.Id, Enabled: false},
				}).Error)
				exact := &model.Model{ModelName: "matrix-hidden-unpriced", Status: 0, SyncOfficial: 0}
				require.NoError(t, exact.Insert())
				rule := &model.Model{ModelName: "matrix-hidden-", NameRule: model.NameRulePrefix}
				enrichModels([]*model.Model{exact, rule})
				assert.Equal(t, []string{"available"}, exact.EnableGroups)
				assert.Equal(t, []model.BoundChannel{{Name: "Active route", Type: 1}}, exact.BoundChannels)
				assert.Equal(t, []string{"matrix-hidden-unpriced"}, rule.MatchedModels)
				assert.Empty(t, exact.Endpoints, "inferred endpoints must not become stored configuration")
				priceBefore, err := model.GetModelPricingSnapshot([]string{"matrix-hidden-unpriced"})
				require.NoError(t, err)
				require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: exact.ModelName, ExpectedVersion: priceBefore.Entries[0].Version, Pricing: model.PricingValues{"ModelPrice": float64(0)}}}))
				exact.ModelName = "matrix-renamed"
				exact.Endpoints = `{"openai":{"path":"/v1/chat/completions","method":"POST"}}`
				response := modelManagementRequest(t, UpdateModelMeta, http.MethodPut, "/api/models/", exact, nil)
				assert.Contains(t, response.Body.String(), `"success":true`)
				var reloaded model.Model
				require.NoError(t, db.First(&reloaded, exact.Id).Error)
				enrichModels([]*model.Model{&reloaded})
				assert.Equal(t, exact.Endpoints, reloaded.Endpoints)
				assert.Empty(t, reloaded.BoundChannels)
				prices, err := model.GetModelPricingSnapshot([]string{"matrix-hidden-unpriced", "matrix-renamed"})
				require.NoError(t, err)
				assert.Equal(t, float64(0), prices.Entries[0].Configured["ModelPrice"])
				assert.Empty(t, prices.Entries[1].Configured)
				require.NoError(t, reloaded.Delete())
				require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: "matrix-hidden-unpriced", ExpectedVersion: prices.Entries[0].Version, Reset: true}}))
				prices, err = model.GetModelPricingSnapshot([]string{"matrix-hidden-unpriced"})
				require.NoError(t, err)
				assert.Empty(t, prices.Entries[0].Configured)
				var ability model.Ability
				require.NoError(t, db.Where("model = ? AND channel_id = ? AND enabled = ?", "matrix-hidden-unpriced", active.Id, true).First(&ability).Error)
			})
			t.Run("metadata_preview_selection_versions_and_transaction", func(t *testing.T) {
				local := &model.Model{ModelName: "matrix-existing", Description: "Local description", Tags: "keep", Status: 1, SyncOfficial: 1}
				require.NoError(t, local.Insert())
				blocked := &model.Model{ModelName: "matrix-blocked", Status: 1, SyncOfficial: 0}
				require.NoError(t, blocked.Insert())
				require.NoError(t, db.Create(&model.Ability{Model: "matrix-new", Group: "default", ChannelId: 1, Enabled: true}).Error)
				var revision atomic.Int32
				var failVendors atomic.Bool
				upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
					assert.Contains(t, r.URL.Path, "/api/i18n/zh/newapi/")
					var payload any
					if strings.HasSuffix(r.URL.Path, "vendors.json") {
						if failVendors.Load() {
							w.WriteHeader(http.StatusServiceUnavailable)
							return
						}
						payload = []upstreamVendor{{Name: "Matrix vendor", Status: 1}}
					} else {
						payload = []upstreamModel{
							{ModelName: "matrix-existing", Description: fmt.Sprintf("Upstream %d", revision.Load()), VendorName: "Matrix vendor", Tags: "changed", Status: 0, Endpoints: []byte(`{"openai":{"path":"/v1/chat/completions","method":"POST"}}`)},
							{ModelName: "matrix-new", Description: "New model", VendorName: "Matrix vendor", Status: 0, Endpoints: []byte(`{"openai":"/v1/chat/completions"}`)},
							{ModelName: "matrix-blocked", Description: "Do not overwrite", Status: 1},
							{ModelName: "matrix-catalog", Description: "Catalog only", Status: 1},
						}
					}
					encoded, err := common.Marshal(payload)
					require.NoError(t, err)
					_, _ = w.Write(encoded)
				}))
				defer upstream.Close()
				t.Setenv("SYNC_UPSTREAM_BASE", upstream.URL)
				t.Setenv("SYNC_HTTP_RETRY", "1")
				var preview struct {
					Success bool
					Data    struct {
						Source     metadataSyncSource
						Candidates []metadataSyncCandidate
					}
				}
				response := modelManagementRequest(t, SyncUpstreamPreview, "GET", "/api/models/sync_upstream/preview?locale=zh", nil, &preview)
				require.Equal(t, http.StatusOK, response.Code)
				require.True(t, preview.Success, response.Body.String())
				byName := make(map[string]metadataSyncCandidate)
				for _, candidate := range preview.Data.Candidates {
					byName[candidate.ModelName] = candidate
				}
				assert.Equal(t, "site", byName["matrix-new"].Scope)
				assert.Equal(t, "catalog", byName["matrix-catalog"].Scope)
				assert.Equal(t, "blocked", byName["matrix-blocked"].Kind)
				var count int64
				require.NoError(t, db.Model(&model.Vendor{}).Count(&count).Error)
				assert.Zero(t, count)
				body := map[string]any{"locale": "zh", "source_version": preview.Data.Source.Version, "selections": []model.MetadataSyncSelection{
					{ModelName: "matrix-existing", RecordVersion: byName["matrix-existing"].RecordVersion, Fields: []string{"description", "endpoints"}},
					{ModelName: "matrix-new", RecordVersion: byName["matrix-new"].RecordVersion, Create: true},
				}}
				beforePricing, err := model.GetModelPricingSnapshot([]string{"matrix-priced"})
				require.NoError(t, err)
				// A failed model insert must also undo the earlier metadata update
				// and the newly inserted supplier.
				require.NoError(t, db.Callback().Create().Before("gorm:create").Register("fail_metadata_matrix", func(tx *gorm.DB) {
					if tx.Statement.Table == "models" {
						tx.AddError(errors.New("injected metadata failure"))
					}
				}))
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", body, nil)
				assert.NotEqual(t, http.StatusOK, response.Code)
				require.NoError(t, db.Callback().Create().Remove("fail_metadata_matrix"))
				var persisted model.Model
				require.NoError(t, db.First(&persisted, local.Id).Error)
				assert.Equal(t, "Local description", persisted.Description)
				require.NoError(t, db.Model(&model.Vendor{}).Count(&count).Error)
				assert.Zero(t, count)
				var result struct {
					Success bool
					Data    model.MetadataSyncResult
				}
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", body, &result)
				require.Equal(t, http.StatusOK, response.Code, response.Body.String())
				require.True(t, result.Success)
				assert.Equal(t, []string{"matrix-new"}, result.Data.CreatedModels)
				assert.Equal(t, []string{"Matrix vendor"}, result.Data.CreatedVendors)
				require.NoError(t, db.First(&persisted, local.Id).Error)
				assert.Equal(t, "Upstream 0", persisted.Description)
				assert.Equal(t, "keep", persisted.Tags)
				assert.Equal(t, 1, persisted.Status)
				assert.Zero(t, persisted.VendorID)
				assert.JSONEq(t, `{"openai":{"path":"/v1/chat/completions","method":"POST"}}`, persisted.Endpoints)
				var created model.Model
				require.NoError(t, db.Where("model_name = ?", "matrix-new").First(&created).Error)
				assert.Equal(t, 1, created.SyncOfficial)
				assert.Zero(t, created.Status)
				afterPricing, err := model.GetModelPricingSnapshot([]string{"matrix-priced"})
				require.NoError(t, err)
				assert.Equal(t, beforePricing.Entries, afterPricing.Entries)
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", body, nil)
				assert.Equal(t, http.StatusConflict, response.Code)
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", map[string]any{}, nil)
				assert.Equal(t, http.StatusBadRequest, response.Code)
				body["selections"] = []model.MetadataSyncSelection{{ModelName: "matrix-blocked", RecordVersion: byName["matrix-blocked"].RecordVersion, Fields: []string{"description"}}}
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", body, nil)
				assert.Equal(t, http.StatusBadRequest, response.Code)
				revision.Add(1)
				response = modelManagementRequest(t, SyncUpstreamModels, "POST", "/api/models/sync_upstream", body, nil)
				assert.Equal(t, http.StatusConflict, response.Code)
				failVendors.Store(true)
				modelManagementRequest(t, SyncUpstreamPreview, "GET", "/api/models/sync_upstream/preview?locale=zh", nil, &preview)
				assert.False(t, preview.Success)
			})
		})
	}
}

func TestMetadataSyncLocaleAndEndpointValidation(t *testing.T) {
	for _, locale := range []struct{ input, expected string }{{"zh", "zh"}, {"zh-CN", "zh"}, {"en", "en"}, {"ja", "ja"}} {
		t.Run(locale.input, func(t *testing.T) {
			normalized, ok := normalizeLocale(locale.input)
			assert.True(t, ok)
			assert.Equal(t, locale.expected, normalized)
		})
	}
	_, valid := normalizeLocale("invalid")
	assert.False(t, valid)
	for _, endpoint := range []string{`1`, `null`, `{"openai":false}`, `{"openai":{"path":"invalid"}}`} {
		assert.Error(t, model.ValidateModelEndpoints(endpoint))
	}
}

func TestVendorManagementDatabaseMatrix(t *testing.T) {
	for _, dialect := range []struct{ kind, env string }{{"sqlite", ""}, {"mysql", "TEST_MYSQL_DSN"}, {"postgres", "TEST_POSTGRES_DSN"}} {
		t.Run(dialect.kind, func(t *testing.T) {
			if dialect.env != "" && os.Getenv(dialect.env) == "" {
				t.Skip("set " + dialect.env)
			}
			db := modelManagementDB(t, dialect.kind, os.Getenv(dialect.env))

			t.Run("pricing_reads_keep_default_brands_without_writing_vendors", func(t *testing.T) {
				channel := model.Channel{Name: "Vendor fixture", Type: 1, Status: common.ChannelStatusEnabled}
				require.NoError(t, db.Create(&channel).Error)
				require.NoError(t, db.Create(&model.Ability{Model: "gemini-vendor-fixture", Group: "default", ChannelId: channel.Id, Enabled: true}).Error)
				model.RefreshPricing()
				model.GetPricing()
				vendors := model.GetVendors()
				require.Len(t, vendors, 1)
				assert.Equal(t, "Google", vendors[0].Name)
				assert.Equal(t, "Gemini.Color", vendors[0].Icon)
				assert.Negative(t, vendors[0].ID)
				var count int64
				require.NoError(t, db.Model(&model.Vendor{}).Count(&count).Error)
				assert.Zero(t, count)
				saved := model.Vendor{Name: "Google", Icon: "Gemini.Color"}
				require.NoError(t, saved.Insert())
				assert.Equal(t, saved.Id, model.GetVendors()[0].ID)
				require.NoError(t, saved.Delete())
				assert.Equal(t, vendors[0].ID, model.GetVendors()[0].ID)
				require.NoError(t, db.Model(&model.Vendor{}).Count(&count).Error)
				assert.Zero(t, count, "refresh must not recreate a deleted vendor")
			})
			t.Run("metadata_ownership_preview_merge_delete_and_rollback", func(t *testing.T) {
				source := model.Vendor{Name: "  Vendor Source  ", Icon: "Gemini.Color"}
				target := model.Vendor{Name: "Vendor Target", Description: "Keep target", Icon: "OpenAI"}
				require.NoError(t, source.Insert())
				require.NoError(t, target.Insert())
				assert.Equal(t, "Vendor Source", source.Name)
				assert.Error(t, (&model.Vendor{Name: "vendor source"}).Insert())
				assert.Error(t, (&model.Vendor{Name: " "}).Insert())
				require.NoError(t, db.Model(&model.Vendor{}).Where("id = ?", source.Id).Update("status", 0).Error)
				loaded, err := model.GetVendorByID(source.Id)
				require.NoError(t, err)
				staleVersion := loaded.Version
				edit := model.Vendor{Id: source.Id, Name: source.Name, Description: "Updated source", Icon: source.Icon, Version: loaded.Version}
				require.NoError(t, edit.Update())
				updated, err := model.GetVendorByID(source.Id)
				require.NoError(t, err)
				assert.Equal(t, loaded.CreatedTime, updated.CreatedTime)
				assert.Zero(t, updated.Status)
				edit.Version = staleVersion
				assert.ErrorIs(t, edit.Update(), model.ErrVendorConflict)

				one := model.Model{ModelName: "vendor-model-one", VendorID: source.Id, Icon: "Custom", Description: "Preserve description", Status: 0, SyncOfficial: 0}
				rule := model.Model{ModelName: "vendor-rule-", VendorID: source.Id, NameRule: model.NameRulePrefix, Status: 1, SyncOfficial: 1}
				require.NoError(t, one.Insert())
				require.NoError(t, rule.Insert())
				priceBefore, err := model.GetModelPricingSnapshot([]string{one.ModelName})
				require.NoError(t, err)
				require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: one.ModelName, ExpectedVersion: priceBefore.Entries[0].Version, Pricing: model.PricingValues{"ModelPrice": float64(0.25)}}}))
				priceBefore, err = model.GetModelPricingSnapshot([]string{one.ModelName})
				require.NoError(t, err)
				channel := model.Channel{Name: "Unchanged vendor channel", Type: 1, Status: common.ChannelStatusEnabled}
				require.NoError(t, db.Create(&channel).Error)
				ability := model.Ability{Model: one.ModelName, Group: "default", ChannelId: channel.Id, Enabled: true}
				require.NoError(t, db.Create(&ability).Error)
				linked, total, err := model.SearchVendors("", 0, 20, "linked")
				require.NoError(t, err)
				require.Len(t, linked, 1)
				assert.EqualValues(t, 1, total)
				assert.EqualValues(t, 2, linked[0].ModelCount)
				unlinked, _, err := model.SearchVendors("Vendor Target", 0, 20, "unlinked")
				require.NoError(t, err)
				require.Len(t, unlinked, 1)
				var references *model.VendorReferenceError
				err = model.DeleteVendors([]int{source.Id, target.Id})
				require.ErrorAs(t, err, &references)
				assert.EqualValues(t, 2, references.Counts[source.Id])
				_, err = model.GetVendorByID(target.Id)
				require.NoError(t, err, "bulk delete must not partially delete unreferenced vendors")
				var response struct {
					Success         bool
					Code            string
					ReferenceCounts map[int]int64 `json:"reference_counts"`
				}
				recorder := modelManagementRequest(t, PreviewVendorOperation, http.MethodPost, "/api/vendors/operations/preview", model.VendorOperation{Action: "delete", VendorIDs: []int{source.Id}}, &response)
				assert.Equal(t, http.StatusConflict, recorder.Code)
				assert.Equal(t, "VENDOR_REFERENCED", response.Code)
				assert.EqualValues(t, 2, response.ReferenceCounts[source.Id])

				disappearing := model.Vendor{Name: "Preview target"}
				require.NoError(t, disappearing.Insert())
				staleAssignment := model.VendorOperation{Action: "assign", ModelIDs: []int{one.Id}, TargetVendorID: disappearing.Id}
				stalePreview, err := model.PreviewVendorOperation(staleAssignment)
				require.NoError(t, err)
				staleAssignment.ExpectedVersion = stalePreview.Version
				require.NoError(t, disappearing.Delete())
				recorder = modelManagementRequest(t, ApplyVendorOperation, http.MethodPost, "/api/vendors/operations", staleAssignment, &response)
				assert.Equal(t, http.StatusConflict, recorder.Code)
				assert.Equal(t, "VENDOR_CONFLICT", response.Code)

				assign := model.VendorOperation{Action: "assign", ModelIDs: []int{one.Id}, TargetVendorID: target.Id}
				preview, err := model.PreviewVendorOperation(assign)
				require.NoError(t, err)
				require.Len(t, preview.Models, 1)
				assign.ExpectedVersion = preview.Version
				one.Description = "Updated in the same timestamp"
				require.NoError(t, db.Model(&model.Model{}).Where("id = ?", one.Id).Update("description", one.Description).Error)
				_, err = model.ApplyVendorOperation(assign)
				assert.ErrorIs(t, err, model.ErrVendorConflict)
				preview, err = model.PreviewVendorOperation(assign)
				require.NoError(t, err)
				assign.ExpectedVersion = preview.Version
				target.Description = "New target description"
				require.NoError(t, target.Update())
				_, err = model.ApplyVendorOperation(assign)
				assert.ErrorIs(t, err, model.ErrVendorConflict)
				preview, err = model.PreviewVendorOperation(assign)
				require.NoError(t, err)
				assign.ExpectedVersion = preview.Version
				result, err := model.ApplyVendorOperation(assign)
				require.NoError(t, err)
				assert.Equal(t, []int{one.Id}, result.UpdatedModels)
				var after model.Model
				after = model.Model{}
				require.NoError(t, db.First(&after, one.Id).Error)
				assert.Equal(t, target.Id, after.VendorID)
				assert.Equal(t, one.Description, after.Description)
				assert.Equal(t, one.Icon, after.Icon)
				assert.Equal(t, one.Status, after.Status)
				after = model.Model{}
				require.NoError(t, db.First(&after, rule.Id).Error)
				assert.Equal(t, source.Id, after.VendorID)
				assign.TargetVendorID = 0
				preview, err = model.PreviewVendorOperation(assign)
				require.NoError(t, err)
				assign.ExpectedVersion = preview.Version
				_, err = model.ApplyVendorOperation(assign)
				require.NoError(t, err)
				after = model.Model{}
				require.NoError(t, db.First(&after, one.Id).Error)
				assert.Zero(t, after.VendorID)
				after.VendorID = -1001
				assert.Error(t, after.Update(), "display-only vendors cannot become stored references")

				merge := model.VendorOperation{Action: "merge", VendorIDs: []int{source.Id}, TargetVendorID: target.Id}
				preview, err = model.PreviewVendorOperation(merge)
				require.NoError(t, err)
				merge.ExpectedVersion = preview.Version
				require.NoError(t, db.Callback().Delete().Before("gorm:delete").Register("vendor_delete_failure", func(tx *gorm.DB) {
					if tx.Statement.Table == "vendors" {
						tx.AddError(errors.New("injected vendor delete failure"))
					}
				}))
				_, err = model.ApplyVendorOperation(merge)
				require.Error(t, err)
				require.NoError(t, db.Callback().Delete().Remove("vendor_delete_failure"))
				after = model.Model{}
				require.NoError(t, db.First(&after, rule.Id).Error)
				assert.Equal(t, source.Id, after.VendorID, "ownership updates roll back when deletion fails")
				_, err = model.GetVendorByID(source.Id)
				require.NoError(t, err)
				_, err = model.ApplyVendorOperation(merge)
				require.NoError(t, err)
				_, err = model.GetVendorByID(source.Id)
				assert.ErrorIs(t, err, gorm.ErrRecordNotFound)
				retained, err := model.GetVendorByID(target.Id)
				require.NoError(t, err)
				assert.Equal(t, target.Description, retained.Description)
				assert.Equal(t, "OpenAI", retained.Icon)
				assert.EqualValues(t, 1, retained.ModelCount)
				after = one
				after.VendorID = source.Id
				assert.Error(t, after.Update(), "deleted vendors cannot acquire new references")
				priceAfter, err := model.GetModelPricingSnapshot([]string{one.ModelName})
				require.NoError(t, err)
				assert.Equal(t, priceBefore.Entries[0], priceAfter.Entries[0], "assignment and merge preserve model pricing")
				var retainedChannel model.Channel
				require.NoError(t, db.First(&retainedChannel, channel.Id).Error)
				assert.Equal(t, channel.Name, retainedChannel.Name)
				assert.Equal(t, channel.Status, retainedChannel.Status)
				var retainedAbility model.Ability
				require.NoError(t, db.Where("model = ? AND channel_id = ?", one.ModelName, channel.Id).First(&retainedAbility).Error)
				assert.Equal(t, ability.Group, retainedAbility.Group)
				assert.Equal(t, ability.Enabled, retainedAbility.Enabled)
			})
			t.Run("concurrent_create_and_delete_never_orphan_model", func(t *testing.T) {
				vendor := model.Vendor{Name: "Concurrent owner"}
				require.NoError(t, vendor.Insert())
				var createErr, deleteErr error
				var wg sync.WaitGroup
				wg.Add(2)
				go func() {
					defer wg.Done()
					createErr = (&model.Model{ModelName: "concurrent-owned-model", VendorID: vendor.Id}).Insert()
				}()
				go func() { defer wg.Done(); deleteErr = vendor.Delete() }()
				wg.Wait()
				if createErr == nil {
					require.Error(t, deleteErr)
				} else {
					require.NoError(t, deleteErr)
				}
				var models []model.Model
				require.NoError(t, db.Where("model_name = ?", "concurrent-owned-model").Find(&models).Error)
				if len(models) != 0 {
					_, err := model.GetVendorByID(models[0].VendorID)
					require.NoError(t, err)
				}
			})
		})
	}
}

func TestModelDeletionDatabaseMatrix(t *testing.T) {
	for _, dialect := range []struct{ kind, env string }{{"sqlite", ""}, {"mysql", "TEST_MYSQL_DSN"}, {"postgres", "TEST_POSTGRES_DSN"}} {
		t.Run(dialect.kind, func(t *testing.T) {
			if dialect.env != "" && os.Getenv(dialect.env) == "" {
				t.Skip("set " + dialect.env + " to run this database")
			}
			db := modelManagementDB(t, dialect.kind, os.Getenv(dialect.env))

			var response struct {
				Success bool
				Data    model.ModelDeleteResult
			}
			metadataOnly := model.Model{ModelName: "metadata-only", Status: 1}
			require.NoError(t, metadataOnly.Insert())
			channel := model.Channel{Name: "Retained channel", Type: 1, Key: "fixture-key", Models: metadataOnly.ModelName, Group: "default", Status: common.ChannelStatusEnabled}
			require.NoError(t, db.Create(&channel).Error)
			require.NoError(t, channel.UpdateAbilities(db))
			recorder := modelManagementRequest(t, func(c *gin.Context) {
				c.Params = gin.Params{{Key: "id", Value: strconv.Itoa(metadataOnly.Id)}}
				DeleteModelMeta(c)
			}, http.MethodDelete, "/api/models/"+strconv.Itoa(metadataOnly.Id), nil, &response)
			require.True(t, response.Success, recorder.Body.String())
			assert.Equal(t, model.ModelDeleteResult{DeletedCount: 1}, response.Data)
			var retained model.Channel
			require.NoError(t, db.First(&retained, channel.Id).Error)
			assert.Equal(t, channel.Models, retained.Models)
			var count int64
			require.NoError(t, db.Model(&model.Ability{}).Where("channel_id = ?", channel.Id).Count(&count).Error)
			assert.EqualValues(t, 1, count)

			for _, rule := range []int{model.NameRuleExact, model.NameRulePrefix, model.NameRuleContains, model.NameRuleSuffix} {
				t.Run(fmt.Sprintf("rule_%d_exact_names_only_atomic_and_cached", rule), func(t *testing.T) {
					name := fmt.Sprintf("delete-rule-%d", rule)
					first := model.Model{ModelName: name, NameRule: rule, Status: 1}
					second := model.Model{ModelName: name + "-second", Status: 1}
					require.NoError(t, first.Insert())
					require.NoError(t, second.Insert())
					mapping := `{"` + name + `":"upstream-name"}`
					priority, weight := int64(7), uint(9)
					channels := []model.Channel{
						{Name: "Enabled", Type: 1, Key: "fixture-key", Models: name + "," + name + "-keep," + second.ModelName, Group: "default,vip", Status: common.ChannelStatusEnabled, ModelMapping: &mapping, Priority: &priority, Weight: &weight},
						{Name: "Disabled", Type: 1, Models: name + ",prefix-" + name, Group: "disabled-group", Status: common.ChannelStatusManuallyDisabled},
						{Name: "Last model", Type: 1, Models: name, Group: "last-model-group", Status: common.ChannelStatusEnabled},
						{Name: "Case-sensitive name", Type: 1, Models: strings.ToUpper(name), Group: "case-group", Status: common.ChannelStatusEnabled},
					}
					for i := range channels {
						require.NoError(t, db.Create(&channels[i]).Error)
						require.NoError(t, channels[i].UpdateAbilities(db))
					}
					common.MemoryCacheEnabled = true
					model.InitChannelCache()
					cached, err := model.GetRandomSatisfiedChannel("default", name, 0, nil)
					require.NoError(t, err)
					require.NotNil(t, cached)
					baseline, err := model.GetModelPricingSnapshot([]string{name})
					require.NoError(t, err)
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: name, ExpectedVersion: baseline.EmptyVersion, Pricing: model.PricingValues{"ModelPrice": float64(2)}}}))
					pricingBefore, err := model.GetModelPricingSnapshot([]string{name, second.ModelName})
					require.NoError(t, err)
					if rule != model.NameRuleExact {
						_, err := model.DeleteModelMetadata([]int{first.Id, second.Id}, true, true)
						require.EqualError(t, err, "only exact-match models can be removed from channels")
						after, err := model.GetModelPricingSnapshot([]string{name, second.ModelName})
						require.NoError(t, err)
						assert.Equal(t, pricingBefore, after)
						require.NoError(t, db.Model(&model.Model{}).Where("id IN ?", []int{first.Id, second.Id}).Count(&count).Error)
						assert.EqualValues(t, 2, count)
						for _, original := range channels {
							var after model.Channel
							require.NoError(t, db.First(&after, original.Id).Error)
							assert.Equal(t, original, after)
						}
						return
					}
					body := map[string]any{"model_ids": []int{first.Id, second.Id, first.Id}, "remove_from_channels": true}
					// A failure at the final metadata delete must undo every earlier
					// channel/ability write and keep the published cache intact.
					require.NoError(t, db.Callback().Delete().Before("gorm:delete").Register("fail_model_deletion", func(tx *gorm.DB) {
						if tx.Statement.Table == "models" {
							tx.AddError(errors.New("injected model deletion failure"))
						}
					}))
					result, err := model.DeleteModelMetadata([]int{first.Id, second.Id}, true, false)
					require.Error(t, err)
					assert.Zero(t, result)
					require.NoError(t, db.Callback().Delete().Remove("fail_model_deletion"))
					for _, original := range channels {
						var after model.Channel
						require.NoError(t, db.First(&after, original.Id).Error)
						assert.Equal(t, original, after)
					}
					cached, err = model.GetRandomSatisfiedChannel("default", name, 0, nil)
					require.NoError(t, err)
					require.NotNil(t, cached)
					recorder := modelManagementRequest(t, BatchDeleteModelMeta, http.MethodPost, "/api/models/delete", body, &response)
					require.True(t, response.Success, recorder.Body.String())
					assert.Equal(t, model.ModelDeleteResult{DeletedCount: 2, UpdatedChannels: 3}, response.Data)
					for i, original := range channels {
						var after model.Channel
						require.NoError(t, db.First(&after, original.Id).Error)
						original.Models = []string{name + "-keep", "prefix-" + name, "", strings.ToUpper(name)}[i]
						assert.Equal(t, original, after, "only the model list changes")
					}
					var abilities []model.Ability
					require.NoError(t, db.Where("channel_id IN ?", []int{channels[0].Id, channels[1].Id, channels[2].Id, channels[3].Id}).Find(&abilities).Error)
					assert.Len(t, abilities, 4)
					for _, ability := range abilities {
						assert.NotEqual(t, name, ability.Model)
						assert.NotEqual(t, second.ModelName, ability.Model)
						assert.NotEmpty(t, ability.Model)
						if ability.ChannelId == channels[0].Id {
							assert.Equal(t, &priority, ability.Priority)
							assert.Equal(t, weight, ability.Weight)
							assert.True(t, ability.Enabled)
						}
						if ability.ChannelId == channels[1].Id {
							assert.False(t, ability.Enabled)
						}
					}
					for _, group := range []string{"default", "vip", "last-model-group"} {
						cached, _ = model.GetRandomSatisfiedChannel(group, name, 0, nil)
						assert.Nil(t, cached)
					}
					cached, err = model.GetRandomSatisfiedChannel("default", name+"-keep", 0, nil)
					require.NoError(t, err)
					require.NotNil(t, cached)
					pricingAfter, err := model.GetModelPricingSnapshot([]string{name, second.ModelName})
					require.NoError(t, err)
					assert.Equal(t, pricingBefore, pricingAfter)
					require.NoError(t, db.Model(&model.Model{}).Where("id IN ?", []int{first.Id, second.Id}).Count(&count).Error)
					assert.Zero(t, count)
					_, err = model.DeleteModelMetadata([]int{first.Id}, true, false)
					assert.Error(t, err, "stale selections cannot delete newly created records")
				})
			}
			for _, removeChannels := range []bool{false, true} {
				t.Run(fmt.Sprintf("pricing_removal_channels_%t", removeChannels), func(t *testing.T) {
					name := fmt.Sprintf("remove-pricing-%t", removeChannels)
					metadata := model.Model{ModelName: name, NameRule: model.NameRuleExact, Status: 1}
					require.NoError(t, metadata.Insert())
					keep := name + "-keep"
					channel := model.Channel{Name: "Independent pricing removal", Type: 1, Models: name + "," + keep, Group: "pricing-removal", Status: common.ChannelStatusEnabled}
					require.NoError(t, db.Create(&channel).Error)
					require.NoError(t, channel.UpdateAbilities(db))
					model.InitChannelCache()
					baseline, err := model.GetModelPricingSnapshot([]string{name, keep})
					require.NoError(t, err)
					pricing := model.PricingValues{"ModelRatio": float64(1), "ModelPrice": float64(0), "CompletionRatio": float64(2), "CacheRatio": float64(0.1), "CreateCacheRatio": float64(1.25), "ImageRatio": float64(3), "AudioRatio": float64(4), "AudioCompletionRatio": float64(5), "billing_setting.billing_mode": "tiered_expr", "billing_setting.billing_expr": `tier("base", p * 2 + c * 4)`}
					require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{
						{ModelName: name, ExpectedVersion: baseline.EmptyVersion, Pricing: pricing},
						{ModelName: keep, ExpectedVersion: baseline.EmptyVersion, Pricing: model.PricingValues{"ModelPrice": float64(9)}},
					}))
					before, err := model.GetModelPricingSnapshot([]string{name, keep})
					require.NoError(t, err)
					body := map[string]any{"model_ids": []int{metadata.Id}, "remove_from_channels": removeChannels, "remove_pricing": true}
					for _, single := range []bool{false, true} {
						recorder := modelManagementRequest(t, func(c *gin.Context) {
							c.Set("role", common.RoleAdminUser)
							if single {
								c.Params = gin.Params{{Key: "id", Value: strconv.Itoa(metadata.Id)}}
								DeleteModelMeta(c)
							} else {
								BatchDeleteModelMeta(c)
							}
						}, http.MethodPost, "/api/models/delete?remove_pricing=true", body, nil)
						assert.Equal(t, http.StatusForbidden, recorder.Code, "pricing permissions cannot be bypassed through deletion")
					}
					updates := 0
					require.NoError(t, db.Callback().Update().Before("gorm:update").Register("fail_deleted_pricing", func(tx *gorm.DB) {
						if tx.Statement.Table == "options" {
							updates++
							if updates == 3 {
								tx.AddError(errors.New("injected pricing deletion failure"))
							}
						}
					}))
					_, err = model.DeleteModelMetadata([]int{metadata.Id}, removeChannels, true)
					require.Error(t, err)
					require.NoError(t, db.Callback().Update().Remove("fail_deleted_pricing"))
					after, err := model.GetModelPricingSnapshot([]string{name, keep})
					require.NoError(t, err)
					assert.Equal(t, before, after, "partial option writes roll back")
					assert.Equal(t, billing_setting.BillingModeTieredExpr, billing_setting.GetBillingMode(name), "failed deletion must not publish new runtime pricing")
					var retained model.Model
					require.NoError(t, db.First(&retained, metadata.Id).Error)
					var channelAfter model.Channel
					require.NoError(t, db.First(&channelAfter, channel.Id).Error)
					assert.Equal(t, channel.Models, channelAfter.Models)
					_, err = model.DeleteModelMetadata([]int{metadata.Id, 999999}, removeChannels, true)
					assert.Error(t, err, "a missing model aborts the whole batch")
					recorder := modelManagementRequest(t, BatchDeleteModelMeta, http.MethodPost, "/api/models/delete", body, &response)
					require.True(t, response.Success, recorder.Body.String())
					after, err = model.GetModelPricingSnapshot([]string{name, keep})
					require.NoError(t, err)
					assert.Empty(t, after.Entries[0].Configured)
					assert.Equal(t, before.Entries[1], after.Entries[1], "name rules do not expand pricing deletion")
					assert.Equal(t, billing_setting.BillingModeRatio, billing_setting.GetBillingMode(name))
					_, hasExpr := billing_setting.GetBillingExpr(name)
					assert.False(t, hasExpr)
					require.NoError(t, db.First(&channelAfter, channel.Id).Error)
					expectedModels := channel.Models
					if removeChannels {
						expectedModels = keep
					}
					assert.Equal(t, expectedModels, channelAfter.Models)
					require.NoError(t, db.Model(&model.Model{}).Where("id = ?", metadata.Id).Count(&count).Error)
					assert.Zero(t, count)
				})
			}
			for _, ids := range [][]int{nil, {0}, {-1}, make([]int, 1001)} {
				_, err := model.DeleteModelMetadata(ids, true, false)
				assert.Error(t, err)
			}
		})
	}
}

func TestSharedModelPluginPricingDatabaseMatrix(t *testing.T) {
	const name = "shared-model::priced"
	const base = `tier("base", u("seconds") * 0.4)`
	const variant = `tier("beta", u("credits") * 2)`
	for _, dialect := range []struct{ kind, env string }{{"sqlite", ""}, {"mysql", "TEST_MYSQL_DSN"}, {"postgres", "TEST_POSTGRES_DSN"}} {
		t.Run(dialect.kind, func(t *testing.T) {
			if dialect.env != "" && os.Getenv(dialect.env) == "" {
				t.Skip("set " + dialect.env + " to run this database")
			}
			db := modelManagementDB(t, dialect.kind, os.Getenv(dialect.env))
			for _, spec := range []struct{ key, field, unit string }{{"matrix-alpha", "seconds", "second"}, {"matrix-beta", "credits", "credit"}} {
				source := fmt.Sprintf(`
		export const meta = {apiVersion:1,key:%q,name:%q,version:"1.0.0",author:{name:"Test"},models:[%q],fetchMode:"per_task",usageSchema:{%s:{type:"number",unit:%q}}};
		export function buildSubmitRequest(){return {};}
		export function parseSubmitResponse(){return {};}
		export function buildQueryRequest(){return {};}
		export function parseTaskResult(){return {};}
		`, spec.key, spec.key, name, spec.field, spec.unit)
				_, err := jsplugin.DefaultRegistry.Register(source, jsplugin.Options{})
				require.NoError(t, err)
				t.Cleanup(func() { jsplugin.DefaultRegistry.Unregister(spec.key) })
				if spec.key == "matrix-alpha" {
					single, err := model.GetModelPricingSnapshot([]string{name})
					require.NoError(t, err)
					require.Len(t, single.Entries[0].PluginVariants, 1, "a sole provider must expose its separate pricing editor")
					assert.Equal(t, "matrix-alpha", single.Entries[0].PluginVariants[0].PluginKey)
				}
			}

			// Representative existing options have no plugin-expression row.
			baseJSON, err := common.Marshal(map[string]string{name: base})
			require.NoError(t, err)
			modeJSON, err := common.Marshal(map[string]string{name: "tiered_expr"})
			require.NoError(t, err)
			require.NoError(t, db.Create(&[]model.Option{
				{Key: "ModelPrice", Value: `{"unrelated-model":0.75}`},
				{Key: "billing_setting.billing_expr", Value: string(baseJSON)},
				{Key: "billing_setting.billing_mode", Value: string(modeJSON)},
			}).Error)
			require.NoError(t, config.GlobalConfig.LoadFromDB(map[string]string{
				"billing_setting.billing_expr": string(baseJSON), "billing_setting.billing_mode": string(modeJSON),
			}))
			before, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			require.Len(t, before.Entries, 1)
			require.Len(t, before.Entries[0].PluginVariants, 2)
			assert.True(t, before.Entries[0].PluginVariants[0].Compatible)
			assert.False(t, before.Entries[0].PluginVariants[1].Compatible)
			assert.Equal(t, base, before.Entries[0].PluginVariants[1].Effective)
			change := model.ModelPricingChange{ModelName: name, ExpectedVersion: before.Entries[0].Version, Pricing: model.PricingValues{
				"billing_setting.billing_mode": "tiered_expr", "billing_setting.billing_expr": base,
				billing_setting.PluginBillingExprOption: map[string]any{"matrix-beta": variant},
			}}
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
			loaded, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, change.Pricing, loaded.Entries[0].Configured)
			require.Len(t, loaded.Entries[0].PluginVariants, 2)
			assert.True(t, loaded.Entries[0].PluginVariants[0].Compatible)
			assert.Equal(t, base, loaded.Entries[0].PluginVariants[0].Effective)
			assert.True(t, loaded.Entries[0].PluginVariants[1].Compatible)
			assert.Equal(t, variant, loaded.Entries[0].PluginVariants[1].Configured)
			// Ordinary relay pricing and the existing plugin expressions are
			// saved together without changing either plugin's billing contract.
			ordinary := model.ModelPricingChange{ModelName: name, ExpectedVersion: loaded.Entries[0].Version, Pricing: model.PricingValues{
				"billing_setting.billing_mode": "tiered_expr", "billing_setting.billing_expr": `tier("image", fixed(0.04)) * image_count`,
				billing_setting.PluginBillingExprOption: map[string]any{"matrix-alpha": base, "matrix-beta": variant},
			}}
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{ordinary}))
			separate, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, ordinary.Pricing, separate.Entries[0].Configured)
			assert.Equal(t, base, separate.Entries[0].PluginVariants[0].Effective)
			assert.Equal(t, variant, separate.Entries[0].PluginVariants[1].Effective)
			// Keep exercising the pre-existing plugin-default configuration below.
			change.ExpectedVersion = separate.Entries[0].Version
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
			var flat map[string]string
			require.NoError(t, common.UnmarshalJsonStr(loaded.Options[billing_setting.PluginBillingExprOption], &flat))
			assert.Equal(t, map[string]string{"matrix-beta::" + name: variant}, flat)
			all, err := model.GetModelPricingSnapshot(nil)
			require.NoError(t, err)
			for _, entry := range all.Entries {
				assert.NotEqual(t, "matrix-beta::"+name, entry.ModelName)
			}
			unrelated, err := model.GetModelPricingSnapshot([]string{"unrelated-model"})
			require.NoError(t, err)
			assert.Equal(t, float64(0.75), unrelated.Entries[0].Configured["ModelPrice"])
			assert.NotContains(t, billing_setting.GetPricingSyncData(map[string]any{}), "plugin_billing_expr")
			assert.NotContains(t, billing_setting.GetPricingSyncData(map[string]any{})["billing_expr"], "matrix-beta::"+name)
			// Restart/re-read is idempotent; a second save based on its version succeeds.
			require.NoError(t, db.AutoMigrate(&model.Option{}))
			change.ExpectedVersion = loaded.Entries[0].Version
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
			repeated, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, loaded.Entries[0].Version, repeated.Entries[0].Version)
			// Changing only the provider price changes the model version.
			change.Pricing[billing_setting.PluginBillingExprOption] = map[string]any{"matrix-beta": `tier("free", u("credits") * 0)`}
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
			updated, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.NotEqual(t, loaded.Entries[0].Version, updated.Entries[0].Version)
			assert.ErrorIs(t, model.UpdateModelPricing([]model.ModelPricingChange{change}), model.ErrModelPricingConflict)
			// The legacy option API validates the full draft and cannot drop a required override.
			response := modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: billing_setting.PluginBillingExprOption, Value: `{}`}, nil)
			assert.Contains(t, response.Body.String(), `"success":false`)
			assert.Contains(t, response.Body.String(), "matrix-beta")
			afterFailure, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, updated.Entries[0].Version, afterFailure.Entries[0].Version)
			// Model-level legacy saves also skip providers with a stored override.
			response = modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: "billing_setting.billing_expr", Value: string(baseJSON)}, nil)
			assert.Contains(t, response.Body.String(), `"success":true`)
			flat["matrix-beta::"+name] = variant
			raw, err := common.Marshal(flat)
			require.NoError(t, err)
			response = modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: billing_setting.PluginBillingExprOption, Value: string(raw)}, nil)
			assert.Contains(t, response.Body.String(), `"success":true`)
			final, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, variant, final.Entries[0].PluginVariants[1].Effective)
			// A provider may disappear without making every legacy price save fail.
			require.NoError(t, jsplugin.DefaultRegistry.Unregister("matrix-beta"))
			stale, err := model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			require.Len(t, stale.Entries[0].PluginVariants, 2)
			assert.True(t, stale.Entries[0].PluginVariants[1].Stale)
			assert.Equal(t, variant, stale.Entries[0].PluginVariants[1].Configured)
			assert.Empty(t, stale.Entries[0].PluginVariants[1].Effective)
			_, err = model.PreviewModelPricing(name, stale.Entries[0].Configured)
			require.NoError(t, err)
			ratioJSON, err := common.Marshal(map[string]float64{name: 2})
			require.NoError(t, err)
			response = modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: "ModelRatio", Value: string(ratioJSON)}, nil)
			assert.Contains(t, response.Body.String(), `"success":true`)
			response = modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: "billing_setting.billing_expr", Value: string(baseJSON)}, nil)
			assert.Contains(t, response.Body.String(), `"success":true`)
			final, err = model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Equal(t, variant, final.Entries[0].PluginVariants[1].Configured)
			// The versioned save also preserves an unchanged stale expression.
			change = model.ModelPricingChange{ModelName: name, ExpectedVersion: final.Entries[0].Version, Pricing: final.Entries[0].Configured}
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{change}))
			change.Pricing[billing_setting.PluginBillingExprOption] = map[string]any{"matrix-beta": "1"}
			// Even if this process's cache is ahead of storage, a changed stale
			// override is validated against the locked database value.
			tamperedJSON, err := common.Marshal(map[string]string{"matrix-beta::" + name: "1"})
			require.NoError(t, err)
			require.NoError(t, config.GlobalConfig.LoadFromDB(map[string]string{billing_setting.PluginBillingExprOption: string(tamperedJSON)}))
			require.ErrorContains(t, model.UpdateModelPricing([]model.ModelPricingChange{change}), "does not declare this model")
			require.NoError(t, config.GlobalConfig.LoadFromDB(map[string]string{billing_setting.PluginBillingExprOption: final.Options[billing_setting.PluginBillingExprOption]}))
			// Updating a plugin to stop declaring this model also leaves the
			// stored override visible and inert, even with no active providers.
			_, err = jsplugin.DefaultRegistry.Register(`
export const meta = {apiVersion:1,key:"matrix-beta",name:"Beta updated",version:"2.0.0",author:{name:"Test"},models:["replacement-model"],fetchMode:"per_task",usageSchema:{credits:{type:"number",unit:"credit"}}};
export function buildSubmitRequest(){return {};}
export function parseSubmitResponse(){return {};}
export function buildQueryRequest(){return {};}
export function parseTaskResult(){return {};}
`, jsplugin.Options{})
			require.NoError(t, err)
			require.NoError(t, jsplugin.DefaultRegistry.Unregister("matrix-alpha"))
			stale, err = model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			require.Len(t, stale.Entries[0].PluginVariants, 1)
			assert.True(t, stale.Entries[0].PluginVariants[0].Stale)
			assert.Equal(t, "Beta updated", stale.Entries[0].PluginVariants[0].PluginName)
			require.NoError(t, model.UpdateModelPricingOptions(map[string]string{"ModelRatio": string(ratioJSON)}))
			// Removing just the stale override succeeds and leaves other prices.
			response = modelManagementRequest(t, UpdateOption, http.MethodPut, "/api/option/", OptionUpdateRequest{Key: billing_setting.PluginBillingExprOption, Value: `{}`}, nil)
			assert.Contains(t, response.Body.String(), `"success":true`)
			final, err = model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Empty(t, final.Entries[0].PluginVariants)
			assert.Equal(t, base, final.Entries[0].Configured["billing_setting.billing_expr"])
			// A complete reset removes all provider keys, including models containing ::.
			require.NoError(t, model.UpdateModelPricing([]model.ModelPricingChange{{ModelName: name, ExpectedVersion: final.Entries[0].Version, Reset: true}}))
			final, err = model.GetModelPricingSnapshot([]string{name})
			require.NoError(t, err)
			assert.Empty(t, final.Entries[0].Configured)
			assert.Equal(t, "{}", final.Options[billing_setting.PluginBillingExprOption])
		})
	}
}