同步前端文件更新

This commit is contained in:
2569718930@qq.com
2026-05-20 21:08:54 +08:00
parent 717ad3c6f4
commit a0005b1e37
2 changed files with 40 additions and 2 deletions
@@ -25,6 +25,16 @@ export function runTests() {
path.join(projectRoot, "app", "api", "analytics", "events", "route.ts"),
"utf8",
);
const subscriptionsPageSource = fs.readFileSync(
path.join(
projectRoot,
"components",
"ops",
"subscriptions",
"SubscriptionsPageClient.tsx",
),
"utf8",
);
assert(
accountCenterSource.includes(
@@ -66,4 +76,11 @@ export function runTests() {
accountCenterSource.includes('trackAppEvent("dashboard_active"'),
"account center must emit signup_completed and dashboard_active so the ops funnel has top-of-funnel data",
);
assert(
subscriptionsPageSource.includes("getSupabaseBrowserClient") &&
subscriptionsPageSource.includes("Authorization") &&
subscriptionsPageSource.includes("/api/ops/subscriptions/grant") &&
subscriptionsPageSource.includes("/api/ops/subscriptions/extend"),
"ops manual subscription grant/extend must send the Supabase bearer token to avoid 401 when route cookies are stale",
);
}
@@ -4,6 +4,27 @@ import { useState } from "react";
import { ScrollText, Coins, Minus } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import {
getSupabaseBrowserClient,
hasSupabasePublicEnv,
} from "@/lib/supabase/client";
async function buildOpsAuthHeaders() {
const headers: Record<string, string> = {
"Content-Type": "application/json",
};
if (!hasSupabasePublicEnv()) return headers;
try {
const {
data: { session },
} = await getSupabaseBrowserClient().auth.getSession();
const token = String(session?.access_token || "").trim();
if (token) headers.Authorization = `Bearer ${token}`;
} catch {
// Route cookies may still authenticate the request.
}
return headers;
}
export function SubscriptionsPageClient() {
const [email, setEmail] = useState("");
@@ -21,7 +42,7 @@ export function SubscriptionsPageClient() {
try {
const res = await fetch("/api/ops/subscriptions/grant", {
method: "POST",
headers: { "Content-Type": "application/json" },
headers: await buildOpsAuthHeaders(),
body: JSON.stringify({
email: email.trim(),
plan_code: planCode,
@@ -56,7 +77,7 @@ export function SubscriptionsPageClient() {
try {
const res = await fetch("/api/ops/subscriptions/extend", {
method: "POST",
headers: { "Content-Type": "application/json" },
headers: await buildOpsAuthHeaders(),
body: JSON.stringify({ email: email.trim(), additional_days: extendDays }),
});
if (res.ok) {