| 363 | } |
| 364 | |
| 365 | export async function create(input: { inviterWorkspaceID: string; inviteeWorkspaceID: string }) { |
| 366 | return Database.transaction(async (tx) => { |
| 367 | if (input.inviterWorkspaceID === input.inviteeWorkspaceID) throw new Error("Self-referral workspace mismatch") |
| 368 | |
| 369 | const inviterWorkspace = await tx |
| 370 | .select({ id: WorkspaceTable.id }) |
| 371 | .from(WorkspaceTable) |
| 372 | .where(and(eq(WorkspaceTable.id, input.inviterWorkspaceID), isNull(WorkspaceTable.timeDeleted))) |
| 373 | .then((rows) => rows[0]) |
| 374 | if (!inviterWorkspace) throw new Error(`Inviter workspace not found: ${input.inviterWorkspaceID}`) |
| 375 | |
| 376 | const inviteeWorkspace = await tx |
| 377 | .select({ id: WorkspaceTable.id }) |
| 378 | .from(WorkspaceTable) |
| 379 | .where(and(eq(WorkspaceTable.id, input.inviteeWorkspaceID), isNull(WorkspaceTable.timeDeleted))) |
| 380 | .then((rows) => rows[0]) |
| 381 | if (!inviteeWorkspace) throw new Error(`Invitee workspace not found: ${input.inviteeWorkspaceID}`) |
| 382 | |
| 383 | const invitee = await tx |
| 384 | .select({ accountID: UserTable.accountID, userID: UserTable.id, liteID: LiteTable.id }) |
| 385 | .from(UserTable) |
| 386 | .innerJoin( |
| 387 | LiteTable, |
| 388 | and( |
| 389 | eq(LiteTable.workspaceID, UserTable.workspaceID), |
| 390 | eq(LiteTable.userID, UserTable.id), |
| 391 | isNull(LiteTable.timeDeleted), |
| 392 | ), |
| 393 | ) |
| 394 | .where( |
| 395 | and( |
| 396 | eq(UserTable.workspaceID, input.inviteeWorkspaceID), |
| 397 | eq(UserTable.role, "admin"), |
| 398 | isNull(UserTable.timeDeleted), |
| 399 | ), |
| 400 | ) |
| 401 | .then((rows) => rows[0]) |
| 402 | if (!invitee?.accountID) throw new Error(`Invitee Lite workspace owner not found: ${input.inviteeWorkspaceID}`) |
| 403 | |
| 404 | const inviterUser = await tx |
| 405 | .select({ id: UserTable.id }) |
| 406 | .from(UserTable) |
| 407 | .where( |
| 408 | and( |
| 409 | eq(UserTable.workspaceID, input.inviterWorkspaceID), |
| 410 | eq(UserTable.accountID, invitee.accountID), |
| 411 | isNull(UserTable.timeDeleted), |
| 412 | ), |
| 413 | ) |
| 414 | .then((rows) => rows[0]) |
| 415 | if (inviterUser) throw new Error(`Self-referral is not allowed: ${invitee.accountID}`) |
| 416 | |
| 417 | const existingReferral = await tx |
| 418 | .select({ id: ReferralTable.id, workspaceID: ReferralTable.workspaceID }) |
| 419 | .from(ReferralTable) |
| 420 | .where(and(eq(ReferralTable.inviteeAccountID, invitee.accountID), isNull(ReferralTable.timeDeleted))) |
| 421 | .then((rows) => rows[0]) |
| 422 | if (existingReferral && existingReferral.workspaceID !== input.inviterWorkspaceID) { |