11import { db } from '@sim/db'
2- import * as schema from '@sim/db/schema'
2+ import {
3+ member ,
4+ organization ,
5+ session ,
6+ subscription as subscriptionTable ,
7+ user ,
8+ } from '@sim/db/schema'
39import { createLogger } from '@sim/logger'
410import { and , eq } from 'drizzle-orm'
511import { getPlanPricing } from '@/lib/billing/core/billing'
@@ -20,16 +26,16 @@ type SubscriptionData = {
2026 */
2127async function getUserOwnedOrganization ( userId : string ) : Promise < string | null > {
2228 const existingMemberships = await db
23- . select ( { organizationId : schema . member . organizationId } )
24- . from ( schema . member )
25- . where ( and ( eq ( schema . member . userId , userId ) , eq ( schema . member . role , 'owner' ) ) )
29+ . select ( { organizationId : member . organizationId } )
30+ . from ( member )
31+ . where ( and ( eq ( member . userId , userId ) , eq ( member . role , 'owner' ) ) )
2632 . limit ( 1 )
2733
2834 if ( existingMemberships . length > 0 ) {
2935 const [ existingOrg ] = await db
30- . select ( { id : schema . organization . id } )
31- . from ( schema . organization )
32- . where ( eq ( schema . organization . id , existingMemberships [ 0 ] . organizationId ) )
36+ . select ( { id : organization . id } )
37+ . from ( organization )
38+ . where ( eq ( organization . id , existingMemberships [ 0 ] . organizationId ) )
3339 . limit ( 1 )
3440
3541 return existingOrg ?. id || null
@@ -40,6 +46,8 @@ async function getUserOwnedOrganization(userId: string): Promise<string | null>
4046
4147/**
4248 * Create a new organization and add user as owner
49+ * Uses transaction to ensure org + member are created atomically
50+ * Also updates user's active sessions to set the new org as active
4351 */
4452async function createOrganizationWithOwner (
4553 userId : string ,
@@ -49,31 +57,36 @@ async function createOrganizationWithOwner(
4957) : Promise < string > {
5058 const orgId = `org_${ crypto . randomUUID ( ) } `
5159
52- const [ newOrg ] = await db
53- . insert ( schema . organization )
54- . values ( {
60+ await db . transaction ( async ( tx ) => {
61+ await tx . insert ( organization ) . values ( {
5562 id : orgId ,
5663 name : organizationName ,
5764 slug : organizationSlug ,
5865 metadata,
5966 } )
60- . returning ( { id : schema . organization . id } )
61-
62- // Add user as owner/admin of the organization
63- await db . insert ( schema . member ) . values ( {
64- id : crypto . randomUUID ( ) ,
65- userId : userId ,
66- organizationId : newOrg . id ,
67- role : 'owner' ,
67+
68+ await tx . insert ( member ) . values ( {
69+ id : crypto . randomUUID ( ) ,
70+ userId : userId ,
71+ organizationId : orgId ,
72+ role : 'owner' ,
73+ } )
6874 } )
6975
76+ const updatedSessions = await db
77+ . update ( session )
78+ . set ( { activeOrganizationId : orgId } )
79+ . where ( eq ( session . userId , userId ) )
80+ . returning ( { id : session . id } )
81+
7082 logger . info ( 'Created organization with owner' , {
7183 userId,
72- organizationId : newOrg . id ,
84+ organizationId : orgId ,
7385 organizationName,
86+ sessionsUpdated : updatedSessions . length ,
7487 } )
7588
76- return newOrg . id
89+ return orgId
7790}
7891
7992export async function createOrganizationForTeamPlan (
@@ -132,12 +145,12 @@ export async function ensureOrganizationForTeamSubscription(
132145
133146 const existingMembership = await db
134147 . select ( {
135- id : schema . member . id ,
136- organizationId : schema . member . organizationId ,
137- role : schema . member . role ,
148+ id : member . id ,
149+ organizationId : member . organizationId ,
150+ role : member . role ,
138151 } )
139- . from ( schema . member )
140- . where ( eq ( schema . member . userId , userId ) )
152+ . from ( member )
153+ . where ( eq ( member . userId , userId ) )
141154 . limit ( 1 )
142155
143156 if ( existingMembership . length > 0 ) {
@@ -149,9 +162,14 @@ export async function ensureOrganizationForTeamSubscription(
149162 } )
150163
151164 await db
152- . update ( schema . subscription )
165+ . update ( subscriptionTable )
153166 . set ( { referenceId : membership . organizationId } )
154- . where ( eq ( schema . subscription . id , subscription . id ) )
167+ . where ( eq ( subscriptionTable . id , subscription . id ) )
168+
169+ await db
170+ . update ( session )
171+ . set ( { activeOrganizationId : membership . organizationId } )
172+ . where ( eq ( session . userId , userId ) )
155173
156174 return { ...subscription , referenceId : membership . organizationId }
157175 }
@@ -165,9 +183,9 @@ export async function ensureOrganizationForTeamSubscription(
165183 }
166184
167185 const [ userData ] = await db
168- . select ( { name : schema . user . name , email : schema . user . email } )
169- . from ( schema . user )
170- . where ( eq ( schema . user . id , userId ) )
186+ . select ( { name : user . name , email : user . email } )
187+ . from ( user )
188+ . where ( eq ( user . id , userId ) )
171189 . limit ( 1 )
172190
173191 const orgId = await createOrganizationForTeamPlan (
@@ -177,9 +195,9 @@ export async function ensureOrganizationForTeamSubscription(
177195 )
178196
179197 await db
180- . update ( schema . subscription )
198+ . update ( subscriptionTable )
181199 . set ( { referenceId : orgId } )
182- . where ( eq ( schema . subscription . id , subscription . id ) )
200+ . where ( eq ( subscriptionTable . id , subscription . id ) )
183201
184202 logger . info ( 'Created organization and updated subscription referenceId' , {
185203 subscriptionId : subscription . id ,
@@ -204,9 +222,9 @@ export async function syncSubscriptionUsageLimits(subscription: SubscriptionData
204222
205223 // Check if this is a user or organization subscription
206224 const users = await db
207- . select ( { id : schema . user . id } )
208- . from ( schema . user )
209- . where ( eq ( schema . user . id , subscription . referenceId ) )
225+ . select ( { id : user . id } )
226+ . from ( user )
227+ . where ( eq ( user . id , subscription . referenceId ) )
210228 . limit ( 1 )
211229
212230 if ( users . length > 0 ) {
@@ -230,9 +248,9 @@ export async function syncSubscriptionUsageLimits(subscription: SubscriptionData
230248
231249 // Only set if not already set or if updating to a higher value based on seats
232250 const orgData = await db
233- . select ( { orgUsageLimit : schema . organization . orgUsageLimit } )
234- . from ( schema . organization )
235- . where ( eq ( schema . organization . id , organizationId ) )
251+ . select ( { orgUsageLimit : organization . orgUsageLimit } )
252+ . from ( organization )
253+ . where ( eq ( organization . id , organizationId ) )
236254 . limit ( 1 )
237255
238256 const currentLimit =
@@ -243,12 +261,12 @@ export async function syncSubscriptionUsageLimits(subscription: SubscriptionData
243261 // Update if no limit set, or if new seat-based minimum is higher
244262 if ( currentLimit < orgLimit ) {
245263 await db
246- . update ( schema . organization )
264+ . update ( organization )
247265 . set ( {
248266 orgUsageLimit : orgLimit . toFixed ( 2 ) ,
249267 updatedAt : new Date ( ) ,
250268 } )
251- . where ( eq ( schema . organization . id , organizationId ) )
269+ . where ( eq ( organization . id , organizationId ) )
252270
253271 logger . info ( 'Set organization usage limit for team plan' , {
254272 organizationId,
@@ -262,9 +280,9 @@ export async function syncSubscriptionUsageLimits(subscription: SubscriptionData
262280
263281 // Sync usage limits for all members
264282 const members = await db
265- . select ( { userId : schema . member . userId } )
266- . from ( schema . member )
267- . where ( eq ( schema . member . organizationId , organizationId ) )
283+ . select ( { userId : member . userId } )
284+ . from ( member )
285+ . where ( eq ( member . organizationId , organizationId ) )
268286
269287 if ( members . length > 0 ) {
270288 for ( const member of members ) {
0 commit comments