import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; const source = (path: string) => readFileSync(new URL(`../${path}`, import.meta.url), "utf8"); const packagesRoute = source("src/app/api/payment/packages/route.ts"); const createRoute = source("src/app/api/payment/epay/create/route.ts"); const statusRoute = source("src/app/api/payment/epay/status/route.ts"); const notifyRoute = source("src/app/api/payment/epay/notify/route.ts"); const productsRoute = source("src/app/api/admin/products/route.ts"); const epaySettingsRoute = source("src/app/api/admin/epay-settings/route.ts"); const subscriptionsRoute = source("src/app/api/admin/subscriptions/route.ts"); const featureFlagsRoute = source("src/app/api/admin/feature-flags/route.ts"); const modelsRoute = source("src/app/api/admin/models/route.ts"); const modelDiscoveryRoute = source("src/app/api/admin/models/discover/route.ts"); const modelMutationHandler = source("src/lib/admin/model-mutation-handler.ts"); const ordersRoute = source("src/app/api/admin/orders/route.ts"); const codesRoute = source("src/app/api/admin/codes/route.ts"); const codeRoute = source("src/app/api/admin/codes/[id]/route.ts"); const codesHelper = source("src/lib/admin/codes.ts"); const billingOperationsUi = source("src/components/admin/billing-operations-resources.tsx"); const codesUi = source("src/components/admin/codes-resource.tsx"); const redemptionAccessMigration = source("supabase/migrations/20260816010000_admin_redemption_admin_access.sql"); const baseRedemptionMigration = source("supabase/migrations/20260805010000_reconcile_admin_redemption_audit.sql"); test("billing.subscriptions only gates new trial and subscription purchases", () => { assert.match(packagesRoute, /loadRuntimeFeatureFlags\(\["billing\.subscriptions"\]\)/); assert.match(packagesRoute, /subscriptionsEnabled \|\| product\.product_type === "credit_pack"/); assert.match(createRoute, /product\.product_type !== "credit_pack"[\s\S]*billing\.subscriptions[\s\S]*BILLING_SUBSCRIPTIONS_DISABLED/); assert.ok( createRoute.indexOf("BILLING_SUBSCRIPTIONS_DISABLED") < createRoute.indexOf('.from("payment_orders").insert'), "the flag must reject subscription orders before insertion", ); }); test("existing payment orders remain queryable and settleable when subscriptions are disabled", () => { assert.doesNotMatch(statusRoute, /billing\.subscriptions|loadRuntimeFeatureFlags/); assert.doesNotMatch(notifyRoute, /billing\.subscriptions|loadRuntimeFeatureFlags/); assert.match(statusRoute, /from\("payment_orders"\)/); assert.match(notifyRoute, /createEpayNotifyHandler[\s\S]*settle_order/); }); test("billing and operations writes use the shared ordinary mutation guard", () => { assert.match(productsRoute, /requireAdminMutation\(request, permission\)/); assert.match(productsRoute, /admin_console_(?:save|publish|delete)_product/); assert.match(productsRoute, /admin_delete_product/); const productMutationMigration = source("supabase/migrations/20260818010000_admin_product_catalog_mutations.sql"); assert.match(productMutationMigration, /jsonb_build_object\('productCode'/); assert.doesNotMatch(productMutationMigration, /jsonb_build_object\('code'/); assert.match(epaySettingsRoute, /requireAdminMutation\(request, "billing\.adjustments\.write"\)/); assert.match(epaySettingsRoute, /admin_save_epay_settings/); assert.match(subscriptionsRoute, /requireAdminMutation\(request,"billing\.adjustments\.write"\)/); assert.match(subscriptionsRoute, /admin_console_adjust_subscription/); assert.match(featureFlagsRoute, /requireAdminMutation\(request,"ops\.flags\.write"\)/); assert.match(featureFlagsRoute, /admin_console_publish_feature_flag/); for (const route of [productsRoute, epaySettingsRoute, subscriptionsRoute, featureFlagsRoute]) { assert.doesNotMatch(route, /requireHighRiskAdminMutation/); } }); test("model provider changes and release mutations use the ordinary admin guard", () => { assert.match(modelsRoute, /await requireAdminMutation\(request, permission\)/); assert.doesNotMatch(modelsRoute, /requireHighRiskAdminMutation/); assert.match(modelDiscoveryRoute, /requireAdminMutation\(request,"models\.test"\)/); assert.doesNotMatch(modelDiscoveryRoute, /requireHighRiskAdminMutation/); assert.match(modelsRoute, /handleAdminModelMutation\(/); assert.match(modelMutationHandler, /admin_save_model_provider/); assert.match(modelMutationHandler, /admin_publish_model/); assert.match(modelMutationHandler, /probeAndRecord[\s\S]*admin_rollback_model/); }); test("self-hosted payment catalog uses simple queries and immutable product snapshots", () => { assert.doesNotMatch(packagesRoute, /product_entitlements\s*\(/); assert.doesNotMatch(createRoute, /product_entitlements\s*\(/); assert.match(packagesRoute, /\.from\("billing_products"\)[\s\S]*\.from\("product_entitlements"\)/); assert.match(packagesRoute, /entitlementsByProduct/); assert.match(createRoute, /\.from\("billing_products"\)[\s\S]*\.from\("product_entitlements"\)/); assert.match(createRoute, /oneTimePerUser:\s*product\.one_time_per_user/); assert.match(createRoute, /product_snapshot:\s*productSnapshot/); }); test("order adjustments require permission, version, server audit reason, request id, and the domain RPC", () => { assert.match( ordersRoute, /requireAdminMutation\(\s*request,\s*"billing\.adjustments\.write",?\s*\)/, ); assert.match(ordersRoute, /expectedVersion:\s*z\.number\(\)\.int\(\)\.min\(0\)/); assert.doesNotMatch(ordersRoute, /reason:\s*z\.string/); assert.match(ordersRoute, /admin_console_adjust_order/); assert.match(ordersRoute, /queryAdminRows/); assert.match(ordersRoute, /public\.admin_adjust_order\(/); assert.match(ordersRoute, /requestId\(request\)/); assert.doesNotMatch(ordersRoute, /createAdminSupabaseClient|\.rpc\(/); assert.match(billingOperationsUi, /retry_grant/); assert.match(billingOperationsUi, /compensate/); assert.match(billingOperationsUi, /record_refund/); assert.doesNotMatch(billingOperationsUi, /reauthPermission|邮箱验证码|\/api\/admin\/reauth/); assert.match(billingOperationsUi, /不调用支付网关|仅记录账务/); }); test("redemption-code writes generate server audit reasons and encode JSONB for self-hosted pg", () => { assert.match(codesRoute, /await requirePermission\("admin\.access"\)/); assert.match(codesRoute, /requireAdminMutation\(\s*request,\s*"admin\.access",?\s*\)/); assert.equal((codeRoute.match(/requireAdminMutation\(/g) ?? []).length, 2); assert.doesNotMatch(codeRoute, /requireHighRiskAdminMutation/); assert.doesNotMatch(codesRoute, /reason:\s*z\.string/); assert.doesNotMatch(codeRoute, /reason:\s*z\.string/); assert.match(codesRoute, /p_reason:\s*"admin_console_create_redemption_codes"/); assert.match(codeRoute, /p_reason:\s*"admin_console_update_redemption_code"/); assert.match(codeRoute, /p_reason:\s*"admin_console_revoke_redemption_code"/); assert.match(codesHelper, /JSON\.stringify\(input\.p_codes\)/); assert.match(codesHelper, /session\.user\.email,[\s\S]*"admin",/); assert.doesNotMatch(codesHelper, /session\.roles\[0\]/); assert.match(codesHelper, /queryAdminRows/); assert.match(codesHelper, /public\.admin_create_redemption_codes\(/); assert.match(codesHelper, /public\.admin_update_redemption_code\(/); assert.match(codesHelper, /public\.admin_revoke_redemption_code\(/); assert.doesNotMatch(codesHelper, /createAdminSupabaseClient|\.rpc\(|\$\{functionName\}/); assert.match(codesUi, /permissions\.includes\("admin\.access"\)/); assert.doesNotMatch(codesUi, /reauthPermission|邮箱验证码|\/api\/admin\/reauth/); assert.match(codesUi, /onFinish=\{\(values\) => void submitCreate\(values\)\}/); assert.match(codesUi, /onFinish=\{\(values\) => void submitEdit\(values\)\}/); assert.match(codesUi, /onClick=\{\(\) => void revoke\(record\)\}/); assert.doesNotMatch(codesUi, /ConfirmActionModal|pendingCreate|pendingEdit|revokeRecord/); assert.match(codesUi, /copyable=\{\{ text: record\.code \?\? "" \}\}/); assert.equal((redemptionAccessMigration.match(/admin_has_permission\(p_actor_user_id,'admin\.access'\)/g) ?? []).length, 3); assert.match(redemptionAccessMigration, /new\.permission_used := 'admin\.access'/); assert.match(baseRedemptionMigration, /admin_verified_actor_email/); assert.match(redemptionAccessMigration, /grant execute on function public\.admin_create_redemption_codes/); assert.doesNotMatch(redemptionAccessMigration, /billing\.adjustments\.write/); });