mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
feat: add organisations (#1820)
This commit is contained in:
@ -27,6 +27,7 @@ const examplePdf = fs
|
||||
|
||||
type DocumentToSeed = {
|
||||
sender: User;
|
||||
teamId: number;
|
||||
recipients: (User | string)[];
|
||||
type: DocumentStatus;
|
||||
documentOptions?: Partial<Prisma.DocumentUncheckedCreateInput>;
|
||||
@ -38,19 +39,19 @@ export const seedDocuments = async (documents: DocumentToSeed[]) => {
|
||||
documents.map(async (document, i) =>
|
||||
match(document.type)
|
||||
.with(DocumentStatus.DRAFT, async () =>
|
||||
seedDraftDocument(document.sender, document.recipients, {
|
||||
seedDraftDocument(document.sender, document.teamId, document.recipients, {
|
||||
key: i,
|
||||
createDocumentOptions: document.documentOptions,
|
||||
}),
|
||||
)
|
||||
.with(DocumentStatus.PENDING, async () =>
|
||||
seedPendingDocument(document.sender, document.recipients, {
|
||||
seedPendingDocument(document.sender, document.teamId, document.recipients, {
|
||||
key: i,
|
||||
createDocumentOptions: document.documentOptions,
|
||||
}),
|
||||
)
|
||||
.with(DocumentStatus.COMPLETED, async () =>
|
||||
seedCompletedDocument(document.sender, document.recipients, {
|
||||
seedCompletedDocument(document.sender, document.teamId, document.recipients, {
|
||||
key: i,
|
||||
createDocumentOptions: document.documentOptions,
|
||||
}),
|
||||
@ -59,7 +60,11 @@ export const seedDocuments = async (documents: DocumentToSeed[]) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const seedBlankDocument = async (owner: User, options: CreateDocumentOptions = {}) => {
|
||||
export const seedBlankDocument = async (
|
||||
owner: User,
|
||||
teamId: number,
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
const { key, createDocumentOptions = {} } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
@ -73,6 +78,7 @@ export const seedBlankDocument = async (owner: User, options: CreateDocumentOpti
|
||||
return await prisma.document.create({
|
||||
data: {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
teamId,
|
||||
title: `[TEST] Document ${key} - Draft`,
|
||||
status: DocumentStatus.DRAFT,
|
||||
documentDataId: documentData.id,
|
||||
@ -99,8 +105,23 @@ export const seedTeamDocumentWithMeta = async (team: Team) => {
|
||||
},
|
||||
});
|
||||
|
||||
const { organisation } = await prisma.team.findFirstOrThrow({
|
||||
where: {
|
||||
id: team.id,
|
||||
},
|
||||
include: {
|
||||
organisation: {
|
||||
include: {
|
||||
owner: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const ownerUser = organisation.owner;
|
||||
|
||||
const document = await createDocument({
|
||||
userId: team.ownerUserId,
|
||||
userId: ownerUser.id,
|
||||
teamId: team.id,
|
||||
title: `[TEST] Document ${nanoid(8)} - Draft`,
|
||||
documentDataId: documentData.id,
|
||||
@ -112,12 +133,6 @@ export const seedTeamDocumentWithMeta = async (team: Team) => {
|
||||
},
|
||||
});
|
||||
|
||||
const owner = await prisma.user.findFirstOrThrow({
|
||||
where: {
|
||||
id: team.ownerUserId,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.document.update({
|
||||
where: {
|
||||
id: document.id,
|
||||
@ -129,8 +144,8 @@ export const seedTeamDocumentWithMeta = async (team: Team) => {
|
||||
|
||||
await prisma.recipient.create({
|
||||
data: {
|
||||
email: owner.email,
|
||||
name: owner.name ?? '',
|
||||
email: ownerUser.email,
|
||||
name: ownerUser.name ?? '',
|
||||
token: nanoid(),
|
||||
readStatus: ReadStatus.OPENED,
|
||||
sendStatus: SendStatus.SENT,
|
||||
@ -176,23 +191,32 @@ export const seedTeamTemplateWithMeta = async (team: Team) => {
|
||||
},
|
||||
});
|
||||
|
||||
const { organisation } = await prisma.team.findFirstOrThrow({
|
||||
where: {
|
||||
id: team.id,
|
||||
},
|
||||
include: {
|
||||
organisation: {
|
||||
include: {
|
||||
owner: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const ownerUser = organisation.owner;
|
||||
|
||||
const template = await createTemplate({
|
||||
title: `[TEST] Template ${nanoid(8)} - Draft`,
|
||||
userId: team.ownerUserId,
|
||||
userId: ownerUser.id,
|
||||
teamId: team.id,
|
||||
templateDocumentDataId: documentData.id,
|
||||
});
|
||||
|
||||
const owner = await prisma.user.findFirstOrThrow({
|
||||
where: {
|
||||
id: team.ownerUserId,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.recipient.create({
|
||||
data: {
|
||||
email: owner.email,
|
||||
name: owner.name ?? '',
|
||||
email: ownerUser.email,
|
||||
name: ownerUser.name ?? '',
|
||||
token: nanoid(),
|
||||
readStatus: ReadStatus.OPENED,
|
||||
sendStatus: SendStatus.SENT,
|
||||
@ -231,6 +255,7 @@ export const seedTeamTemplateWithMeta = async (team: Team) => {
|
||||
|
||||
export const seedDraftDocument = async (
|
||||
sender: User,
|
||||
teamId: number,
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
@ -247,6 +272,7 @@ export const seedDraftDocument = async (
|
||||
const document = await prisma.document.create({
|
||||
data: {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
teamId,
|
||||
title: `[TEST] Document ${key} - Draft`,
|
||||
status: DocumentStatus.DRAFT,
|
||||
documentDataId: documentData.id,
|
||||
@ -300,6 +326,7 @@ type CreateDocumentOptions = {
|
||||
|
||||
export const seedPendingDocument = async (
|
||||
sender: User,
|
||||
teamId: number,
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
@ -316,6 +343,7 @@ export const seedPendingDocument = async (
|
||||
const document = await prisma.document.create({
|
||||
data: {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
teamId,
|
||||
title: `[TEST] Document ${key} - Pending`,
|
||||
status: DocumentStatus.PENDING,
|
||||
documentDataId: documentData.id,
|
||||
@ -372,13 +400,15 @@ export const seedPendingDocument = async (
|
||||
export const seedPendingDocumentNoFields = async ({
|
||||
owner,
|
||||
recipients,
|
||||
teamId,
|
||||
updateDocumentOptions,
|
||||
}: {
|
||||
owner: User;
|
||||
recipients: (User | string)[];
|
||||
teamId: number;
|
||||
updateDocumentOptions?: Partial<Prisma.DocumentUncheckedUpdateInput>;
|
||||
}) => {
|
||||
const document: Document = await seedBlankDocument(owner);
|
||||
const document: Document = await seedBlankDocument(owner, teamId);
|
||||
|
||||
for (const recipient of recipients) {
|
||||
const email = typeof recipient === 'string' ? recipient : recipient.email;
|
||||
@ -432,14 +462,16 @@ export const seedPendingDocumentWithFullFields = async ({
|
||||
recipientsCreateOptions,
|
||||
updateDocumentOptions,
|
||||
fields = [FieldType.DATE, FieldType.EMAIL, FieldType.NAME, FieldType.SIGNATURE, FieldType.TEXT],
|
||||
teamId,
|
||||
}: {
|
||||
owner: User;
|
||||
recipients: (User | string)[];
|
||||
recipientsCreateOptions?: Partial<Prisma.RecipientCreateInput>[];
|
||||
updateDocumentOptions?: Partial<Prisma.DocumentUncheckedUpdateInput>;
|
||||
fields?: FieldType[];
|
||||
teamId: number;
|
||||
}) => {
|
||||
const document: Document = await seedBlankDocument(owner);
|
||||
const document: Document = await seedBlankDocument(owner, teamId);
|
||||
|
||||
for (const [recipientIndex, recipient] of recipients.entries()) {
|
||||
const email = typeof recipient === 'string' ? recipient : recipient.email;
|
||||
@ -509,6 +541,7 @@ export const seedPendingDocumentWithFullFields = async ({
|
||||
|
||||
export const seedCompletedDocument = async (
|
||||
sender: User,
|
||||
teamId: number,
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
@ -525,6 +558,7 @@ export const seedCompletedDocument = async (
|
||||
const document = await prisma.document.create({
|
||||
data: {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
teamId,
|
||||
title: `[TEST] Document ${key} - Completed`,
|
||||
status: DocumentStatus.COMPLETED,
|
||||
documentDataId: documentData.id,
|
||||
@ -597,7 +631,7 @@ export const seedCompletedDocument = async (
|
||||
* - 5 All
|
||||
*/
|
||||
export const seedTeamDocuments = async () => {
|
||||
const team = await seedTeam({
|
||||
const { team, owner, organisation } = await seedTeam({
|
||||
createTeamMembers: 4,
|
||||
});
|
||||
|
||||
@ -605,17 +639,17 @@ export const seedTeamDocuments = async () => {
|
||||
teamId: team.id,
|
||||
};
|
||||
|
||||
const teamMember1 = team.members[1].user;
|
||||
const teamMember2 = team.members[2].user;
|
||||
const teamMember3 = team.members[3].user;
|
||||
const teamMember4 = team.members[4].user;
|
||||
const teamMember1 = organisation.members[1].user;
|
||||
const teamMember2 = organisation.members[2].user;
|
||||
const teamMember3 = organisation.members[3].user;
|
||||
const teamMember4 = organisation.members[4].user;
|
||||
|
||||
const [testUser1, testUser2, testUser3, testUser4] = await Promise.all([
|
||||
seedUser(),
|
||||
seedUser(),
|
||||
seedUser(),
|
||||
seedUser(),
|
||||
]);
|
||||
const [
|
||||
{ user: testUser1, team: testUser1Team },
|
||||
{ user: testUser2, team: testUser2Team },
|
||||
{ user: testUser3, team: testUser3Team },
|
||||
{ user: testUser4, team: testUser4Team },
|
||||
] = await Promise.all([seedUser(), seedUser(), seedUser(), seedUser()]);
|
||||
|
||||
await seedDocuments([
|
||||
/**
|
||||
@ -623,30 +657,35 @@ export const seedTeamDocuments = async () => {
|
||||
*/
|
||||
{
|
||||
sender: teamMember1,
|
||||
teamId: team.id,
|
||||
recipients: [testUser1, testUser2],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
documentOptions,
|
||||
},
|
||||
{
|
||||
sender: teamMember2,
|
||||
teamId: team.id,
|
||||
recipients: [testUser1],
|
||||
type: DocumentStatus.PENDING,
|
||||
documentOptions,
|
||||
},
|
||||
{
|
||||
sender: teamMember2,
|
||||
teamId: team.id,
|
||||
recipients: [testUser1, testUser2, testUser3, testUser4],
|
||||
type: DocumentStatus.PENDING,
|
||||
documentOptions,
|
||||
},
|
||||
{
|
||||
sender: teamMember2,
|
||||
teamId: team.id,
|
||||
recipients: [testUser1, testUser2, teamMember1],
|
||||
type: DocumentStatus.DRAFT,
|
||||
documentOptions,
|
||||
},
|
||||
{
|
||||
sender: team.owner,
|
||||
sender: owner,
|
||||
teamId: team.id,
|
||||
recipients: [testUser1, testUser2],
|
||||
type: DocumentStatus.DRAFT,
|
||||
documentOptions,
|
||||
@ -656,16 +695,19 @@ export const seedTeamDocuments = async () => {
|
||||
*/
|
||||
{
|
||||
sender: teamMember1,
|
||||
teamId: testUser3Team.id, // Not sure.
|
||||
recipients: [testUser1, testUser2],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
},
|
||||
{
|
||||
sender: teamMember2,
|
||||
teamId: testUser3Team.id, // Not sure.
|
||||
recipients: [testUser1],
|
||||
type: DocumentStatus.PENDING,
|
||||
},
|
||||
{
|
||||
sender: teamMember3,
|
||||
teamId: testUser3Team.id, // Not sure.
|
||||
recipients: [testUser1, testUser2],
|
||||
type: DocumentStatus.DRAFT,
|
||||
},
|
||||
@ -674,16 +716,19 @@ export const seedTeamDocuments = async () => {
|
||||
*/
|
||||
{
|
||||
sender: testUser1,
|
||||
teamId: testUser1Team.id,
|
||||
recipients: [teamMember1, teamMember2],
|
||||
type: DocumentStatus.COMPLETED,
|
||||
},
|
||||
{
|
||||
sender: testUser2,
|
||||
teamId: testUser2Team.id,
|
||||
recipients: [teamMember1],
|
||||
type: DocumentStatus.PENDING,
|
||||
},
|
||||
{
|
||||
sender: testUser3,
|
||||
teamId: testUser3Team.id,
|
||||
recipients: [teamMember1, teamMember2],
|
||||
type: DocumentStatus.DRAFT,
|
||||
},
|
||||
@ -691,6 +736,7 @@ export const seedTeamDocuments = async () => {
|
||||
|
||||
return {
|
||||
team,
|
||||
teamOwner: owner,
|
||||
teamMember1,
|
||||
teamMember2,
|
||||
teamMember3,
|
||||
|
||||
@ -1,33 +1,26 @@
|
||||
import type { User } from '@prisma/client';
|
||||
import { DocumentStatus, FolderType } from '@prisma/client';
|
||||
import { FolderType } from '@prisma/client';
|
||||
|
||||
import { prisma } from '..';
|
||||
import type { Prisma } from '../client';
|
||||
import { seedDocuments } from './documents';
|
||||
|
||||
type CreateFolderOptions = {
|
||||
type?: string;
|
||||
createFolderOptions?: Partial<Prisma.FolderUncheckedCreateInput>;
|
||||
};
|
||||
|
||||
export const seedBlankFolder = async (user: User, options: CreateFolderOptions = {}) => {
|
||||
export const seedBlankFolder = async (
|
||||
user: User,
|
||||
teamId: number,
|
||||
options: CreateFolderOptions = {},
|
||||
) => {
|
||||
return await prisma.folder.create({
|
||||
data: {
|
||||
name: 'My folder',
|
||||
userId: user.id,
|
||||
teamId,
|
||||
type: FolderType.DOCUMENT,
|
||||
...options.createFolderOptions,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const seedFolderWithDocuments = async (user: User, options: CreateFolderOptions = {}) => {
|
||||
const folder = await seedBlankFolder(user, options);
|
||||
await seedDocuments([
|
||||
{
|
||||
sender: user,
|
||||
recipients: [user],
|
||||
type: DocumentStatus.DRAFT,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { hashSync } from '@documenso/lib/server-only/auth/hash';
|
||||
|
||||
import { prisma } from '..';
|
||||
import { DocumentDataType, DocumentSource, Role, TeamMemberRole } from '../client';
|
||||
import { DocumentDataType, DocumentSource } from '../client';
|
||||
import { seedPendingDocument } from './documents';
|
||||
import { seedDirectTemplate, seedTemplate } from './templates';
|
||||
import { seedUser } from './users';
|
||||
|
||||
const createDocumentData = async ({ documentData }: { documentData: string }) => {
|
||||
return prisma.documentData.create({
|
||||
@ -23,32 +22,31 @@ export const seedDatabase = async () => {
|
||||
.readFileSync(path.join(__dirname, '../../../assets/example.pdf'))
|
||||
.toString('base64');
|
||||
|
||||
const exampleUser = await prisma.user.upsert({
|
||||
const exampleUserExists = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: 'example@documenso.com',
|
||||
},
|
||||
create: {
|
||||
name: 'Example User',
|
||||
email: 'example@documenso.com',
|
||||
emailVerified: new Date(),
|
||||
password: hashSync('password'),
|
||||
roles: [Role.USER],
|
||||
},
|
||||
update: {},
|
||||
});
|
||||
|
||||
const adminUser = await prisma.user.upsert({
|
||||
const adminUserExists = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: 'admin@documenso.com',
|
||||
},
|
||||
create: {
|
||||
name: 'Admin User',
|
||||
email: 'admin@documenso.com',
|
||||
emailVerified: new Date(),
|
||||
password: hashSync('password'),
|
||||
roles: [Role.USER, Role.ADMIN],
|
||||
},
|
||||
update: {},
|
||||
});
|
||||
|
||||
if (exampleUserExists || adminUserExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
const exampleUser = await seedUser({
|
||||
name: 'Example User',
|
||||
email: 'example@documenso.com',
|
||||
});
|
||||
|
||||
const adminUser = await seedUser({
|
||||
name: 'Admin User',
|
||||
email: 'admin@documenso.com',
|
||||
isAdmin: true,
|
||||
});
|
||||
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
@ -59,11 +57,12 @@ export const seedDatabase = async () => {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
title: `Example Document ${i}`,
|
||||
documentDataId: documentData.id,
|
||||
userId: exampleUser.id,
|
||||
userId: exampleUser.user.id,
|
||||
teamId: exampleUser.team.id,
|
||||
recipients: {
|
||||
create: {
|
||||
name: String(adminUser.name),
|
||||
email: adminUser.email,
|
||||
name: String(adminUser.user.name),
|
||||
email: adminUser.user.email,
|
||||
token: Math.random().toString(36).slice(2, 9),
|
||||
},
|
||||
},
|
||||
@ -79,11 +78,12 @@ export const seedDatabase = async () => {
|
||||
source: DocumentSource.DOCUMENT,
|
||||
title: `Document ${i}`,
|
||||
documentDataId: documentData.id,
|
||||
userId: adminUser.id,
|
||||
userId: adminUser.user.id,
|
||||
teamId: adminUser.team.id,
|
||||
recipients: {
|
||||
create: {
|
||||
name: String(exampleUser.name),
|
||||
email: exampleUser.email,
|
||||
name: String(exampleUser.user.name),
|
||||
email: exampleUser.user.email,
|
||||
token: Math.random().toString(36).slice(2, 9),
|
||||
},
|
||||
},
|
||||
@ -91,14 +91,14 @@ export const seedDatabase = async () => {
|
||||
});
|
||||
}
|
||||
|
||||
await seedPendingDocument(exampleUser, [adminUser], {
|
||||
await seedPendingDocument(exampleUser.user, exampleUser.team.id, [adminUser.user], {
|
||||
key: 'example-pending',
|
||||
createDocumentOptions: {
|
||||
title: 'Pending Document',
|
||||
},
|
||||
});
|
||||
|
||||
await seedPendingDocument(adminUser, [exampleUser], {
|
||||
await seedPendingDocument(adminUser.user, adminUser.team.id, [exampleUser.user], {
|
||||
key: 'admin-pending',
|
||||
createDocumentOptions: {
|
||||
title: 'Pending Document',
|
||||
@ -108,80 +108,24 @@ export const seedDatabase = async () => {
|
||||
await Promise.all([
|
||||
seedTemplate({
|
||||
title: 'Template 1',
|
||||
userId: exampleUser.id,
|
||||
userId: exampleUser.user.id,
|
||||
teamId: exampleUser.team.id,
|
||||
}),
|
||||
seedDirectTemplate({
|
||||
title: 'Direct Template 1',
|
||||
userId: exampleUser.id,
|
||||
userId: exampleUser.user.id,
|
||||
teamId: exampleUser.team.id,
|
||||
}),
|
||||
|
||||
seedTemplate({
|
||||
title: 'Template 1',
|
||||
userId: adminUser.id,
|
||||
userId: adminUser.user.id,
|
||||
teamId: adminUser.team.id,
|
||||
}),
|
||||
seedDirectTemplate({
|
||||
title: 'Direct Template 1',
|
||||
userId: adminUser.id,
|
||||
userId: adminUser.user.id,
|
||||
teamId: adminUser.team.id,
|
||||
}),
|
||||
]);
|
||||
|
||||
const testUsers = [
|
||||
'test@documenso.com',
|
||||
'test2@documenso.com',
|
||||
'test3@documenso.com',
|
||||
'test4@documenso.com',
|
||||
];
|
||||
|
||||
const createdUsers = [];
|
||||
|
||||
for (const email of testUsers) {
|
||||
const testUser = await prisma.user.upsert({
|
||||
where: {
|
||||
email: email,
|
||||
},
|
||||
create: {
|
||||
name: 'Test User',
|
||||
email: email,
|
||||
emailVerified: new Date(),
|
||||
password: hashSync('password'),
|
||||
roles: [Role.USER],
|
||||
},
|
||||
update: {},
|
||||
});
|
||||
|
||||
createdUsers.push(testUser);
|
||||
}
|
||||
|
||||
const team1 = await prisma.team.create({
|
||||
data: {
|
||||
name: 'Team 1',
|
||||
url: 'team1',
|
||||
ownerUserId: createdUsers[0].id,
|
||||
},
|
||||
});
|
||||
|
||||
const team2 = await prisma.team.create({
|
||||
data: {
|
||||
name: 'Team 2',
|
||||
url: 'team2',
|
||||
ownerUserId: createdUsers[1].id,
|
||||
},
|
||||
});
|
||||
|
||||
for (const team of [team1, team2]) {
|
||||
await prisma.teamMember.createMany({
|
||||
data: [
|
||||
{
|
||||
teamId: team.id,
|
||||
userId: createdUsers[1].id,
|
||||
role: TeamMemberRole.ADMIN,
|
||||
},
|
||||
{
|
||||
teamId: team.id,
|
||||
userId: createdUsers[2].id,
|
||||
role: TeamMemberRole.MEMBER,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
101
packages/prisma/seed/organisations.ts
Normal file
101
packages/prisma/seed/organisations.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import type { OrganisationMemberRole, OrganisationType } from '@prisma/client';
|
||||
import { OrganisationMemberInviteStatus, type User } from '@prisma/client';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { hashSync } from '@documenso/lib/server-only/auth/hash';
|
||||
import { acceptOrganisationInvitation } from '@documenso/lib/server-only/organisation/accept-organisation-invitation';
|
||||
import { prefixedId } from '@documenso/lib/universal/id';
|
||||
|
||||
import { prisma } from '..';
|
||||
import { seedTestEmail } from './users';
|
||||
|
||||
export const seedOrganisationMembers = async ({
|
||||
members,
|
||||
organisationId,
|
||||
}: {
|
||||
members: {
|
||||
email?: string;
|
||||
name?: string;
|
||||
organisationRole: OrganisationMemberRole;
|
||||
}[];
|
||||
organisationId: string;
|
||||
}) => {
|
||||
const membersToInvite: {
|
||||
email: string;
|
||||
organisationRole: OrganisationMemberRole;
|
||||
}[] = [];
|
||||
|
||||
const createdMembers: User[] = [];
|
||||
|
||||
for (const member of members) {
|
||||
const email = member.email ?? seedTestEmail();
|
||||
|
||||
let newUser = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: email.toLowerCase(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!newUser) {
|
||||
newUser = await prisma.user.create({
|
||||
data: {
|
||||
name: member.name ?? 'Test user',
|
||||
email: email.toLowerCase(),
|
||||
password: hashSync('password'),
|
||||
emailVerified: new Date(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
createdMembers.push(newUser);
|
||||
|
||||
membersToInvite.push({
|
||||
email: newUser.email,
|
||||
organisationRole: member.organisationRole,
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.organisationMemberInvite.createMany({
|
||||
data: membersToInvite.map((invite) => ({
|
||||
id: prefixedId('member_invite'),
|
||||
email: invite.email,
|
||||
organisationId,
|
||||
organisationRole: invite.organisationRole,
|
||||
token: nanoid(32),
|
||||
})),
|
||||
});
|
||||
|
||||
const invites = await prisma.organisationMemberInvite.findMany({
|
||||
where: {
|
||||
organisationId,
|
||||
status: OrganisationMemberInviteStatus.PENDING,
|
||||
},
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
invites.map(async (invite) => {
|
||||
await acceptOrganisationInvitation({
|
||||
token: invite.token,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
return createdMembers;
|
||||
};
|
||||
|
||||
export const setOrganisationType = async ({
|
||||
organisationId,
|
||||
type,
|
||||
}: {
|
||||
organisationId: string;
|
||||
type: OrganisationType;
|
||||
}) => {
|
||||
await prisma.organisation.update({
|
||||
where: {
|
||||
id: organisationId,
|
||||
},
|
||||
data: {
|
||||
type,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -1,19 +0,0 @@
|
||||
import { prisma } from '..';
|
||||
|
||||
export const seedTestEmail = () => `user-${Date.now()}@test.documenso.com`;
|
||||
|
||||
type SeedSubscriptionOptions = {
|
||||
userId: number;
|
||||
priceId: string;
|
||||
};
|
||||
|
||||
export const seedUserSubscription = async ({ userId, priceId }: SeedSubscriptionOptions) => {
|
||||
return await prisma.subscription.create({
|
||||
data: {
|
||||
userId,
|
||||
planId: Date.now().toString(),
|
||||
priceId,
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -1,8 +1,11 @@
|
||||
import { customAlphabet } from 'nanoid';
|
||||
|
||||
import { createTeamMembers } from '@documenso/trpc/server/team-router/create-team-members';
|
||||
|
||||
import { prisma } from '..';
|
||||
import type { Prisma } from '../client';
|
||||
import { TeamMemberInviteStatus, TeamMemberRole } from '../client';
|
||||
import { OrganisationMemberRole, TeamMemberRole } from '../client';
|
||||
import { seedOrganisationMembers } from './organisations';
|
||||
import { seedUser } from './users';
|
||||
|
||||
const EMAIL_DOMAIN = `test.documenso.com`;
|
||||
@ -19,63 +22,54 @@ export const seedTeam = async ({
|
||||
createTeamEmail,
|
||||
createTeamOptions = {},
|
||||
}: SeedTeamOptions = {}) => {
|
||||
const teamUrl = `team-${nanoid()}`;
|
||||
const teamEmail = createTeamEmail === true ? `${teamUrl}@${EMAIL_DOMAIN}` : createTeamEmail;
|
||||
|
||||
const teamOwner = await seedUser({
|
||||
name: `${teamUrl}-original-owner`,
|
||||
email: `${teamUrl}-original-owner@${EMAIL_DOMAIN}`,
|
||||
const {
|
||||
user: owner,
|
||||
team: seededTeam,
|
||||
organisation: seededOrganisation,
|
||||
} = await seedUser({
|
||||
name: 'Owner',
|
||||
teamEmail: createTeamEmail === true ? `${nanoid()}@${EMAIL_DOMAIN}` : createTeamEmail,
|
||||
});
|
||||
|
||||
const teamMembers = await Promise.all(
|
||||
Array.from({ length: createTeamMembers }).map(async (_, i) => {
|
||||
return seedUser({
|
||||
name: `${teamUrl}-member-${i + 1}`,
|
||||
email: `${teamUrl}-member-${i + 1}@${EMAIL_DOMAIN}`,
|
||||
});
|
||||
}),
|
||||
);
|
||||
const teamUrl = seededTeam.url;
|
||||
|
||||
const team = await prisma.team.create({
|
||||
data: {
|
||||
name: teamUrl,
|
||||
url: teamUrl,
|
||||
ownerUserId: teamOwner.id,
|
||||
members: {
|
||||
createMany: {
|
||||
data: [teamOwner, ...teamMembers].map((user) => ({
|
||||
userId: user.id,
|
||||
role: user === teamOwner ? TeamMemberRole.ADMIN : TeamMemberRole.MEMBER,
|
||||
})),
|
||||
},
|
||||
},
|
||||
teamEmail: teamEmail
|
||||
? {
|
||||
create: {
|
||||
email: teamEmail,
|
||||
name: teamEmail,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
...createTeamOptions,
|
||||
},
|
||||
await seedOrganisationMembers({
|
||||
members: Array.from({ length: createTeamMembers }).map((_, i) => ({
|
||||
name: `${teamUrl}-member-${i + 1}`,
|
||||
email: `${teamUrl}-member-${i + 1}@${EMAIL_DOMAIN}`,
|
||||
organisationRole: OrganisationMemberRole.MEMBER,
|
||||
})),
|
||||
organisationId: seededOrganisation.id,
|
||||
});
|
||||
|
||||
return await prisma.team.findFirstOrThrow({
|
||||
const team = await prisma.team.findFirstOrThrow({
|
||||
where: {
|
||||
id: team.id,
|
||||
id: seededTeam.id,
|
||||
},
|
||||
include: {
|
||||
teamEmail: true,
|
||||
teamGlobalSettings: true,
|
||||
},
|
||||
});
|
||||
|
||||
const organisation = await prisma.organisation.findFirstOrThrow({
|
||||
where: {
|
||||
id: seededOrganisation.id,
|
||||
},
|
||||
include: {
|
||||
owner: true,
|
||||
members: {
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
},
|
||||
teamEmail: true,
|
||||
teamGlobalSettings: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
owner,
|
||||
team,
|
||||
organisation,
|
||||
};
|
||||
};
|
||||
|
||||
export const unseedTeam = async (teamUrl: string) => {
|
||||
@ -83,9 +77,6 @@ export const unseedTeam = async (teamUrl: string) => {
|
||||
where: {
|
||||
url: teamUrl,
|
||||
},
|
||||
include: {
|
||||
members: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
@ -97,14 +88,6 @@ export const unseedTeam = async (teamUrl: string) => {
|
||||
url: teamUrl,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
id: {
|
||||
in: team.members.map((member) => member.userId),
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
type SeedTeamMemberOptions = {
|
||||
@ -118,48 +101,49 @@ export const seedTeamMember = async ({
|
||||
name,
|
||||
role = TeamMemberRole.ADMIN,
|
||||
}: SeedTeamMemberOptions) => {
|
||||
const user = await seedUser({ name });
|
||||
const { user } = await seedUser({ name });
|
||||
|
||||
await prisma.teamMember.create({
|
||||
data: {
|
||||
teamId,
|
||||
role,
|
||||
userId: user.id,
|
||||
const team = await prisma.team.findFirstOrThrow({
|
||||
where: {
|
||||
id: teamId,
|
||||
},
|
||||
include: {
|
||||
organisation: true,
|
||||
},
|
||||
});
|
||||
|
||||
await seedOrganisationMembers({
|
||||
members: [
|
||||
{
|
||||
name: user.name ?? '',
|
||||
email: user.email,
|
||||
organisationRole: OrganisationMemberRole.MEMBER,
|
||||
},
|
||||
],
|
||||
organisationId: team.organisationId,
|
||||
});
|
||||
|
||||
const { id: organisationMemberId } = await prisma.organisationMember.findFirstOrThrow({
|
||||
where: {
|
||||
userId: user.id,
|
||||
organisationId: team.organisationId,
|
||||
},
|
||||
});
|
||||
|
||||
await createTeamMembers({
|
||||
userId: team.organisation.ownerUserId,
|
||||
teamId,
|
||||
membersToCreate: [
|
||||
{
|
||||
organisationMemberId,
|
||||
teamRole: role,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
type UnseedTeamMemberOptions = {
|
||||
teamId: number;
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export const unseedTeamMember = async ({ teamId, userId }: UnseedTeamMemberOptions) => {
|
||||
await prisma.teamMember.delete({
|
||||
where: {
|
||||
userId_teamId: {
|
||||
userId,
|
||||
teamId,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const seedTeamTransfer = async (options: { newOwnerUserId: number; teamId: number }) => {
|
||||
return await prisma.teamTransferVerification.create({
|
||||
data: {
|
||||
teamId: options.teamId,
|
||||
token: Date.now().toString(),
|
||||
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24),
|
||||
userId: options.newOwnerUserId,
|
||||
name: '',
|
||||
email: '',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const seedTeamEmail = async ({ email, teamId }: { email: string; teamId: number }) => {
|
||||
return await prisma.teamEmail.create({
|
||||
data: {
|
||||
@ -178,26 +162,6 @@ export const unseedTeamEmail = async ({ teamId }: { teamId: number }) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const seedTeamInvite = async ({
|
||||
email,
|
||||
teamId,
|
||||
role = TeamMemberRole.ADMIN,
|
||||
}: {
|
||||
email: string;
|
||||
teamId: number;
|
||||
role?: TeamMemberRole;
|
||||
}) => {
|
||||
return await prisma.teamMemberInvite.create({
|
||||
data: {
|
||||
email,
|
||||
teamId,
|
||||
role,
|
||||
status: TeamMemberInviteStatus.PENDING,
|
||||
token: Date.now().toString(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const seedTeamEmailVerification = async ({
|
||||
email,
|
||||
teamId,
|
||||
|
||||
@ -17,7 +17,7 @@ const examplePdf = fs
|
||||
type SeedTemplateOptions = {
|
||||
title?: string;
|
||||
userId: number;
|
||||
teamId?: number;
|
||||
teamId: number;
|
||||
createTemplateOptions?: Partial<Prisma.TemplateCreateInput>;
|
||||
};
|
||||
|
||||
@ -26,7 +26,11 @@ type CreateTemplateOptions = {
|
||||
createTemplateOptions?: Partial<Prisma.TemplateUncheckedCreateInput>;
|
||||
};
|
||||
|
||||
export const seedBlankTemplate = async (owner: User, options: CreateTemplateOptions = {}) => {
|
||||
export const seedBlankTemplate = async (
|
||||
owner: User,
|
||||
teamId: number,
|
||||
options: CreateTemplateOptions = {},
|
||||
) => {
|
||||
const { key, createTemplateOptions = {} } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
@ -40,6 +44,7 @@ export const seedBlankTemplate = async (owner: User, options: CreateTemplateOpti
|
||||
return await prisma.template.create({
|
||||
data: {
|
||||
title: `[TEST] Template ${key}`,
|
||||
teamId,
|
||||
templateDocumentDataId: documentData.id,
|
||||
userId: owner.id,
|
||||
...createTemplateOptions,
|
||||
@ -82,15 +87,11 @@ export const seedTemplate = async (options: SeedTemplateOptions) => {
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
},
|
||||
...(teamId
|
||||
? {
|
||||
team: {
|
||||
connect: {
|
||||
id: teamId,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
team: {
|
||||
connect: {
|
||||
id: teamId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -126,15 +127,11 @@ export const seedDirectTemplate = async (options: SeedTemplateOptions) => {
|
||||
token: Math.random().toString().slice(2, 7),
|
||||
},
|
||||
},
|
||||
...(teamId
|
||||
? {
|
||||
team: {
|
||||
connect: {
|
||||
id: teamId,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
team: {
|
||||
connect: {
|
||||
id: teamId,
|
||||
},
|
||||
},
|
||||
...options.createTemplateOptions,
|
||||
},
|
||||
include: {
|
||||
|
||||
@ -1,14 +1,22 @@
|
||||
import { OrganisationType, Role } from '@prisma/client';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
|
||||
import { hashSync } from '@documenso/lib/server-only/auth/hash';
|
||||
import { createPersonalOrganisation } from '@documenso/lib/server-only/organisation/create-organisation';
|
||||
|
||||
import { prisma } from '..';
|
||||
import { setOrganisationType } from './organisations';
|
||||
|
||||
type SeedUserOptions = {
|
||||
name?: string;
|
||||
email?: string;
|
||||
password?: string;
|
||||
verified?: boolean;
|
||||
setTeamEmailAsOwner?: boolean;
|
||||
teamEmail?: string;
|
||||
inheritMembers?: boolean;
|
||||
isAdmin?: boolean;
|
||||
isPersonalOrganisation?: boolean;
|
||||
};
|
||||
|
||||
const nanoid = customAlphabet('1234567890abcdef', 10);
|
||||
@ -16,33 +24,77 @@ const nanoid = customAlphabet('1234567890abcdef', 10);
|
||||
export const seedTestEmail = () => `${nanoid()}@test.documenso.com`;
|
||||
|
||||
export const seedUser = async ({
|
||||
name,
|
||||
name = nanoid(),
|
||||
email,
|
||||
password = 'password',
|
||||
verified = true,
|
||||
setTeamEmailAsOwner = false,
|
||||
teamEmail = '',
|
||||
inheritMembers = true,
|
||||
isAdmin = false,
|
||||
isPersonalOrganisation = false,
|
||||
}: SeedUserOptions = {}) => {
|
||||
let url = name;
|
||||
|
||||
if (name) {
|
||||
url = nanoid();
|
||||
} else {
|
||||
name = nanoid();
|
||||
url = name;
|
||||
}
|
||||
|
||||
if (!email) {
|
||||
email = `${nanoid()}@test.documenso.com`;
|
||||
}
|
||||
|
||||
return await prisma.user.create({
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
email: email.toLowerCase(),
|
||||
password: hashSync(password),
|
||||
emailVerified: verified ? new Date() : undefined,
|
||||
url,
|
||||
roles: isAdmin ? [Role.USER, Role.ADMIN] : [Role.USER],
|
||||
},
|
||||
});
|
||||
|
||||
await createPersonalOrganisation({
|
||||
userId: user.id,
|
||||
inheritMembers,
|
||||
type: isPersonalOrganisation ? OrganisationType.PERSONAL : OrganisationType.ORGANISATION,
|
||||
});
|
||||
|
||||
const organisation = await prisma.organisation.findFirstOrThrow({
|
||||
where: {
|
||||
ownerUserId: user.id,
|
||||
},
|
||||
include: {
|
||||
teams: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (setTeamEmailAsOwner) {
|
||||
await prisma.teamEmail.create({
|
||||
data: {
|
||||
name: '',
|
||||
teamId: organisation.teams[0].id,
|
||||
email: user.email,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (teamEmail) {
|
||||
await prisma.teamEmail.create({
|
||||
data: {
|
||||
name: '',
|
||||
teamId: organisation.teams[0].id,
|
||||
email: teamEmail,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!isPersonalOrganisation) {
|
||||
await setOrganisationType({
|
||||
organisationId: organisation.id,
|
||||
type: OrganisationType.ORGANISATION,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
organisation,
|
||||
team: organisation.teams[0],
|
||||
};
|
||||
};
|
||||
|
||||
export const unseedUser = async (userId: number) => {
|
||||
|
||||
Reference in New Issue
Block a user