feat(payment): accept support character guidance scene
Docker Image / Build and Push Docker Image (push) Successful in 2m10s

This commit is contained in:
Codex
2026-07-28 12:09:33 +08:00
parent 995fdbda57
commit 38ae06fe04
4 changed files with 27 additions and 3 deletions
@@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from "react";
import { ArrowRight, CircleDollarSign, X } from "lucide-react";
import type { PaymentGuidance } from "@/data/schemas/chat";
import type { PaymentAnalyticsTriggerReason } from "@/lib/analytics/payment_analytics_context";
import { recordChatActionEventById } from "@/lib/chat/chat_action_events";
import { useActiveCharacter } from "@/providers/character-provider";
import { useAppNavigator } from "@/router/use-app-navigator";
@@ -15,6 +16,18 @@ export interface PaymentGuidanceCardProps {
guidance: PaymentGuidance;
}
function triggerReasonForGuidance(
scene: PaymentGuidance["scene"],
): PaymentAnalyticsTriggerReason {
if (scene === "supportCharacter" || scene === "vip" || scene === "purchaseOptions") {
return "vip_cta";
}
if (scene === "privateMessageLocked" || scene === "historyLocked") {
return "private_topic_limit";
}
return "insufficient_credits";
}
export function PaymentGuidanceCard({ guidance }: PaymentGuidanceCardProps) {
const character = useActiveCharacter();
const navigator = useAppNavigator();
@@ -91,7 +104,7 @@ export function PaymentGuidanceCard({ guidance }: PaymentGuidanceCardProps) {
chatActionId: guidance.guidanceId,
analytics: {
entryPoint: "chat_input",
triggerReason: "insufficient_credits",
triggerReason: triggerReasonForGuidance(guidance.scene),
},
});
}}
@@ -27,6 +27,16 @@ describe("payment guidance wire contract", () => {
expect(PaymentGuidanceSchema.parse(guidance)).toEqual(guidance);
});
it("accepts the supportCharacter guidance scene", () => {
expect(
PaymentGuidanceSchema.parse({
...guidance,
scene: "supportCharacter",
ruleId: "payment_guidance_supportCharacter",
}).scene,
).toBe("supportCharacter");
});
it("keeps all backend lock facts instead of dropping hint and CTA", () => {
expect(
ChatLockDetailSchema.parse({
@@ -24,6 +24,7 @@ export const PaymentGuidanceSceneSchema = z.enum([
"privateZoneLocked",
"unknownLock",
"whyPay",
"supportCharacter",
"leavingAfterCredits",
"paymentIssue",
"externalRisk",
@@ -116,7 +116,7 @@ describe("sendResponseToUiMessage", () => {
copy: "Buy me a coffee?",
ctaLabel: "View gifts",
target: "giftCatalog",
ruleId: "coffee_support_question",
ruleId: "coffee_after_thanks",
},
}),
);
@@ -127,7 +127,7 @@ describe("sendResponseToUiMessage", () => {
copy: "Buy me a coffee?",
ctaLabel: "View gifts",
target: "giftCatalog",
ruleId: "coffee_support_question",
ruleId: "coffee_after_thanks",
});
});