refactor: remove unused Stripe dependency and update credit expiration logic

This commit is contained in:
javayhu 2025-07-12 23:41:50 +08:00
parent 8a08dfdf3b
commit 31116cbf8b
7 changed files with 21 additions and 39 deletions

View File

@ -11,9 +11,9 @@
"language": "切换语言",
"mode": {
"label": "切换模式",
"light": "浅色",
"dark": "深色",
"system": "系统"
"light": "浅色模式",
"dark": "深色模式",
"system": "跟随系统"
},
"theme": {
"label": "切换主题",

View File

@ -4,7 +4,6 @@
"private": true,
"scripts": {
"dev": "next dev",
"dev-https": "next dev --experimental-https",
"build": "next build",
"start": "next start",
"postinstall": "fumadocs-mdx",
@ -73,7 +72,6 @@
"@radix-ui/react-tooltip": "^1.1.8",
"@react-email/components": "0.0.33",
"@react-email/render": "1.0.5",
"@stripe/react-stripe-js": "^3.7.0",
"@stripe/stripe-js": "^5.6.0",
"@tabler/icons-react": "^3.31.0",
"@tanstack/react-table": "^8.21.2",

17
pnpm-lock.yaml generated
View File

@ -152,9 +152,6 @@ importers:
'@react-email/render':
specifier: 1.0.5
version: 1.0.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@stripe/react-stripe-js':
specifier: ^3.7.0
version: 3.7.0(@stripe/stripe-js@5.6.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@stripe/stripe-js':
specifier: ^5.6.0
version: 5.6.0
@ -3854,13 +3851,6 @@ packages:
'@standard-schema/spec@1.0.0':
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
'@stripe/react-stripe-js@3.7.0':
resolution: {integrity: sha512-PYls/2S9l0FF+2n0wHaEJsEU8x7CmBagiH7zYOsxbBlLIHEsqUIQ4MlIAbV9Zg6xwT8jlYdlRIyBTHmO3yM7kQ==}
peerDependencies:
'@stripe/stripe-js': '>=1.44.1 <8.0.0'
react: '>=16.8.0 <20.0.0'
react-dom: '>=16.8.0 <20.0.0'
'@stripe/stripe-js@5.6.0':
resolution: {integrity: sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw==}
engines: {node: '>=12.16'}
@ -10003,13 +9993,6 @@ snapshots:
'@standard-schema/spec@1.0.0': {}
'@stripe/react-stripe-js@3.7.0(@stripe/stripe-js@5.6.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@stripe/stripe-js': 5.6.0
prop-types: 15.8.1
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
'@stripe/stripe-js@5.6.0': {}
'@swc/counter@0.1.3': {}

View File

@ -8,8 +8,8 @@ import { addDays } from 'date-fns';
import { and, eq, gte, isNotNull, lte, sql, sum } from 'drizzle-orm';
import { createSafeActionClient } from 'next-safe-action';
const CREDITS_EXPIRATION_DAYS = 30;
const CREDITS_MONTHLY_DAYS = 30;
const CREDITS_EXPIRATION_DAYS = 31;
const CREDITS_MONTHLY_DAYS = 31;
// Create a safe action client
const actionClient = createSafeActionClient();
@ -21,6 +21,7 @@ export const getCreditStatsAction = actionClient.action(async () => {
try {
const session = await getSession();
if (!session) {
console.warn('unauthorized request to get credit stats');
return {
success: false,
error: 'Unauthorized',
@ -30,8 +31,8 @@ export const getCreditStatsAction = actionClient.action(async () => {
const db = await getDb();
const userId = session.user.id;
// Get credits expiring in the next 30 days
const thirtyDaysFromNow = addDays(new Date(), CREDITS_EXPIRATION_DAYS);
// Get credits expiring in the next CREDITS_EXPIRATION_DAYS days
const expirationDaysFromNow = addDays(new Date(), CREDITS_EXPIRATION_DAYS);
const expiringCredits = await db
.select({
amount: sum(creditTransaction.remainingAmount),
@ -44,13 +45,13 @@ export const getCreditStatsAction = actionClient.action(async () => {
isNotNull(creditTransaction.expirationDate),
isNotNull(creditTransaction.remainingAmount),
gte(creditTransaction.remainingAmount, 1),
lte(creditTransaction.expirationDate, thirtyDaysFromNow),
lte(creditTransaction.expirationDate, expirationDaysFromNow),
gte(creditTransaction.expirationDate, new Date())
)
);
// Get credits from subscription renewals (recent 30 days)
const thirtyDaysAgo = addDays(new Date(), -CREDITS_MONTHLY_DAYS);
// Get credits from subscription renewals (recent CREDITS_MONTHLY_DAYS days)
const monthlyRefreshDaysAgo = addDays(new Date(), -CREDITS_MONTHLY_DAYS);
const subscriptionCredits = await db
.select({
amount: sum(creditTransaction.amount),
@ -63,11 +64,11 @@ export const getCreditStatsAction = actionClient.action(async () => {
creditTransaction.type,
CREDIT_TRANSACTION_TYPE.SUBSCRIPTION_RENEWAL
),
gte(creditTransaction.createdAt, thirtyDaysAgo)
gte(creditTransaction.createdAt, monthlyRefreshDaysAgo)
)
);
// Get credits from monthly lifetime distribution (recent 30 days)
// Get credits from monthly lifetime distribution (recent CREDITS_MONTHLY_DAYS days)
const lifetimeCredits = await db
.select({
amount: sum(creditTransaction.amount),
@ -77,7 +78,7 @@ export const getCreditStatsAction = actionClient.action(async () => {
and(
eq(creditTransaction.userId, userId),
eq(creditTransaction.type, CREDIT_TRANSACTION_TYPE.LIFETIME_MONTHLY),
gte(creditTransaction.createdAt, thirtyDaysAgo)
gte(creditTransaction.createdAt, monthlyRefreshDaysAgo)
)
);

View File

@ -23,7 +23,7 @@ import {
} from 'lucide-react';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
import { CREDIT_TRANSACTION_TYPE } from './types';
import { CREDIT_TRANSACTION_TYPE } from '../../../credits/types';
// Define the credit transaction interface (matching the one in the table)
export interface CreditTransaction {

View File

@ -1,5 +1,6 @@
'use client';
import { CreditDetailViewer } from '@/components/settings/credits/credit-detail-viewer';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
@ -31,7 +32,6 @@ import {
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { CreditDetailViewer } from '@/credits/credit-detail-viewer';
import { CREDIT_TRANSACTION_TYPE } from '@/credits/types';
import { formatDate } from '@/lib/formatter';
import { CaretDownIcon, CaretUpIcon } from '@radix-ui/react-icons';

View File

@ -118,18 +118,18 @@ export async function addCredits({
}) {
if (!userId || !type || !description) {
console.error('addCredits, invalid params', userId, type, description);
throw new Error('addCredits, invalid params');
throw new Error('Invalid params');
}
if (!Number.isFinite(amount) || amount <= 0) {
console.error('addCredits, invalid amount', userId, amount);
throw new Error('addCredits, invalid amount');
throw new Error('Invalid amount');
}
if (
expireDays !== undefined &&
(!Number.isFinite(expireDays) || expireDays <= 0)
) {
console.error('addCredits, invalid expire days', userId, expireDays);
throw new Error('addCredits, invalid expire days');
throw new Error('Invalid expire days');
}
// Process expired credits first
await processExpiredCredits(userId);
@ -201,11 +201,11 @@ export async function consumeCredits({
}) {
if (!userId || !description) {
console.error('consumeCredits, invalid params', userId, description);
throw new Error('consumeCredits, invalid params');
throw new Error('Invalid params');
}
if (!Number.isFinite(amount) || amount <= 0) {
console.error('consumeCredits, invalid amount', userId, amount);
throw new Error('consumeCredits, invalid amount');
throw new Error('Invalid amount');
}
// Process expired credits first
await processExpiredCredits(userId);