ref(backend): smash migrations and apply changes to api

This commit is contained in:
Nicholas Tindle
2025-02-11 14:20:04 -06:00
parent c71bb17658
commit 0e99bdc742
6 changed files with 173 additions and 82 deletions

View File

@@ -5,11 +5,13 @@ from typing import Optional, cast
from autogpt_libs.auth.models import DEFAULT_USER_ID
from fastapi import HTTPException
from prisma import Json
from prisma.enums import NotificationType
from prisma.models import User
from backend.data.db import prisma
from backend.data.model import UserIntegrations, UserMetadata, UserMetadataRaw
from backend.data.notifications import NotificationPreference
from backend.server.v2.store.exceptions import DatabaseError
from backend.util.encryption import JSONCryptor
logger = logging.getLogger(__name__)
@@ -31,8 +33,13 @@ async def get_or_create_user(user_data: dict) -> User:
"id": user_id,
"email": user_email,
"name": user_data.get("user_metadata", {}).get("name"),
"UserNotificationPreference": {"create": {"userId": user_id}},
}
)
if not user.UserNotificationPreference:
user.UserNotificationPreference = (
await prisma.usernotificationpreference.create(data={"userId": user_id})
)
return User.model_validate(user)
@@ -159,19 +166,74 @@ async def get_active_users_ids() -> list[str]:
async def get_user_notification_preference(user_id: str) -> NotificationPreference:
user = await User.prisma().find_unique_or_raise(
where={"id": user_id},
include={
"UserNotificationPreference": True,
},
)
notification_preference = NotificationPreference(
user_id=user.id,
email=user.email,
# TODO with the UI when it comes in
preferences={},
daily_limit=3,
emails_sent_today=0,
last_reset_date=datetime.now(),
)
return NotificationPreference.model_validate(notification_preference)
try:
user = await User.prisma().find_unique_or_raise(
where={"id": user_id},
include={
"UserNotificationPreference": True,
},
)
# enable notifications by default if user has no notification preference (shouldn't ever happen though)
preferences: dict[NotificationType, bool] = {
NotificationType.AGENT_RUN: (
user.UserNotificationPreference.notifyOnAgentRun
if user.UserNotificationPreference
else True
),
NotificationType.ZERO_BALANCE: (
user.UserNotificationPreference.notifyOnZeroBalance
if user.UserNotificationPreference
else True
),
NotificationType.LOW_BALANCE: (
user.UserNotificationPreference.notifyOnLowBalance
if user.UserNotificationPreference
else True
),
NotificationType.BLOCK_EXECUTION_FAILED: (
user.UserNotificationPreference.notifyOnBlockExecutionFailed
if user.UserNotificationPreference
else True
),
NotificationType.CONTINUOUS_AGENT_ERROR: (
user.UserNotificationPreference.notifyOnContinuousAgentError
if user.UserNotificationPreference
else True
),
NotificationType.DAILY_SUMMARY: (
user.UserNotificationPreference.notifyOnDailySummary
if user.UserNotificationPreference
else True
),
NotificationType.WEEKLY_SUMMARY: (
user.UserNotificationPreference.notifyOnWeeklySummary
if user.UserNotificationPreference
else True
),
NotificationType.MONTHLY_SUMMARY: (
user.UserNotificationPreference.notifyOnMonthlySummary
if user.UserNotificationPreference
else True
),
}
daily_limit = (
user.UserNotificationPreference.maxEmailsPerDay
if user.UserNotificationPreference
else 3
)
notification_preference = NotificationPreference(
user_id=user.id,
email=user.email,
preferences=preferences,
daily_limit=daily_limit,
# TODO with other changes later, for now we just will email them
emails_sent_today=0,
last_reset_date=datetime.now(),
)
return NotificationPreference.model_validate(notification_preference)
except Exception as e:
raise DatabaseError(
f"Failed to upsert user notification preference for user {user_id}: {e}"
) from e

View File

