feat: notifcations settings
This commit is contained in:
parent
d89eb44b8f
commit
c982e30e96
|
|
@ -22,6 +22,7 @@ import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions
|
|||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service';
|
||||
import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto';
|
||||
import { EmailNotificationsDto } from '@gitroom/nestjs-libraries/dtos/users/email-notifications.dto';
|
||||
import { HttpForbiddenException } from '@gitroom/nestjs-libraries/services/exception.filter';
|
||||
import { RealIP } from 'nestjs-real-ip';
|
||||
import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent';
|
||||
|
|
@ -125,6 +126,19 @@ export class UsersController {
|
|||
return this._userService.changePersonal(user.id, body);
|
||||
}
|
||||
|
||||
@Get('/email-notifications')
|
||||
async getEmailNotifications(@GetUserFromRequest() user: User) {
|
||||
return this._userService.getEmailNotifications(user.id);
|
||||
}
|
||||
|
||||
@Post('/email-notifications')
|
||||
async updateEmailNotifications(
|
||||
@GetUserFromRequest() user: User,
|
||||
@Body() body: EmailNotificationsDto
|
||||
) {
|
||||
return this._userService.updateEmailNotifications(user.id, body);
|
||||
}
|
||||
|
||||
@Get('/subscription')
|
||||
@CheckPolicies([AuthorizationActions.Create, Sections.ADMIN])
|
||||
async getSubscription(@GetOrgFromRequest() organization: Organization) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
'use client';
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import useSWR from 'swr';
|
||||
import { Slider } from '@gitroom/react/form/slider';
|
||||
import { useToaster } from '@gitroom/react/toaster/toaster';
|
||||
import { useT } from '@gitroom/react/translation/get.transation.service.client';
|
||||
|
||||
interface EmailNotifications {
|
||||
sendSuccessEmails: boolean;
|
||||
sendFailureEmails: boolean;
|
||||
}
|
||||
|
||||
export const useEmailNotifications = () => {
|
||||
const fetch = useFetch();
|
||||
|
||||
const load = useCallback(async () => {
|
||||
return (await fetch('/user/email-notifications')).json();
|
||||
}, []);
|
||||
|
||||
return useSWR<EmailNotifications>('email-notifications', load, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
revalidateOnMount: true,
|
||||
refreshWhenHidden: false,
|
||||
refreshWhenOffline: false,
|
||||
});
|
||||
};
|
||||
|
||||
const EmailNotificationsComponent = () => {
|
||||
const t = useT();
|
||||
const fetch = useFetch();
|
||||
const toaster = useToaster();
|
||||
const { data, isLoading } = useEmailNotifications();
|
||||
|
||||
const [localSettings, setLocalSettings] = useState<EmailNotifications>({
|
||||
sendSuccessEmails: true,
|
||||
sendFailureEmails: true,
|
||||
});
|
||||
|
||||
// Keep a ref to always have the latest state
|
||||
const settingsRef = useRef(localSettings);
|
||||
settingsRef.current = localSettings;
|
||||
|
||||
// Sync local state with fetched data
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setLocalSettings(data);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
const updateSetting = useCallback(
|
||||
async (key: keyof EmailNotifications, value: boolean) => {
|
||||
// Use ref to get the latest state
|
||||
const currentSettings = settingsRef.current;
|
||||
const newData = {
|
||||
...currentSettings,
|
||||
[key]: value,
|
||||
};
|
||||
|
||||
// Update local state immediately
|
||||
setLocalSettings(newData);
|
||||
|
||||
await fetch('/user/email-notifications', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(newData),
|
||||
});
|
||||
|
||||
toaster.show(t('settings_updated', 'Settings updated'), 'success');
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleSuccessEmailsChange = useCallback(
|
||||
(value: 'on' | 'off') => {
|
||||
updateSetting('sendSuccessEmails', value === 'on');
|
||||
},
|
||||
[updateSetting]
|
||||
);
|
||||
|
||||
const handleFailureEmailsChange = useCallback(
|
||||
(value: 'on' | 'off') => {
|
||||
updateSetting('sendFailureEmails', value === 'on');
|
||||
},
|
||||
[updateSetting]
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="my-[16px] mt-[16px] bg-sixth border-fifth border rounded-[4px] p-[24px]">
|
||||
<div className="animate-pulse">
|
||||
{t('loading', 'Loading...')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="my-[16px] mt-[16px] bg-sixth border-fifth border rounded-[4px] p-[24px] flex flex-col gap-[24px]">
|
||||
<div className="mt-[4px]">
|
||||
{t('email_notifications', 'Email Notifications')}
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[14px]">
|
||||
{t('success_emails', 'Success Emails')}
|
||||
</div>
|
||||
<div className="text-[12px] text-customColor18">
|
||||
{t(
|
||||
'success_emails_description',
|
||||
'Receive email notifications when posts are published successfully'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
value={localSettings.sendSuccessEmails ? 'on' : 'off'}
|
||||
onChange={handleSuccessEmailsChange}
|
||||
fill={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[14px]">
|
||||
{t('failure_emails', 'Failure Emails')}
|
||||
</div>
|
||||
<div className="text-[12px] text-customColor18">
|
||||
{t(
|
||||
'failure_emails_description',
|
||||
'Receive email notifications when posts fail to publish'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
value={localSettings.sendFailureEmails ? 'on' : 'off'}
|
||||
onChange={handleFailureEmailsChange}
|
||||
fill={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmailNotificationsComponent;
|
||||
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
import React from 'react';
|
||||
import { useT } from '@gitroom/react/translation/get.transation.service.client';
|
||||
import dynamic from 'next/dynamic';
|
||||
import EmailNotificationsComponent from '@gitroom/frontend/components/settings/email-notifications.component';
|
||||
|
||||
const MetricComponent = dynamic(
|
||||
() => import('@gitroom/frontend/components/settings/metric.component'),
|
||||
|
|
@ -10,12 +11,14 @@ const MetricComponent = dynamic(
|
|||
ssr: false,
|
||||
}
|
||||
);
|
||||
|
||||
export const GlobalSettings = () => {
|
||||
const t = useT();
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<h3 className="text-[20px]">{t('global_settings', 'Global Settings')}</h3>
|
||||
<MetricComponent />
|
||||
<EmailNotificationsComponent />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -187,7 +187,9 @@ export class IntegrationService {
|
|||
orgId,
|
||||
`Could not refresh your ${integration.providerIdentifier} channel ${err}`,
|
||||
`Could not refresh your ${integration.providerIdentifier} channel ${err}. Please go back to the system and connect it again ${process.env.FRONTEND_URL}/launches`,
|
||||
true
|
||||
true,
|
||||
false,
|
||||
'info'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/cl
|
|||
import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export type NotificationType = 'success' | 'fail' | 'info';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
constructor(
|
||||
|
|
@ -41,7 +43,8 @@ export class NotificationService {
|
|||
subject: string,
|
||||
message: string,
|
||||
sendEmail = false,
|
||||
digest = false
|
||||
digest = false,
|
||||
type: NotificationType = 'success'
|
||||
) {
|
||||
const date = new Date().toISOString();
|
||||
await this._notificationRepository.createNotification(orgId, message);
|
||||
|
|
@ -52,6 +55,12 @@ export class NotificationService {
|
|||
if (digest) {
|
||||
await ioRedis.watch('digest_' + orgId);
|
||||
const value = await ioRedis.get('digest_' + orgId);
|
||||
|
||||
// Track notification types in the digest
|
||||
const typesKey = 'digest_types_' + orgId;
|
||||
await ioRedis.sadd(typesKey, type);
|
||||
await ioRedis.expire(typesKey, 120); // Slightly longer than digest window
|
||||
|
||||
if (value) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -77,12 +86,66 @@ export class NotificationService {
|
|||
return;
|
||||
}
|
||||
|
||||
await this.sendEmailsToOrg(orgId, subject, message);
|
||||
await this.sendEmailsToOrg(orgId, subject, message, type);
|
||||
}
|
||||
|
||||
async sendEmailsToOrg(orgId: string, subject: string, message: string) {
|
||||
async sendEmailsToOrg(
|
||||
orgId: string,
|
||||
subject: string,
|
||||
message: string,
|
||||
type?: NotificationType
|
||||
) {
|
||||
const userOrg = await this._organizationRepository.getAllUsersOrgs(orgId);
|
||||
for (const user of userOrg?.users || []) {
|
||||
// 'info' type is always sent regardless of preferences
|
||||
if (type !== 'info') {
|
||||
// Filter users based on their email preferences
|
||||
if (type === 'success' && !user.user.sendSuccessEmails) {
|
||||
continue;
|
||||
}
|
||||
if (type === 'fail' && !user.user.sendFailureEmails) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
await this.sendEmail(user.user.email, subject, message);
|
||||
}
|
||||
}
|
||||
|
||||
async getDigestTypes(orgId: string): Promise<NotificationType[]> {
|
||||
const typesKey = 'digest_types_' + orgId;
|
||||
const types = await ioRedis.smembers(typesKey);
|
||||
// Clean up the types key after reading
|
||||
await ioRedis.del(typesKey);
|
||||
return types as NotificationType[];
|
||||
}
|
||||
|
||||
async sendDigestEmailsToOrg(
|
||||
orgId: string,
|
||||
subject: string,
|
||||
message: string,
|
||||
types: NotificationType[]
|
||||
) {
|
||||
const userOrg = await this._organizationRepository.getAllUsersOrgs(orgId);
|
||||
const hasInfo = types.includes('info');
|
||||
const hasSuccess = types.includes('success');
|
||||
const hasFail = types.includes('fail');
|
||||
|
||||
for (const user of userOrg?.users || []) {
|
||||
// 'info' type is always sent regardless of preferences
|
||||
if (hasInfo) {
|
||||
await this.sendEmail(user.user.email, subject, message);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For digest, check if user wants any of the notification types in the digest
|
||||
const wantsSuccess = hasSuccess && user.user.sendSuccessEmails;
|
||||
const wantsFail = hasFail && user.user.sendFailureEmails;
|
||||
|
||||
// Only send if user wants at least one type of notification in the digest
|
||||
if (!wantsSuccess && !wantsFail) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.sendEmail(user.user.email, subject, message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,6 +293,8 @@ export class OrganizationRepository {
|
|||
select: {
|
||||
email: true,
|
||||
id: true,
|
||||
sendSuccessEmails: true,
|
||||
sendFailureEmails: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -304,7 +304,9 @@ export class PostsService {
|
|||
firstPost.organizationId,
|
||||
`We couldn't post to ${firstPost.integration?.providerIdentifier} for ${firstPost?.integration?.name}`,
|
||||
`We couldn't post to ${firstPost.integration?.providerIdentifier} for ${firstPost?.integration?.name} because you need to reconnect it. Please enable it and try again.`,
|
||||
true
|
||||
true,
|
||||
false,
|
||||
'info'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -314,7 +316,9 @@ export class PostsService {
|
|||
firstPost.organizationId,
|
||||
`We couldn't post to ${firstPost.integration?.providerIdentifier} for ${firstPost?.integration?.name}`,
|
||||
`We couldn't post to ${firstPost.integration?.providerIdentifier} for ${firstPost?.integration?.name} because it's disabled. Please enable it and try again.`,
|
||||
true
|
||||
true,
|
||||
false,
|
||||
'info'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -343,7 +347,9 @@ export class PostsService {
|
|||
firstPost.organizationId,
|
||||
`Error posting on ${firstPost.integration?.providerIdentifier} for ${firstPost?.integration?.name}`,
|
||||
`An error occurred while posting on ${firstPost.integration?.providerIdentifier}`,
|
||||
true
|
||||
true,
|
||||
false,
|
||||
'fail'
|
||||
);
|
||||
|
||||
return;
|
||||
|
|
@ -362,7 +368,9 @@ export class PostsService {
|
|||
`An error occurred while posting on ${
|
||||
firstPost.integration?.providerIdentifier
|
||||
}${err?.message ? `: ${err?.message}` : ``}`,
|
||||
true
|
||||
true,
|
||||
false,
|
||||
'fail'
|
||||
);
|
||||
|
||||
console.error(
|
||||
|
|
@ -959,15 +967,20 @@ export class PostsService {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get the types of notifications in this digest
|
||||
const types = await this._notificationService.getDigestTypes(orgId);
|
||||
|
||||
const message = getNotificationsForOrgSince
|
||||
.map((p) => p.content)
|
||||
.join('<br />');
|
||||
await this._notificationService.sendEmailsToOrg(
|
||||
|
||||
await this._notificationService.sendDigestEmailsToOrg(
|
||||
orgId,
|
||||
getNotificationsForOrgSince.length === 1
|
||||
? subject
|
||||
: '[Postiz] Your latest notifications',
|
||||
message
|
||||
message,
|
||||
types.length > 0 ? types : ['success'] // Default to success if no types tracked
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
runtime = "nodejs"
|
||||
|
|
@ -16,32 +13,32 @@ model Organization {
|
|||
name String
|
||||
description String?
|
||||
apiKey String?
|
||||
users UserOrganization[]
|
||||
media Media[]
|
||||
paymentId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
github GitHub[]
|
||||
subscription Subscription?
|
||||
Integration Integration[]
|
||||
post Post[] @relation("organization")
|
||||
submittedPost Post[] @relation("submittedForOrg")
|
||||
allowTrial Boolean @default(false)
|
||||
isTrailing Boolean @default(false)
|
||||
Comments Comments[]
|
||||
notifications Notifications[]
|
||||
buyerOrganization MessagesGroup[]
|
||||
usedCodes UsedCodes[]
|
||||
credits Credits[]
|
||||
plugs Plugs[]
|
||||
customers Customer[]
|
||||
webhooks Webhooks[]
|
||||
tags Tags[]
|
||||
signatures Signatures[]
|
||||
autoPost AutoPost[]
|
||||
sets Sets[]
|
||||
thirdParty ThirdParty[]
|
||||
Comments Comments[]
|
||||
credits Credits[]
|
||||
customers Customer[]
|
||||
errors Errors[]
|
||||
github GitHub[]
|
||||
Integration Integration[]
|
||||
media Media[]
|
||||
buyerOrganization MessagesGroup[]
|
||||
notifications Notifications[]
|
||||
plugs Plugs[]
|
||||
post Post[] @relation("organization")
|
||||
submittedPost Post[] @relation("submittedForOrg")
|
||||
sets Sets[]
|
||||
signatures Signatures[]
|
||||
subscription Subscription?
|
||||
tags Tags[]
|
||||
thirdParty ThirdParty[]
|
||||
usedCodes UsedCodes[]
|
||||
users UserOrganization[]
|
||||
webhooks Webhooks[]
|
||||
}
|
||||
|
||||
model Tags {
|
||||
|
|
@ -49,11 +46,11 @@ model Tags {
|
|||
name String
|
||||
color String
|
||||
orgId String
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
posts TagsPosts[]
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
posts TagsPosts[]
|
||||
|
||||
@@index([orgId])
|
||||
@@index([deletedAt])
|
||||
|
|
@ -61,50 +58,52 @@ model Tags {
|
|||
|
||||
model TagsPosts {
|
||||
postId String
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
tagId String
|
||||
tag Tags @relation(fields: [tagId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
tag Tags @relation(fields: [tagId], references: [id])
|
||||
|
||||
@@id([postId, tagId])
|
||||
@@unique([postId, tagId])
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
email String
|
||||
password String?
|
||||
providerName Provider
|
||||
name String?
|
||||
lastName String?
|
||||
isSuperAdmin Boolean @default(false)
|
||||
isSuperAdmin Boolean @default(false)
|
||||
bio String?
|
||||
audience Int @default(0)
|
||||
audience Int @default(0)
|
||||
pictureId String?
|
||||
picture Media? @relation(fields: [pictureId], references: [id])
|
||||
providerId String?
|
||||
organizations UserOrganization[]
|
||||
timezone Int
|
||||
comments Comments[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
lastReadNotifications DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
lastReadNotifications DateTime @default(now())
|
||||
inviteId String?
|
||||
activated Boolean @default(true)
|
||||
items ItemUser[]
|
||||
marketplace Boolean @default(true)
|
||||
activated Boolean @default(true)
|
||||
marketplace Boolean @default(true)
|
||||
account String?
|
||||
connectedAccount Boolean @default(false)
|
||||
groupBuyer MessagesGroup[] @relation("groupBuyer")
|
||||
groupSeller MessagesGroup[] @relation("groupSeller")
|
||||
orderBuyer Orders[] @relation("orderBuyer")
|
||||
orderSeller Orders[] @relation("orderSeller")
|
||||
payoutProblems PayoutProblems[]
|
||||
lastOnline DateTime @default(now())
|
||||
agencies SocialMediaAgency[]
|
||||
connectedAccount Boolean @default(false)
|
||||
lastOnline DateTime @default(now())
|
||||
ip String?
|
||||
agent String?
|
||||
comments Comments[]
|
||||
items ItemUser[]
|
||||
groupBuyer MessagesGroup[] @relation("groupBuyer")
|
||||
groupSeller MessagesGroup[] @relation("groupSeller")
|
||||
orderBuyer Orders[] @relation("orderBuyer")
|
||||
orderSeller Orders[] @relation("orderSeller")
|
||||
payoutProblems PayoutProblems[]
|
||||
agencies SocialMediaAgency?
|
||||
picture Media? @relation(fields: [pictureId], references: [id])
|
||||
organizations UserOrganization[]
|
||||
sendSuccessEmails Boolean @default(true)
|
||||
sendFailureEmails Boolean @default(true)
|
||||
|
||||
@@unique([email, providerName])
|
||||
@@index([lastReadNotifications])
|
||||
|
|
@ -118,23 +117,23 @@ model UsedCodes {
|
|||
id String @id @default(uuid())
|
||||
code String
|
||||
orgId String
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
|
||||
@@index([code])
|
||||
}
|
||||
|
||||
model UserOrganization {
|
||||
id String @id @default(uuid())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
organizationId String
|
||||
disabled Boolean @default(false)
|
||||
role Role @default(USER)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@unique([userId, organizationId])
|
||||
@@index([disabled])
|
||||
|
|
@ -146,10 +145,10 @@ model GitHub {
|
|||
name String?
|
||||
token String
|
||||
jobId String?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
organizationId String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([login])
|
||||
@@index([organizationId])
|
||||
|
|
@ -158,13 +157,12 @@ model GitHub {
|
|||
model Trending {
|
||||
id String @id @default(uuid())
|
||||
trendingList String
|
||||
language String?
|
||||
language String? @unique
|
||||
hash String
|
||||
date DateTime
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([language])
|
||||
@@index([hash])
|
||||
}
|
||||
|
||||
|
|
@ -176,9 +174,9 @@ model TrendingLog {
|
|||
|
||||
model ItemUser {
|
||||
id String @id @default(uuid())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId String
|
||||
key String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@unique([userId, key])
|
||||
@@index([userId])
|
||||
|
|
@ -203,18 +201,18 @@ model Media {
|
|||
id String @id @default(uuid())
|
||||
name String
|
||||
path String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
organizationId String
|
||||
thumbnail String?
|
||||
thumbnailTimestamp Int?
|
||||
alt String?
|
||||
fileSize Int @default(0)
|
||||
type String @default("image")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
userPicture User[]
|
||||
agencies SocialMediaAgency[]
|
||||
deletedAt DateTime?
|
||||
fileSize Int @default(0)
|
||||
type String @default("image")
|
||||
thumbnail String?
|
||||
alt String?
|
||||
thumbnailTimestamp Int?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
agencies SocialMediaAgency[]
|
||||
userPicture User[]
|
||||
|
||||
@@index([name])
|
||||
@@index([organizationId])
|
||||
|
|
@ -222,15 +220,12 @@ model Media {
|
|||
}
|
||||
|
||||
model SocialMediaAgency {
|
||||
id String @id @default(uuid())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId String @unique()
|
||||
name String
|
||||
logoId String?
|
||||
logo Media? @relation(fields: [logoId], references: [id])
|
||||
website String?
|
||||
slug String?
|
||||
|
||||
id String @id @default(uuid())
|
||||
userId String @unique
|
||||
name String
|
||||
logoId String?
|
||||
website String?
|
||||
slug String?
|
||||
facebook String?
|
||||
instagram String?
|
||||
twitter String?
|
||||
|
|
@ -238,15 +233,15 @@ model SocialMediaAgency {
|
|||
youtube String?
|
||||
tiktok String?
|
||||
otherSocialMedia String?
|
||||
|
||||
shortDescription String
|
||||
description String
|
||||
niches SocialMediaAgencyNiche[]
|
||||
approved Boolean @default(false)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
logo Media? @relation(fields: [logoId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
niches SocialMediaAgencyNiche[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([deletedAt])
|
||||
|
|
@ -255,20 +250,20 @@ model SocialMediaAgency {
|
|||
|
||||
model SocialMediaAgencyNiche {
|
||||
agencyId String
|
||||
agency SocialMediaAgency @relation(fields: [agencyId], references: [id])
|
||||
niche String
|
||||
agency SocialMediaAgency @relation(fields: [agencyId], references: [id])
|
||||
|
||||
@@id([agencyId, niche])
|
||||
}
|
||||
|
||||
model Credits {
|
||||
id String @id @default(uuid())
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
organizationId String
|
||||
credits Int
|
||||
type String @default("ai_images")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
type String @default("ai_images")
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([organizationId])
|
||||
@@index([createdAt])
|
||||
|
|
@ -277,7 +272,6 @@ model Credits {
|
|||
model Subscription {
|
||||
id String @id @default(cuid())
|
||||
organizationId String @unique
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
subscriptionTier SubscriptionTier
|
||||
identifier String?
|
||||
cancelAt DateTime?
|
||||
|
|
@ -287,6 +281,7 @@ model Subscription {
|
|||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([organizationId])
|
||||
@@index([deletedAt])
|
||||
|
|
@ -296,11 +291,11 @@ model Customer {
|
|||
id String @id @default(uuid())
|
||||
name String
|
||||
orgId String
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
integrations Integration[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [orgId], references: [id])
|
||||
integrations Integration[]
|
||||
|
||||
@@unique([orgId, name, deletedAt])
|
||||
}
|
||||
|
|
@ -310,7 +305,6 @@ model Integration {
|
|||
internalId String
|
||||
organizationId String
|
||||
name String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
picture String?
|
||||
providerIdentifier String
|
||||
type String
|
||||
|
|
@ -318,23 +312,24 @@ model Integration {
|
|||
disabled Boolean @default(false)
|
||||
tokenExpiration DateTime?
|
||||
refreshToken String?
|
||||
posts Post[]
|
||||
profile String?
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime? @updatedAt
|
||||
orderItems OrderItems[]
|
||||
inBetweenSteps Boolean @default(false)
|
||||
refreshNeeded Boolean @default(false)
|
||||
postingTimes String @default("[{\"time\":120}, {\"time\":400}, {\"time\":700}]")
|
||||
customInstanceDetails String?
|
||||
customerId String?
|
||||
customer Customer? @relation(fields: [customerId], references: [id])
|
||||
plugs Plugs[]
|
||||
exisingPlugData ExisingPlugData[]
|
||||
rootInternalId String?
|
||||
additionalSettings String? @default("[]")
|
||||
exisingPlugData ExisingPlugData[]
|
||||
customer Customer? @relation(fields: [customerId], references: [id])
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
webhooks IntegrationsWebhooks[]
|
||||
orderItems OrderItems[]
|
||||
plugs Plugs[]
|
||||
posts Post[]
|
||||
|
||||
@@unique([organizationId, internalId])
|
||||
@@index([rootInternalId])
|
||||
|
|
@ -352,12 +347,12 @@ model Integration {
|
|||
model Signatures {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
content String
|
||||
autoAdd Boolean
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([organizationId])
|
||||
|
|
@ -368,14 +363,14 @@ model Comments {
|
|||
id String @id @default(uuid())
|
||||
content String
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
postId String
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([organizationId])
|
||||
|
|
@ -392,33 +387,33 @@ model Post {
|
|||
integrationId String
|
||||
content String
|
||||
group String
|
||||
organization Organization @relation("organization", fields: [organizationId], references: [id])
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
title String?
|
||||
description String?
|
||||
parentPostId String?
|
||||
releaseId String?
|
||||
releaseURL String?
|
||||
settings String?
|
||||
parentPost Post? @relation("parentPostId", fields: [parentPostId], references: [id])
|
||||
childrenPost Post[] @relation("parentPostId")
|
||||
image String?
|
||||
submittedForOrderId String?
|
||||
submittedForOrder Orders? @relation(fields: [submittedForOrderId], references: [id])
|
||||
submittedForOrganizationId String?
|
||||
submittedForOrganization Organization? @relation("submittedForOrg", fields: [submittedForOrganizationId], references: [id])
|
||||
approvedSubmitForOrder APPROVED_SUBMIT_FOR_ORDER @default(NO)
|
||||
lastMessageId String?
|
||||
lastMessage Messages? @relation(fields: [lastMessageId], references: [id])
|
||||
intervalInDays Int?
|
||||
payoutProblems PayoutProblems[]
|
||||
comments Comments[]
|
||||
tags TagsPosts[]
|
||||
errors Errors[]
|
||||
error String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
comments Comments[]
|
||||
errors Errors[]
|
||||
payoutProblems PayoutProblems[]
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
lastMessage Messages? @relation(fields: [lastMessageId], references: [id])
|
||||
organization Organization @relation("organization", fields: [organizationId], references: [id])
|
||||
parentPost Post? @relation("parentPostId", fields: [parentPostId], references: [id])
|
||||
childrenPost Post[] @relation("parentPostId")
|
||||
submittedForOrder Orders? @relation(fields: [submittedForOrderId], references: [id])
|
||||
submittedForOrganization Organization? @relation("submittedForOrg", fields: [submittedForOrganizationId], references: [id])
|
||||
tags TagsPosts[]
|
||||
|
||||
@@index([group])
|
||||
@@index([deletedAt])
|
||||
|
|
@ -439,12 +434,12 @@ model Post {
|
|||
model Notifications {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
content String
|
||||
link String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([organizationId])
|
||||
|
|
@ -454,15 +449,15 @@ model Notifications {
|
|||
model MessagesGroup {
|
||||
id String @id @default(uuid())
|
||||
buyerOrganizationId String
|
||||
buyerOrganization Organization @relation(fields: [buyerOrganizationId], references: [id])
|
||||
buyerId String
|
||||
buyer User @relation("groupBuyer", fields: [buyerId], references: [id])
|
||||
sellerId String
|
||||
seller User @relation("groupSeller", fields: [sellerId], references: [id])
|
||||
messages Messages[]
|
||||
orders Orders[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
messages Messages[]
|
||||
buyer User @relation("groupBuyer", fields: [buyerId], references: [id])
|
||||
buyerOrganization Organization @relation(fields: [buyerOrganizationId], references: [id])
|
||||
seller User @relation("groupSeller", fields: [sellerId], references: [id])
|
||||
orders Orders[]
|
||||
|
||||
@@unique([buyerId, sellerId])
|
||||
@@index([createdAt])
|
||||
|
|
@ -474,31 +469,31 @@ model PayoutProblems {
|
|||
id String @id @default(uuid())
|
||||
status String
|
||||
orderId String
|
||||
order Orders @relation(fields: [orderId], references: [id])
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
postId String?
|
||||
post Post? @relation(fields: [postId], references: [id])
|
||||
amount Int
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
order Orders @relation(fields: [orderId], references: [id])
|
||||
post Post? @relation(fields: [postId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
}
|
||||
|
||||
model Orders {
|
||||
id String @id @default(uuid())
|
||||
buyerId String
|
||||
sellerId String
|
||||
posts Post[]
|
||||
buyer User @relation("orderBuyer", fields: [buyerId], references: [id])
|
||||
seller User @relation("orderSeller", fields: [sellerId], references: [id])
|
||||
status OrderStatus
|
||||
ordersItems OrderItems[]
|
||||
messageGroupId String
|
||||
messageGroup MessagesGroup @relation(fields: [messageGroupId], references: [id])
|
||||
captureId String?
|
||||
payoutProblems PayoutProblems[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
ordersItems OrderItems[]
|
||||
buyer User @relation("orderBuyer", fields: [buyerId], references: [id])
|
||||
messageGroup MessagesGroup @relation(fields: [messageGroupId], references: [id])
|
||||
seller User @relation("orderSeller", fields: [sellerId], references: [id])
|
||||
payoutProblems PayoutProblems[]
|
||||
posts Post[]
|
||||
|
||||
@@index([buyerId])
|
||||
@@index([sellerId])
|
||||
|
|
@ -510,11 +505,11 @@ model Orders {
|
|||
model OrderItems {
|
||||
id String @id @default(uuid())
|
||||
orderId String
|
||||
order Orders @relation(fields: [orderId], references: [id])
|
||||
integrationId String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
quantity Int
|
||||
price Int
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
order Orders @relation(fields: [orderId], references: [id])
|
||||
|
||||
@@index([orderId])
|
||||
@@index([integrationId])
|
||||
|
|
@ -525,12 +520,12 @@ model Messages {
|
|||
from From
|
||||
content String?
|
||||
groupId String
|
||||
group MessagesGroup @relation(fields: [groupId], references: [id])
|
||||
special String?
|
||||
posts Post[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
group MessagesGroup @relation(fields: [groupId], references: [id])
|
||||
posts Post[]
|
||||
|
||||
@@index([groupId])
|
||||
@@index([createdAt])
|
||||
|
|
@ -540,12 +535,12 @@ model Messages {
|
|||
model Plugs {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
plugFunction String
|
||||
data String
|
||||
integrationId String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
activated Boolean @default(true)
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@unique([plugFunction, integrationId])
|
||||
@@index([organizationId])
|
||||
|
|
@ -554,9 +549,9 @@ model Plugs {
|
|||
model ExisingPlugData {
|
||||
id String @id @default(uuid())
|
||||
integrationId String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
methodName String
|
||||
value String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
|
||||
@@unique([integrationId, methodName, value])
|
||||
}
|
||||
|
|
@ -573,8 +568,8 @@ model PopularPosts {
|
|||
|
||||
model IntegrationsWebhooks {
|
||||
integrationId String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
webhookId String
|
||||
integration Integration @relation(fields: [integrationId], references: [id])
|
||||
webhook Webhooks @relation(fields: [webhookId], references: [id])
|
||||
|
||||
@@id([integrationId, webhookId])
|
||||
|
|
@ -587,12 +582,12 @@ model Webhooks {
|
|||
id String @id @default(uuid())
|
||||
name String
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
integrations IntegrationsWebhooks[]
|
||||
url String
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
integrations IntegrationsWebhooks[]
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([organizationId])
|
||||
@@index([deletedAt])
|
||||
|
|
@ -601,7 +596,6 @@ model Webhooks {
|
|||
model AutoPost {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
title String
|
||||
content String?
|
||||
onSlot Boolean
|
||||
|
|
@ -615,6 +609,7 @@ model AutoPost {
|
|||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([deletedAt])
|
||||
}
|
||||
|
|
@ -622,11 +617,11 @@ model AutoPost {
|
|||
model Sets {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
name String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@index([organizationId])
|
||||
}
|
||||
|
|
@ -634,7 +629,6 @@ model Sets {
|
|||
model ThirdParty {
|
||||
id String @id @default(uuid())
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
identifier String
|
||||
name String
|
||||
internalId String
|
||||
|
|
@ -642,6 +636,7 @@ model ThirdParty {
|
|||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
|
||||
@@unique([organizationId, internalId])
|
||||
@@index([organizationId])
|
||||
|
|
@ -651,14 +646,14 @@ model ThirdParty {
|
|||
model Errors {
|
||||
id String @id @default(uuid())
|
||||
message String
|
||||
body String @default("{}")
|
||||
platform String
|
||||
organizationId String
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
postId String
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
postId String
|
||||
body String @default("{}")
|
||||
organization Organization @relation(fields: [organizationId], references: [id])
|
||||
post Post @relation(fields: [postId], references: [id])
|
||||
|
||||
@@index([organizationId])
|
||||
@@index([createdAt])
|
||||
|
|
@ -668,14 +663,171 @@ model Mentions {
|
|||
name String
|
||||
username String
|
||||
platform String
|
||||
image String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
image String
|
||||
|
||||
@@id([name, username, platform, image])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.
|
||||
model mastra_ai_spans {
|
||||
traceId String
|
||||
spanId String
|
||||
parentSpanId String?
|
||||
name String
|
||||
scope Json?
|
||||
spanType String
|
||||
attributes Json?
|
||||
metadata Json?
|
||||
links Json?
|
||||
input Json?
|
||||
output Json?
|
||||
error Json?
|
||||
startedAt DateTime @db.Timestamp(6)
|
||||
endedAt DateTime? @db.Timestamp(6)
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
updatedAt DateTime? @db.Timestamp(6)
|
||||
isEvent Boolean
|
||||
startedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
endedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
updatedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@index([name], map: "public_mastra_ai_spans_name_idx")
|
||||
@@index([parentSpanId, startedAt(sort: Desc)], map: "public_mastra_ai_spans_parentspanid_startedat_idx")
|
||||
@@index([spanType, startedAt(sort: Desc)], map: "public_mastra_ai_spans_spantype_startedat_idx")
|
||||
@@index([traceId, startedAt(sort: Desc)], map: "public_mastra_ai_spans_traceid_startedat_idx")
|
||||
@@ignore
|
||||
}
|
||||
|
||||
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.
|
||||
model mastra_evals {
|
||||
input String
|
||||
output String
|
||||
result Json
|
||||
agent_name String
|
||||
metric_name String
|
||||
instructions String
|
||||
test_info Json?
|
||||
global_run_id String
|
||||
run_id String
|
||||
created_at DateTime @db.Timestamp(6)
|
||||
createdAt DateTime? @db.Timestamp(6)
|
||||
created_atZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@index([agent_name, created_at(sort: Desc)], map: "public_mastra_evals_agent_name_created_at_idx")
|
||||
@@ignore
|
||||
}
|
||||
|
||||
model mastra_messages {
|
||||
id String @id
|
||||
thread_id String
|
||||
content String
|
||||
role String
|
||||
type String
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
resourceId String?
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@index([thread_id, createdAt(sort: Desc)], map: "public_mastra_messages_thread_id_createdat_idx")
|
||||
}
|
||||
|
||||
model mastra_resources {
|
||||
id String @id
|
||||
workingMemory String?
|
||||
metadata Json?
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
updatedAt DateTime @db.Timestamp(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
updatedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
}
|
||||
|
||||
model mastra_scorers {
|
||||
id String @id
|
||||
scorerId String
|
||||
traceId String?
|
||||
runId String
|
||||
scorer Json
|
||||
preprocessStepResult Json?
|
||||
extractStepResult Json?
|
||||
analyzeStepResult Json?
|
||||
score Float
|
||||
reason String?
|
||||
metadata Json?
|
||||
preprocessPrompt String?
|
||||
extractPrompt String?
|
||||
generateScorePrompt String?
|
||||
generateReasonPrompt String?
|
||||
analyzePrompt String?
|
||||
reasonPrompt String?
|
||||
input Json
|
||||
output Json
|
||||
additionalContext Json?
|
||||
runtimeContext Json?
|
||||
entityType String?
|
||||
entity Json?
|
||||
entityId String?
|
||||
source String
|
||||
resourceId String?
|
||||
threadId String?
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
updatedAt DateTime @db.Timestamp(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
updatedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
spanId String?
|
||||
|
||||
@@index([traceId, spanId, createdAt(sort: Desc)], map: "public_mastra_scores_trace_id_span_id_created_at_idx")
|
||||
}
|
||||
|
||||
model mastra_threads {
|
||||
id String @id
|
||||
resourceId String
|
||||
title String
|
||||
metadata String?
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
updatedAt DateTime @db.Timestamp(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
updatedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@index([resourceId, createdAt(sort: Desc)], map: "public_mastra_threads_resourceid_createdat_idx")
|
||||
}
|
||||
|
||||
model mastra_traces {
|
||||
id String @id
|
||||
parentSpanId String?
|
||||
name String
|
||||
traceId String
|
||||
scope String
|
||||
kind Int
|
||||
attributes Json?
|
||||
status Json?
|
||||
events Json?
|
||||
links Json?
|
||||
other String?
|
||||
startTime BigInt
|
||||
endTime BigInt
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@index([name, startTime(sort: Desc)], map: "public_mastra_traces_name_starttime_idx")
|
||||
}
|
||||
|
||||
model mastra_workflow_snapshot {
|
||||
workflow_name String
|
||||
run_id String
|
||||
resourceId String?
|
||||
snapshot String
|
||||
createdAt DateTime @db.Timestamp(6)
|
||||
updatedAt DateTime @db.Timestamp(6)
|
||||
createdAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
updatedAtZ DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
@@unique([workflow_name, run_id], map: "public_mastra_workflow_snapshot_workflow_name_run_id_key")
|
||||
}
|
||||
|
||||
enum OrderStatus {
|
||||
PENDING
|
||||
ACCEPTED
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { AuthService } from '@gitroom/helpers/auth/auth.service';
|
|||
import { ItemsDto } from '@gitroom/nestjs-libraries/dtos/marketplace/items.dto';
|
||||
import { allTagsOptions } from '@gitroom/nestjs-libraries/database/prisma/marketplace/tags.list';
|
||||
import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto';
|
||||
import { EmailNotificationsDto } from '@gitroom/nestjs-libraries/dtos/users/email-notifications.dto';
|
||||
|
||||
@Injectable()
|
||||
export class UsersRepository {
|
||||
|
|
@ -161,6 +162,30 @@ export class UsersRepository {
|
|||
});
|
||||
}
|
||||
|
||||
async getEmailNotifications(userId: string) {
|
||||
return this._user.model.user.findUnique({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
select: {
|
||||
sendSuccessEmails: true,
|
||||
sendFailureEmails: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateEmailNotifications(userId: string, body: EmailNotificationsDto) {
|
||||
await this._user.model.user.update({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
data: {
|
||||
sendSuccessEmails: body.sendSuccessEmails,
|
||||
sendFailureEmails: body.sendFailureEmails,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getMarketplacePeople(orgId: string, userId: string, items: ItemsDto) {
|
||||
const info = {
|
||||
id: {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { UsersRepository } from '@gitroom/nestjs-libraries/database/prisma/users
|
|||
import { Provider } from '@prisma/client';
|
||||
import { ItemsDto } from '@gitroom/nestjs-libraries/dtos/marketplace/items.dto';
|
||||
import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto';
|
||||
import { EmailNotificationsDto } from '@gitroom/nestjs-libraries/dtos/users/email-notifications.dto';
|
||||
import { OrganizationRepository } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.repository';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -55,4 +56,12 @@ export class UsersService {
|
|||
changePersonal(userId: string, body: UserDetailDto) {
|
||||
return this._usersRepository.changePersonal(userId, body);
|
||||
}
|
||||
|
||||
getEmailNotifications(userId: string) {
|
||||
return this._usersRepository.getEmailNotifications(userId);
|
||||
}
|
||||
|
||||
updateEmailNotifications(userId: string, body: EmailNotificationsDto) {
|
||||
return this._usersRepository.updateEmailNotifications(userId, body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import { IsBoolean } from 'class-validator';
|
||||
|
||||
export class EmailNotificationsDto {
|
||||
@IsBoolean()
|
||||
sendSuccessEmails: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
sendFailureEmails: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
"cron": "rm -rf dist/cron && pnpm --filter ./apps/cron run dev",
|
||||
"prisma-generate": "pnpm dlx prisma@6.5.0 generate --schema ./libraries/nestjs-libraries/src/database/prisma/schema.prisma",
|
||||
"prisma-db-push": "pnpm dlx prisma@6.5.0 db push --schema ./libraries/nestjs-libraries/src/database/prisma/schema.prisma",
|
||||
"prisma-db-pull": "pnpm dlx prisma@6.5.0 db pull --schema ./libraries/nestjs-libraries/src/database/prisma/schema.prisma",
|
||||
"prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && pnpm dlx prisma@6.5.0 db push --force-reset && pnpx prisma@6.5.0 db push",
|
||||
"docker-build": "./var/docker/docker-build.sh",
|
||||
"docker-create": "./var/docker/docker-create.sh",
|
||||
|
|
|
|||
Loading…
Reference in New Issue