| 1 | import { and, eq, inArray } from 'drizzle-orm' |
| 2 | import { createLogger } |
| 3 | import { db } |
| 4 | import { members, users |
| 5 | import { emailService } |
| 6 | |
| 7 | const log = createLogger |
| 8 | |
| 9 | /** |
| 10 | * Fetch all admin and owner members for an organization with their email/name. |
| 11 | */ |
| 12 | export async function getAdminsAndOwners |
| 13 | return await db |
| 14 | .select({ email: |
| 15 | .from(members) |
| 16 | .innerJoin(users, |
| 17 | .where( |
| 18 | and( |
| 19 | eq(members.organizationId |
| 20 | inArray(members.role |
| 21 | ) |
| 22 | ) |
| 23 | } |
| 24 | |
| 25 | /** |
| 26 | * Send an email to each recipient, logging failures instead of silently swallowing them. |
| 27 | * Uses Promise.allSettled so individual failures don't block others. |
| 28 | */ |
| 29 | export async function sendEmailsToRecipients |
| 30 | recipients: Array |
| 31 | buildEmail: (recipient |
| 32 | email: string |
| 33 | name: string |
| 34 | }) => |
| 35 | ) { |
| 36 | const results = |
| 37 | recipients.map(async |
| 38 | const emailParams = |
| 39 | return emailService.sendEmail |
| 40 | }) |
| 41 | ) |
| 42 | |
| 43 | for (const result |
| 44 | if (result.status |
| 45 | log.error('Failed to send notification email |
| 46 | error: String(result |
| 47 | }) |
| 48 | } |
| 49 | } |
| 50 | } |