@@ -1,13 +0,0 @@
-- CreateTable
CREATE TABLE "UserNotificationPreference" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"preferences" JSONB NOT NULL DEFAULT '{}',
CONSTRAINT "UserNotificationPreference_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "UserNotificationPreference" ADD CONSTRAINT "UserNotificationPreference_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1,31 +0,0 @@
-- CreateEnum
CREATE TYPE "NotificationType" AS ENUM ('AGENT_RUN', 'ZERO_BALANCE', 'LOW_BALANCE', 'BLOCK_EXECUTION_FAILED', 'CONTINUOUS_AGENT_ERROR', 'DAILY_SUMMARY', 'WEEKLY_SUMMARY', 'MONTHLY_SUMMARY');
-- CreateTable
CREATE TABLE "NotificationEvent" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userNotificationBatchId" TEXT,
"type" "NotificationType" NOT NULL,
"data" JSONB NOT NULL,
CONSTRAINT "NotificationEvent_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserNotificationBatch" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"type" "NotificationType" NOT NULL,
CONSTRAINT "UserNotificationBatch_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "NotificationEvent" ADD CONSTRAINT "NotificationEvent_userNotificationBatchId_fkey" FOREIGN KEY ("userNotificationBatchId") REFERENCES "UserNotificationBatch"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserNotificationBatch" ADD CONSTRAINT "UserNotificationBatch_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1,8 +0,0 @@
/*
Warnings:
- A unique constraint covering the columns `[userId,type]` on the table `UserNotificationBatch` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "UserNotificationBatch_userId_type_key" ON "UserNotificationBatch"("userId", "type");

View File

@@ -0,0 +1,71 @@
/*
Warnings:
- A unique constraint covering the columns `[userNotificationPreferenceId]` on the table `User` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateEnum
CREATE TYPE "NotificationType" AS ENUM ('AGENT_RUN', 'ZERO_BALANCE', 'LOW_BALANCE', 'BLOCK_EXECUTION_FAILED', 'CONTINUOUS_AGENT_ERROR', 'DAILY_SUMMARY', 'WEEKLY_SUMMARY', 'MONTHLY_SUMMARY');
-- AlterTable
ALTER TABLE "User" ADD COLUMN "userNotificationPreferenceId" TEXT;
-- CreateTable
CREATE TABLE "NotificationEvent" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userNotificationBatchId" TEXT,
"type" "NotificationType" NOT NULL,
"data" JSONB NOT NULL,
CONSTRAINT "NotificationEvent_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserNotificationBatch" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"type" "NotificationType" NOT NULL,
CONSTRAINT "UserNotificationBatch_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserNotificationPreference" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"maxEmailsPerDay" INTEGER NOT NULL DEFAULT 3,
"notifyOnAgentRun" BOOLEAN NOT NULL DEFAULT true,
"notifyOnZeroBalance" BOOLEAN NOT NULL DEFAULT true,
"notifyOnLowBalance" BOOLEAN NOT NULL DEFAULT true,
"notifyOnBlockExecutionFailed" BOOLEAN NOT NULL DEFAULT true,
"notifyOnContinuousAgentError" BOOLEAN NOT NULL DEFAULT true,
"notifyOnDailySummary" BOOLEAN NOT NULL DEFAULT true,
"notifyOnWeeklySummary" BOOLEAN NOT NULL DEFAULT true,
"notifyOnMonthlySummary" BOOLEAN NOT NULL DEFAULT true,
CONSTRAINT "UserNotificationPreference_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "UserNotificationBatch_userId_type_key" ON "UserNotificationBatch"("userId", "type");
-- CreateIndex
CREATE UNIQUE INDEX "UserNotificationPreference_userId_key" ON "UserNotificationPreference"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "User_userNotificationPreferenceId_key" ON "User"("userNotificationPreferenceId");
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_userNotificationPreferenceId_fkey" FOREIGN KEY ("userNotificationPreferenceId") REFERENCES "UserNotificationPreference"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "NotificationEvent" ADD CONSTRAINT "NotificationEvent_userNotificationBatchId_fkey" FOREIGN KEY ("userNotificationBatchId") REFERENCES "UserNotificationBatch"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserNotificationBatch" ADD CONSTRAINT "UserNotificationBatch_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -13,17 +13,19 @@ generator client {
// User model to mirror Auth provider users
model User {
id String @id // This should match the Supabase user ID
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
metadata Json @default("{}")
integrations String @default("")
stripeCustomerId String?
topUpConfig Json?
id String @id // This should match the Supabase user ID
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
metadata Json @default("{}")
integrations String @default("")
stripeCustomerId String?
topUpConfig Json?
userNotificationPreferenceId String? @unique
// Relations
AgentGraphs AgentGraph[]
AgentGraphExecutions AgentGraphExecution[]
AnalyticsDetails AnalyticsDetails[]
@@ -39,8 +41,8 @@ model User {
StoreListingSubmission StoreListingSubmission[]
APIKeys APIKey[]
IntegrationWebhooks IntegrationWebhook[]
UserNotificationPreference UserNotificationPreference[]
UserNotificationBatch UserNotificationBatch[]
UserNotificationPreference UserNotificationPreference? @relation(fields: [userNotificationPreferenceId], references: [id])
@@index([id])
@@index([email])
@@ -156,11 +158,19 @@ model UserNotificationPreference {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique // Add @unique here
User User?
// Dict[NotificationType, bool]
preferences Json @default("{}")
maxEmailsPerDay Int @default(3)
notifyOnAgentRun Boolean @default(true)
notifyOnZeroBalance Boolean @default(true)
notifyOnLowBalance Boolean @default(true)
notifyOnBlockExecutionFailed Boolean @default(true)
notifyOnContinuousAgentError Boolean @default(true)
notifyOnDailySummary Boolean @default(true)
notifyOnWeeklySummary Boolean @default(true)
notifyOnMonthlySummary Boolean @default(true)
}
// For the library page