mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
fix: invalid folder queries (#1898)
Currently the majority of folder mutations only work if the user is the owner of the folder.
This commit is contained in:
@ -116,8 +116,8 @@ export const FolderDeleteDialog = ({ folder, isOpen, onOpenChange }: FolderDelet
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>
|
||||
<Trans>
|
||||
This folder contains multiple items. Deleting it will also delete all items in the
|
||||
folder, including nested folders and their contents.
|
||||
This folder contains multiple items. Deleting it will remove all subfolders and move
|
||||
all nested documents and templates to the root folder.
|
||||
</Trans>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import type * as DialogPrimitive from '@radix-ui/react-dialog';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
@ -14,6 +14,7 @@ import type { TFolderWithSubfolders } from '@documenso/trpc/server/folder-router
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
@ -40,7 +41,7 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||
|
||||
import { useOptionalCurrentTeam } from '~/providers/team';
|
||||
|
||||
export type FolderSettingsDialogProps = {
|
||||
export type FolderUpdateDialogProps = {
|
||||
folder: TFolderWithSubfolders | null;
|
||||
isOpen: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
@ -53,12 +54,8 @@ export const ZUpdateFolderFormSchema = z.object({
|
||||
|
||||
export type TUpdateFolderFormSchema = z.infer<typeof ZUpdateFolderFormSchema>;
|
||||
|
||||
export const FolderSettingsDialog = ({
|
||||
folder,
|
||||
isOpen,
|
||||
onOpenChange,
|
||||
}: FolderSettingsDialogProps) => {
|
||||
const { _ } = useLingui();
|
||||
export const FolderUpdateDialog = ({ folder, isOpen, onOpenChange }: FolderUpdateDialogProps) => {
|
||||
const { t } = useLingui();
|
||||
const team = useOptionalCurrentTeam();
|
||||
|
||||
const { toast } = useToast();
|
||||
@ -84,7 +81,9 @@ export const FolderSettingsDialog = ({
|
||||
}, [folder, form]);
|
||||
|
||||
const onFormSubmit = async (data: TUpdateFolderFormSchema) => {
|
||||
if (!folder) return;
|
||||
if (!folder) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await updateFolder({
|
||||
@ -96,7 +95,7 @@ export const FolderSettingsDialog = ({
|
||||
});
|
||||
|
||||
toast({
|
||||
title: _(msg`Folder updated successfully`),
|
||||
title: t`Folder updated successfully`,
|
||||
});
|
||||
|
||||
onOpenChange(false);
|
||||
@ -105,7 +104,7 @@ export const FolderSettingsDialog = ({
|
||||
|
||||
if (error.code === AppErrorCode.NOT_FOUND) {
|
||||
toast({
|
||||
title: _(msg`Folder not found`),
|
||||
title: t`Folder not found`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -115,8 +114,12 @@ export const FolderSettingsDialog = ({
|
||||
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Folder Settings</DialogTitle>
|
||||
<DialogDescription>Manage the settings for this folder.</DialogDescription>
|
||||
<DialogTitle>
|
||||
<Trans>Folder Settings</Trans>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans>Manage the settings for this folder.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<Form {...form}>
|
||||
@ -126,7 +129,9 @@ export const FolderSettingsDialog = ({
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Name</FormLabel>
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
@ -141,19 +146,25 @@ export const FolderSettingsDialog = ({
|
||||
name="visibility"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Visibility</FormLabel>
|
||||
<FormLabel>
|
||||
<Trans>Visibility</Trans>
|
||||
</FormLabel>
|
||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select visibility" />
|
||||
<SelectValue placeholder={t`Select visibility`} />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value={DocumentVisibility.EVERYONE}>Everyone</SelectItem>
|
||||
<SelectItem value={DocumentVisibility.MANAGER_AND_ABOVE}>
|
||||
Managers and above
|
||||
<SelectItem value={DocumentVisibility.EVERYONE}>
|
||||
<Trans>Everyone</Trans>
|
||||
</SelectItem>
|
||||
<SelectItem value={DocumentVisibility.MANAGER_AND_ABOVE}>
|
||||
<Trans>Managers and above</Trans>
|
||||
</SelectItem>
|
||||
<SelectItem value={DocumentVisibility.ADMIN}>
|
||||
<Trans>Admins only</Trans>
|
||||
</SelectItem>
|
||||
<SelectItem value={DocumentVisibility.ADMIN}>Admins only</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
@ -163,7 +174,15 @@ export const FolderSettingsDialog = ({
|
||||
)}
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="submit">Save Changes</Button>
|
||||
<DialogClose asChild>
|
||||
<Button variant="secondary">
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
</DialogClose>
|
||||
|
||||
<Button type="submit" loading={form.formState.isSubmitting}>
|
||||
<Trans>Update</Trans>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Form>
|
||||
@ -13,7 +13,7 @@ import { Skeleton } from '@documenso/ui/primitives/skeleton';
|
||||
import { FolderCreateDialog } from '~/components/dialogs/folder-create-dialog';
|
||||
import { FolderDeleteDialog } from '~/components/dialogs/folder-delete-dialog';
|
||||
import { FolderMoveDialog } from '~/components/dialogs/folder-move-dialog';
|
||||
import { FolderSettingsDialog } from '~/components/dialogs/folder-settings-dialog';
|
||||
import { FolderUpdateDialog } from '~/components/dialogs/folder-update-dialog';
|
||||
import { TemplateCreateDialog } from '~/components/dialogs/template-create-dialog';
|
||||
import { DocumentUploadDropzone } from '~/components/general/document/document-upload';
|
||||
import { FolderCard, FolderCardEmpty } from '~/components/general/folder/folder-card';
|
||||
@ -219,7 +219,7 @@ export const FolderGrid = ({ type, parentId }: FolderGridProps) => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<FolderSettingsDialog
|
||||
<FolderUpdateDialog
|
||||
folder={folderToSettings}
|
||||
isOpen={isSettingsFolderOpen}
|
||||
onOpenChange={(open) => {
|
||||
|
||||
@ -14,7 +14,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
||||
import { FolderCreateDialog } from '~/components/dialogs/folder-create-dialog';
|
||||
import { FolderDeleteDialog } from '~/components/dialogs/folder-delete-dialog';
|
||||
import { FolderMoveDialog } from '~/components/dialogs/folder-move-dialog';
|
||||
import { FolderSettingsDialog } from '~/components/dialogs/folder-settings-dialog';
|
||||
import { FolderUpdateDialog } from '~/components/dialogs/folder-update-dialog';
|
||||
import { FolderCard } from '~/components/general/folder/folder-card';
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
import { appMetaTags } from '~/utils/meta';
|
||||
@ -177,7 +177,7 @@ export default function DocumentsFoldersPage() {
|
||||
}}
|
||||
/>
|
||||
|
||||
<FolderSettingsDialog
|
||||
<FolderUpdateDialog
|
||||
folder={folderToSettings}
|
||||
isOpen={isSettingsFolderOpen}
|
||||
onOpenChange={(open) => {
|
||||
|
||||
@ -14,7 +14,7 @@ import { Input } from '@documenso/ui/primitives/input';
|
||||
import { FolderCreateDialog } from '~/components/dialogs/folder-create-dialog';
|
||||
import { FolderDeleteDialog } from '~/components/dialogs/folder-delete-dialog';
|
||||
import { FolderMoveDialog } from '~/components/dialogs/folder-move-dialog';
|
||||
import { FolderSettingsDialog } from '~/components/dialogs/folder-settings-dialog';
|
||||
import { FolderUpdateDialog } from '~/components/dialogs/folder-update-dialog';
|
||||
import { FolderCard } from '~/components/general/folder/folder-card';
|
||||
import { useCurrentTeam } from '~/providers/team';
|
||||
import { appMetaTags } from '~/utils/meta';
|
||||
@ -177,7 +177,7 @@ export default function TemplatesFoldersPage() {
|
||||
}}
|
||||
/>
|
||||
|
||||
<FolderSettingsDialog
|
||||
<FolderUpdateDialog
|
||||
folder={folderToSettings}
|
||||
isOpen={isSettingsFolderOpen}
|
||||
onOpenChange={(open: boolean) => {
|
||||
|
||||
@ -1432,7 +1432,6 @@ const updateDocument = async ({
|
||||
return await prisma.document.update({
|
||||
where: {
|
||||
id: documentId,
|
||||
userId,
|
||||
team: buildTeamWhereQuery({ teamId, userId }),
|
||||
},
|
||||
data: {
|
||||
|
||||
@ -168,7 +168,7 @@ test('[TEAMS]: can rename a document folder', async ({ page }) => {
|
||||
await page.getByRole('menuitem', { name: 'Settings' }).click();
|
||||
|
||||
await page.getByLabel('Name').fill('Team Archive');
|
||||
await page.getByRole('button', { name: 'Save Changes' }).click();
|
||||
await page.getByRole('button', { name: 'Update' }).click();
|
||||
|
||||
await expect(page.getByText('Team Archive')).toBeVisible();
|
||||
});
|
||||
@ -470,7 +470,7 @@ test('[TEAMS]: can rename a template folder', async ({ page }) => {
|
||||
await page.getByRole('menuitem', { name: 'Settings' }).click();
|
||||
|
||||
await page.getByLabel('Name').fill('Updated Team Template Folder');
|
||||
await page.getByRole('button', { name: 'Save Changes' }).click();
|
||||
await page.getByRole('button', { name: 'Update' }).click();
|
||||
|
||||
await expect(page.getByText('Updated Team Template Folder')).toBeVisible();
|
||||
});
|
||||
|
||||
@ -16,6 +16,7 @@ import { prefixedId } from '../../universal/id';
|
||||
import { getFileServerSide } from '../../universal/upload/get-file.server';
|
||||
import { putPdfFileServerSide } from '../../universal/upload/put-file.server';
|
||||
import { determineDocumentVisibility } from '../../utils/document-visibility';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
import { getTeamById } from '../team/get-team';
|
||||
import { getTeamSettings } from '../team/get-team-settings';
|
||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||
@ -58,8 +59,10 @@ export const createDocument = async ({
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
},
|
||||
select: {
|
||||
visibility: true,
|
||||
|
||||
@ -26,7 +26,6 @@ export const deleteField = async ({
|
||||
id: fieldId,
|
||||
document: {
|
||||
id: documentId,
|
||||
userId,
|
||||
team: buildTeamWhereQuery({ teamId, userId }),
|
||||
},
|
||||
},
|
||||
|
||||
@ -48,7 +48,6 @@ export const updateField = async ({
|
||||
id: fieldId,
|
||||
document: {
|
||||
id: documentId,
|
||||
userId,
|
||||
team: buildTeamWhereQuery({ teamId, userId }),
|
||||
},
|
||||
},
|
||||
|
||||
@ -4,6 +4,7 @@ import { match } from 'ts-pattern';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
import { getTeamById } from '../team/get-team';
|
||||
|
||||
export interface DeleteFolderOptions {
|
||||
@ -18,8 +19,10 @@ export const deleteFolder = async ({ userId, teamId, folderId }: DeleteFolderOpt
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
},
|
||||
include: {
|
||||
documents: true,
|
||||
|
||||
@ -2,6 +2,8 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export interface MoveFolderOptions {
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
@ -15,8 +17,10 @@ export const moveFolder = async ({ userId, teamId, folderId, parentId }: MoveFol
|
||||
const folder = await tx.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { FolderType } from '@documenso/lib/types/folder-type';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export interface MoveTemplateToFolderOptions {
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
@ -15,45 +17,47 @@ export const moveTemplateToFolder = async ({
|
||||
templateId,
|
||||
folderId,
|
||||
}: MoveTemplateToFolderOptions) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const template = await tx.template.findFirst({
|
||||
where: {
|
||||
id: templateId,
|
||||
userId,
|
||||
const template = await prisma.template.findFirst({
|
||||
where: {
|
||||
id: templateId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
},
|
||||
userId,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
if (!template) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
if (folderId !== null) {
|
||||
const folder = await tx.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
type: FolderType.TEMPLATE,
|
||||
},
|
||||
});
|
||||
|
||||
if (!folder) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Folder not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return await tx.template.update({
|
||||
if (folderId !== null) {
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: templateId,
|
||||
},
|
||||
data: {
|
||||
folderId,
|
||||
id: folderId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
type: FolderType.TEMPLATE,
|
||||
},
|
||||
});
|
||||
|
||||
if (!folder) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Folder not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return await prisma.template.update({
|
||||
where: {
|
||||
id: templateId,
|
||||
},
|
||||
data: {
|
||||
folderId,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import type { TFolderType } from '../../types/folder-type';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export interface PinFolderOptions {
|
||||
userId: number;
|
||||
@ -14,8 +15,10 @@ export const pinFolder = async ({ userId, teamId, folderId, type }: PinFolderOpt
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import type { TFolderType } from '../../types/folder-type';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export interface UnpinFolderOptions {
|
||||
userId: number;
|
||||
@ -14,8 +15,10 @@ export const unpinFolder = async ({ userId, teamId, folderId, type }: UnpinFolde
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
@ -4,6 +4,7 @@ import { DocumentVisibility } from '@documenso/prisma/generated/types';
|
||||
|
||||
import type { TFolderType } from '../../types/folder-type';
|
||||
import { FolderType } from '../../types/folder-type';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export interface UpdateFolderOptions {
|
||||
userId: number;
|
||||
@ -25,8 +26,10 @@ export const updateFolder = async ({
|
||||
const folder = await prisma.folder.findFirst({
|
||||
where: {
|
||||
id: folderId,
|
||||
userId,
|
||||
teamId,
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
type,
|
||||
},
|
||||
});
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
|
||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||
import { TEAM_MEMBER_ROLE_PERMISSIONS_MAP } from '@documenso/lib/constants/teams';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
export type CreateTeamBillingPortalOptions = {
|
||||
userId: number;
|
||||
teamId: number;
|
||||
};
|
||||
|
||||
export const createTeamBillingPortal = async ({
|
||||
userId,
|
||||
teamId,
|
||||
}: CreateTeamBillingPortalOptions) => {
|
||||
if (!IS_BILLING_ENABLED()) {
|
||||
throw new Error('Billing is not enabled');
|
||||
}
|
||||
|
||||
const team = await prisma.team.findFirstOrThrow({
|
||||
where: {
|
||||
id: teamId,
|
||||
members: {
|
||||
some: {
|
||||
userId,
|
||||
role: {
|
||||
in: TEAM_MEMBER_ROLE_PERMISSIONS_MAP['MANAGE_BILLING'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
subscription: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!team.subscription) {
|
||||
throw new Error('Team has no subscription');
|
||||
}
|
||||
|
||||
if (!team.customerId) {
|
||||
throw new Error('Team has no customerId');
|
||||
}
|
||||
|
||||
return getPortalSession({
|
||||
customerId: team.customerId,
|
||||
});
|
||||
};
|
||||
@ -2,6 +2,8 @@ import type { WebhookTriggerEvents } from '@prisma/client';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
|
||||
export type GetAllWebhooksByEventTriggerOptions = {
|
||||
event: WebhookTriggerEvents;
|
||||
userId: number;
|
||||
@ -19,22 +21,10 @@ export const getAllWebhooksByEventTrigger = async ({
|
||||
eventTriggers: {
|
||||
has: event,
|
||||
},
|
||||
team: {
|
||||
id: teamId,
|
||||
teamGroups: {
|
||||
some: {
|
||||
organisationGroup: {
|
||||
organisationGroupMembers: {
|
||||
some: {
|
||||
organisationMember: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
team: buildTeamWhereQuery({
|
||||
teamId,
|
||||
userId,
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Document" DROP CONSTRAINT "Document_folderId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Template" DROP CONSTRAINT "Template_folderId_fkey";
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Document" ADD CONSTRAINT "Document_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "Folder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Template" ADD CONSTRAINT "Template_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "Folder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@ -397,7 +397,7 @@ model Document {
|
||||
template Template? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
||||
|
||||
auditLogs DocumentAuditLog[]
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: Cascade)
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
|
||||
folderId String?
|
||||
|
||||
@@unique([documentDataId])
|
||||
@ -866,7 +866,7 @@ model Template {
|
||||
directLink TemplateDirectLink?
|
||||
documents Document[]
|
||||
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: Cascade)
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
|
||||
folderId String?
|
||||
|
||||
@@unique([templateDocumentDataId])
|
||||
|
||||
Reference in New Issue
Block a user