11import { AuditAction , AuditResourceType , recordAudit } from '@sim/audit'
22import { db } from '@sim/db'
3- import { permissions , type permissionTypeEnum , user , workspace } from '@sim/db/schema'
3+ import {
4+ type InvitationMembershipIntent ,
5+ permissions ,
6+ type permissionTypeEnum ,
7+ user ,
8+ workspace ,
9+ } from '@sim/db/schema'
410import { createLogger } from '@sim/logger'
511import { and , eq , isNull , sql } from 'drizzle-orm'
612import { type NextRequest , NextResponse } from 'next/server'
@@ -123,6 +129,8 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
123129 )
124130 }
125131
132+ let membershipIntent : InvitationMembershipIntent = 'internal'
133+
126134 const existingUser = await db
127135 . select ( )
128136 . from ( user )
@@ -152,23 +160,14 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
152160 )
153161 }
154162
155- if ( invitePolicy . requiresSeat && invitePolicy . organizationId ) {
163+ if ( invitePolicy . organizationId ) {
156164 const existingMembership = await getUserOrganization ( existingUser . id )
157165 if (
158166 existingMembership &&
159167 existingMembership . organizationId !== invitePolicy . organizationId
160168 ) {
161- return NextResponse . json (
162- {
163- error :
164- 'This user is already a member of another organization. They must leave it before joining this workspace.' ,
165- email : normalizedEmail ,
166- } ,
167- { status : 409 }
168- )
169- }
170-
171- if ( ! existingMembership ) {
169+ membershipIntent = 'external'
170+ } else if ( invitePolicy . requiresSeat && ! existingMembership ) {
172171 const seatValidation = await validateSeatAvailability ( invitePolicy . organizationId , 1 )
173172 if ( ! seatValidation . canInvite ) {
174173 return NextResponse . json (
@@ -213,6 +212,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
213212 email : normalizedEmail ,
214213 inviterId : session . user . id ,
215214 organizationId : workspaceDetails . organizationId ,
215+ membershipIntent,
216216 role : 'member' ,
217217 grants : [
218218 {
@@ -228,6 +228,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
228228 invitedBy : session . user . id ,
229229 inviteeEmail : normalizedEmail ,
230230 role : permission ,
231+ membershipIntent,
231232 } )
232233 } catch {
233234 // telemetry must not fail the operation
@@ -236,7 +237,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
236237 captureServerEvent (
237238 session . user . id ,
238239 'workspace_member_invited' ,
239- { workspace_id : workspaceId , invitee_role : permission } ,
240+ { workspace_id : workspaceId , invitee_role : permission , membership_intent : membershipIntent } ,
240241 {
241242 groups : { workspace : workspaceId } ,
242243 setOnce : { first_invitation_sent_at : new Date ( ) . toISOString ( ) } ,
@@ -275,6 +276,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
275276 metadata : {
276277 targetEmail : normalizedEmail ,
277278 targetRole : permission ,
279+ membershipIntent,
278280 workspaceName : workspaceDetails . name ,
279281 invitationId,
280282 } ,
@@ -288,6 +290,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
288290 workspaceId,
289291 email : normalizedEmail ,
290292 permission,
293+ membershipIntent,
291294 expiresAt : undefined ,
292295 } ,
293296 } )
0 commit comments