feat: extend notification system with batch sender, bulk dialog, and logging
Add NotificationLog schema extensions (nullable userId, email, roundId, projectId, batchId fields), batch notification sender service, and bulk notification dialog UI. Include utility scripts for debugging and seeding. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "NotificationLog" DROP CONSTRAINT "NotificationLog_userId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "NotificationLog" ADD COLUMN "batchId" TEXT,
|
||||
ADD COLUMN "email" TEXT,
|
||||
ADD COLUMN "projectId" TEXT,
|
||||
ADD COLUMN "roundId" TEXT,
|
||||
ALTER COLUMN "userId" DROP NOT NULL,
|
||||
ALTER COLUMN "channel" SET DEFAULT 'EMAIL';
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NotificationLog_roundId_type_idx" ON "NotificationLog"("roundId", "type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NotificationLog_projectId_idx" ON "NotificationLog"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NotificationLog_batchId_idx" ON "NotificationLog"("batchId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NotificationLog_email_idx" ON "NotificationLog"("email");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NotificationLog" ADD CONSTRAINT "NotificationLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NotificationLog" ADD CONSTRAINT "NotificationLog_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NotificationLog" ADD CONSTRAINT "NotificationLog_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -638,6 +638,7 @@ model Project {
|
||||
deliberationVotes DeliberationVote[]
|
||||
deliberationResults DeliberationResult[]
|
||||
submissionPromotions SubmissionPromotionEvent[]
|
||||
notificationLogs NotificationLog[]
|
||||
|
||||
@@index([programId])
|
||||
@@index([status])
|
||||
@@ -931,22 +932,34 @@ model AIUsageLog {
|
||||
|
||||
model NotificationLog {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
channel NotificationChannel
|
||||
userId String?
|
||||
channel NotificationChannel @default(EMAIL)
|
||||
provider String? // META, TWILIO, SMTP
|
||||
type String // MAGIC_LINK, REMINDER, ANNOUNCEMENT, JURY_INVITATION
|
||||
type String // MAGIC_LINK, REMINDER, ANNOUNCEMENT, JURY_INVITATION, ADVANCEMENT_NOTIFICATION, etc.
|
||||
status String // PENDING, SENT, DELIVERED, FAILED
|
||||
externalId String? // Message ID from provider
|
||||
errorMsg String? @db.Text
|
||||
|
||||
// Bulk notification tracking
|
||||
email String? // Recipient email address
|
||||
roundId String?
|
||||
projectId String?
|
||||
batchId String? // Groups emails from same send operation
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// Relations
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
round Round? @relation(fields: [roundId], references: [id], onDelete: SetNull)
|
||||
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
@@index([roundId, type])
|
||||
@@index([projectId])
|
||||
@@index([batchId])
|
||||
@@index([email])
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -2233,6 +2246,7 @@ model Round {
|
||||
evaluationSummaries EvaluationSummary[]
|
||||
evaluationDiscussions EvaluationDiscussion[]
|
||||
messages Message[]
|
||||
notificationLogs NotificationLog[]
|
||||
cohorts Cohort[]
|
||||
liveCursor LiveProgressCursor?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user