Expose gateway billing flows from the synced server baseline

The preserved local work adds PopiNewAPI billing checkout, gateway account binding, and matching web console/pricing surfaces on top of the current test-server baseline. During the merge, the start-end video helpers from the deployed baseline were kept alongside the actionGenerate prompt handling from the WIP.

Constraint: Current usable baseline is 7054436, already deployed on the test server.

Rejected: Commit the WIP before syncing the baseline | would have hidden conflicts with the deployed start-end-frame changes.

Confidence: medium

Scope-risk: broad

Directive: Do not deploy this commit to the test server without rechecking gateway credentials and billing checkout behavior in that environment.

Tested: go test ./...

Tested: make build

Tested: cd web && npm run build
This commit is contained in:
wtgoku
2026-05-21 16:53:07 +08:00
parent 7054436a99
commit baba209519
31 changed files with 6035 additions and 86 deletions
+40 -10
View File
@@ -23,16 +23,20 @@ func TestConfigFromEnvDefaultsVideoRouteToViduQ2(t *testing.T) {
func TestInferRouteKeyForModelRecognizesViduAsVideo(t *testing.T) {
cases := map[string]string{
"viduq2": "video.image2video",
"vidu2.0": "video.image2video",
"sora-2": "video.image2video",
"runway-gen4": "video.image2video",
"T2V-01": "video.image2video",
"I2V-01": "video.image2video",
"S2V-01": "video.image2video",
"MiniMax-Hailuo-2.3": "video.image2video",
"MiniMax-Hailuo-02": "video.image2video",
"gpt-image-1": "image.text2image",
"viduq2": "video.image2video",
"vidu2.0": "video.image2video",
"sora-2": "video.image2video",
"runway-gen4": "video.image2video",
"T2V-01": "video.image2video",
"I2V-01": "video.image2video",
"S2V-01": "video.image2video",
"MiniMax-Hailuo-2.3": "video.image2video",
"MiniMax-Hailuo-02": "video.image2video",
"doubao-seedance-2-0-260128": "video.image2video",
"seedance-2-0-fast-260128": "video.image2video",
"jimeng_dreamactor_m20_gen_video": "video.image2video",
"jimeng_i2v_first_v30": "video.image2video",
"gpt-image-1": "image.text2image",
}
for modelID, want := range cases {
@@ -56,3 +60,29 @@ func TestInferRouteKeyForModelRecognizesImageEditInputs(t *testing.T) {
}
}
}
func TestInferRouteKeyForModelRecognizesMusic(t *testing.T) {
cases := []string{
"music-2.6",
"music-2.6-free",
"music-cover",
"music-cover-free",
}
for _, modelID := range cases {
if got := inferRouteKeyForModel(modelID, nil); got != "music.generate" {
t.Fatalf("inferRouteKeyForModel(%q) = %q, want music.generate", modelID, got)
}
}
if got := inferRouteKeyForModelType("custom-model", "music", nil); got != "music.generate" {
t.Fatalf("inferRouteKeyForModelType(custom-model, music) = %q, want music.generate", got)
}
}
func TestInferRouteKeyForModelRecognizesSpeech(t *testing.T) {
if got := inferRouteKeyForModel("speech-2.8-hd", nil); got != "speech.synthesize" {
t.Fatalf("inferRouteKeyForModel(speech-2.8-hd) = %q, want speech.synthesize", got)
}
if got := inferRouteKeyForModelType("custom-model", "speech", nil); got != "speech.synthesize" {
t.Fatalf("inferRouteKeyForModelType(custom-model, speech) = %q, want speech.synthesize", got)
}
}