@@ -15,7 +15,7 @@ import {
1515 userStats ,
1616} from '@sim/db/schema'
1717import { createLogger } from '@sim/logger'
18- import { and , eq , inArray , sql } from 'drizzle-orm'
18+ import { and , eq , inArray , isNull , ne , or , sql } from 'drizzle-orm'
1919import { syncUsageLimitsFromSubscription } from '@/lib/billing/core/usage'
2020import { requireStripeClient } from '@/lib/billing/stripe-client'
2121import { validateSeatAvailability } from '@/lib/billing/validation/seat-management'
@@ -38,6 +38,10 @@ export async function getOrgMemberIds(organizationId: string): Promise<string[]>
3838
3939/**
4040 * Block all members of an organization for billing reasons
41+ * Returns the number of members actually blocked
42+ *
43+ * Reason priority: dispute > payment_failed
44+ * A payment_failed block won't overwrite an existing dispute block
4145 */
4246export async function blockOrgMembers (
4347 organizationId : string ,
@@ -49,17 +53,28 @@ export async function blockOrgMembers(
4953 return 0
5054 }
5155
52- await db
56+ // Don't overwrite dispute blocks with payment_failed (dispute is higher priority)
57+ const whereClause =
58+ reason === 'payment_failed'
59+ ? and (
60+ inArray ( userStats . userId , memberIds ) ,
61+ or ( ne ( userStats . billingBlockedReason , 'dispute' ) , isNull ( userStats . billingBlockedReason ) )
62+ )
63+ : inArray ( userStats . userId , memberIds )
64+
65+ const result = await db
5366 . update ( userStats )
5467 . set ( { billingBlocked : true , billingBlockedReason : reason } )
55- . where ( inArray ( userStats . userId , memberIds ) )
68+ . where ( whereClause )
69+ . returning ( { userId : userStats . userId } )
5670
57- return memberIds . length
71+ return result . length
5872}
5973
6074/**
6175 * Unblock all members of an organization blocked for a specific reason
6276 * Only unblocks members blocked for the specified reason (not other reasons)
77+ * Returns the number of members actually unblocked
6378 */
6479export async function unblockOrgMembers (
6580 organizationId : string ,
@@ -71,12 +86,13 @@ export async function unblockOrgMembers(
7186 return 0
7287 }
7388
74- await db
89+ const result = await db
7590 . update ( userStats )
7691 . set ( { billingBlocked : false , billingBlockedReason : null } )
7792 . where ( and ( inArray ( userStats . userId , memberIds ) , eq ( userStats . billingBlockedReason , reason ) ) )
93+ . returning ( { userId : userStats . userId } )
7894
79- return memberIds . length
95+ return result . length
8096}
8197
8298export interface RestoreProResult {
0 commit comments