|
1 | 1 | import { db } from '@sim/db' |
2 | | -import { member, userStats } from '@sim/db/schema' |
| 2 | +import { member } from '@sim/db/schema' |
3 | 3 | import { createLogger } from '@sim/logger' |
4 | 4 | import { and, eq } from 'drizzle-orm' |
5 | 5 | import { type NextRequest, NextResponse } from 'next/server' |
6 | 6 | import { getSession } from '@/lib/auth' |
| 7 | +import { getEffectiveBillingStatus } from '@/lib/billing/core/access' |
7 | 8 | import { getSimplifiedBillingSummary } from '@/lib/billing/core/billing' |
8 | 9 | import { getOrganizationBillingData } from '@/lib/billing/core/organization' |
9 | 10 | import { dollarsToCredits } from '@/lib/billing/credits/conversion' |
10 | 11 | import { getPlanTierCredits } from '@/lib/billing/plan-helpers' |
11 | 12 |
|
12 | | -/** |
13 | | - * Gets the effective billing blocked status for a user. |
14 | | - * If user is in an org, also checks if the org owner is blocked. |
15 | | - */ |
16 | | -async function getEffectiveBillingStatus(userId: string): Promise<{ |
17 | | - billingBlocked: boolean |
18 | | - billingBlockedReason: 'payment_failed' | 'dispute' | null |
19 | | - blockedByOrgOwner: boolean |
20 | | -}> { |
21 | | - // Check user's own status |
22 | | - const userStatsRows = await db |
23 | | - .select({ |
24 | | - blocked: userStats.billingBlocked, |
25 | | - blockedReason: userStats.billingBlockedReason, |
26 | | - }) |
27 | | - .from(userStats) |
28 | | - .where(eq(userStats.userId, userId)) |
29 | | - .limit(1) |
30 | | - |
31 | | - const userBlocked = userStatsRows.length > 0 ? !!userStatsRows[0].blocked : false |
32 | | - const userBlockedReason = userStatsRows.length > 0 ? userStatsRows[0].blockedReason : null |
33 | | - |
34 | | - if (userBlocked) { |
35 | | - return { |
36 | | - billingBlocked: true, |
37 | | - billingBlockedReason: userBlockedReason, |
38 | | - blockedByOrgOwner: false, |
39 | | - } |
40 | | - } |
41 | | - |
42 | | - // Check if user is in an org where owner is blocked |
43 | | - const memberships = await db |
44 | | - .select({ organizationId: member.organizationId }) |
45 | | - .from(member) |
46 | | - .where(eq(member.userId, userId)) |
47 | | - |
48 | | - // Fetch all org owners in parallel |
49 | | - const ownerResults = await Promise.all( |
50 | | - memberships.map((m) => |
51 | | - db |
52 | | - .select({ userId: member.userId }) |
53 | | - .from(member) |
54 | | - .where(and(eq(member.organizationId, m.organizationId), eq(member.role, 'owner'))) |
55 | | - .limit(1) |
56 | | - ) |
57 | | - ) |
58 | | - |
59 | | - // Collect owner IDs that are not the current user |
60 | | - const otherOwnerIds = ownerResults |
61 | | - .filter((owners) => owners.length > 0 && owners[0].userId !== userId) |
62 | | - .map((owners) => owners[0].userId) |
63 | | - |
64 | | - if (otherOwnerIds.length > 0) { |
65 | | - // Fetch all owner stats in parallel |
66 | | - const ownerStatsResults = await Promise.all( |
67 | | - otherOwnerIds.map((ownerId) => |
68 | | - db |
69 | | - .select({ |
70 | | - blocked: userStats.billingBlocked, |
71 | | - blockedReason: userStats.billingBlockedReason, |
72 | | - }) |
73 | | - .from(userStats) |
74 | | - .where(eq(userStats.userId, ownerId)) |
75 | | - .limit(1) |
76 | | - ) |
77 | | - ) |
78 | | - |
79 | | - for (const stats of ownerStatsResults) { |
80 | | - if (stats.length > 0 && stats[0].blocked) { |
81 | | - return { |
82 | | - billingBlocked: true, |
83 | | - billingBlockedReason: stats[0].blockedReason, |
84 | | - blockedByOrgOwner: true, |
85 | | - } |
86 | | - } |
87 | | - } |
88 | | - } |
89 | | - |
90 | | - return { |
91 | | - billingBlocked: false, |
92 | | - billingBlockedReason: null, |
93 | | - blockedByOrgOwner: false, |
94 | | - } |
95 | | -} |
96 | | - |
97 | 13 | const logger = createLogger('UnifiedBillingAPI') |
98 | 14 |
|
99 | 15 | /** |
|
0 commit comments