11import { db } from '@sim/db'
2- import { member , user , type WorkspaceMode , workspace } from '@sim/db/schema'
2+ import { member , type WorkspaceMode , workspace } from '@sim/db/schema'
33import { createLogger } from '@sim/logger'
44import { and , count , eq , isNull } from 'drizzle-orm'
5+ import { isPlatformAdmin } from '@/lib/auth/platform-admin'
56import { getOrganizationSubscription } from '@/lib/billing/core/billing'
67import { getHighestPrioritySubscription } from '@/lib/billing/core/plan'
78import { getUserOrganization } from '@/lib/billing/organizations/membership'
@@ -84,12 +85,22 @@ export function isOrganizationWorkspace(
8485export async function getWorkspaceInvitePolicy (
8586 workspaceState : WorkspaceOwnershipState
8687) : Promise < WorkspaceInvitePolicy > {
87- const requiresSubscriptionLookup =
88- isBillingEnabled && workspaceState . workspaceMode === WORKSPACE_MODE . GRANDFATHERED_SHARED
89- const billedUserHasTeamOrEnterprise = requiresSubscriptionLookup
90- ? await hasActiveTeamOrEnterpriseSubscription ( workspaceState . billedAccountUserId )
91- : false
92- return evaluateWorkspaceInvitePolicy ( workspaceState , { billedUserHasTeamOrEnterprise } )
88+ if ( ! isBillingEnabled ) {
89+ return evaluateWorkspaceInvitePolicy ( workspaceState , {
90+ billedUserHasTeamOrEnterprise : false ,
91+ billedUserIsPlatformAdmin : false ,
92+ } )
93+ }
94+ const [ billedUserHasTeamOrEnterprise , billedUserIsPlatformAdmin ] = await Promise . all ( [
95+ workspaceState . workspaceMode === WORKSPACE_MODE . GRANDFATHERED_SHARED
96+ ? hasActiveTeamOrEnterpriseSubscription ( workspaceState . billedAccountUserId )
97+ : Promise . resolve ( false ) ,
98+ isPlatformAdmin ( workspaceState . billedAccountUserId ) ,
99+ ] )
100+ return evaluateWorkspaceInvitePolicy ( workspaceState , {
101+ billedUserHasTeamOrEnterprise,
102+ billedUserIsPlatformAdmin,
103+ } )
93104}
94105
95106/**
@@ -100,7 +111,7 @@ export async function getWorkspaceInvitePolicy(
100111 */
101112export function evaluateWorkspaceInvitePolicy (
102113 workspaceState : WorkspaceOwnershipState ,
103- context : { billedUserHasTeamOrEnterprise : boolean }
114+ context : { billedUserHasTeamOrEnterprise : boolean ; billedUserIsPlatformAdmin : boolean }
104115) : WorkspaceInvitePolicy {
105116 if ( ! isBillingEnabled ) {
106117 return {
@@ -112,6 +123,16 @@ export function evaluateWorkspaceInvitePolicy(
112123 }
113124 }
114125
126+ if ( context . billedUserIsPlatformAdmin ) {
127+ return {
128+ allowed : true ,
129+ reason : null ,
130+ requiresSeat : workspaceState . workspaceMode === WORKSPACE_MODE . ORGANIZATION ,
131+ organizationId : workspaceState . organizationId ,
132+ upgradeRequired : false ,
133+ }
134+ }
135+
115136 if ( workspaceState . workspaceMode === WORKSPACE_MODE . ORGANIZATION ) {
116137 if ( workspaceState . organizationId === null ) {
117138 return {
@@ -357,12 +378,6 @@ export async function getOrganizationOwnerId(organizationId: string): Promise<st
357378 return ownerMembership ?. userId ?? null
358379}
359380
360- async function isPlatformAdmin ( userId : string ) : Promise < boolean > {
361- const [ row ] = await db . select ( { role : user . role } ) . from ( user ) . where ( eq ( user . id , userId ) ) . limit ( 1 )
362-
363- return row ?. role === 'admin'
364- }
365-
366381/**
367382 * Like `getOrganizationOwnerId` but throws when no owner row exists.
368383 * Use when the caller needs a guaranteed billed-account userId — every
0 commit comments