diff --git a/prisma/migrations/20230714171654_/migration.sql b/prisma/migrations/20230714171654_/migration.sql new file mode 100644 index 000000000..c4e62cd07 --- /dev/null +++ b/prisma/migrations/20230714171654_/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - Made the column `priority` on table `Goal` required. This step will fail if there are existing NULL values in that column. + +*/ +-- DropIndex +DROP INDEX "Flow_title_key"; + +-- AlterTable +ALTER TABLE "Goal" ALTER COLUMN "priority" SET NOT NULL; diff --git a/prisma/migrations/20230714181336_/migration.sql b/prisma/migrations/20230714181336_/migration.sql new file mode 100644 index 000000000..d0a14b355 --- /dev/null +++ b/prisma/migrations/20230714181336_/migration.sql @@ -0,0 +1,24 @@ +/* + Warnings: + + - A unique constraint covering the columns `[title]` on the table `Flow` will be added. If there are existing duplicate values, this will fail. + - Added the required column `priorityId` to the `Goal` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Goal" ADD COLUMN "priorityId" INTEGER NOT NULL; + +-- CreateTable +CREATE TABLE "Priority" ( + "id" SERIAL NOT NULL, + "title" TEXT NOT NULL, + "value" INTEGER NOT NULL, + + CONSTRAINT "Priority_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Flow_title_key" ON "Flow"("title"); + +-- AddForeignKey +ALTER TABLE "Goal" ADD CONSTRAINT "Goal_priorityId_fkey" FOREIGN KEY ("priorityId") REFERENCES "Priority"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 4fe0d6b05..1776f03c6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -184,6 +184,13 @@ model EstimateToGoal { @@index([estimateId]) } +model Priority { + id Int @id @default(autoincrement()) + title String + value Int + Goal Goal[] +} + model Goal { id String @id @default(cuid()) scopeId Int @default(1) @@ -194,7 +201,9 @@ model Goal { personal Boolean? private Boolean? archived Boolean? @default(false) - priority String? + priority String + priorityExact Priority @relation(fields: [priorityId], references: [id]) + priorityId Int estimate EstimateToGoal[] project Project? @relation("projectGoals", fields: [projectId], references: [id]) projectId String? @@ -219,8 +228,8 @@ model Goal { goalAchiveCriteria GoalAchieveCriteria[] @relation("GoalCriterion") goalAsCriteria GoalAchieveCriteria? @relation("GoalAsCriteria") - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt @@unique([projectId, scopeId]) @@index([ownerId]) diff --git a/prisma/seed.ts b/prisma/seed.ts index 4862625b7..eed74e5a8 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -8,9 +8,34 @@ import { keyPredictor } from '../src/utils/keyPredictor'; const adminEmail = process.env.ADMIN_EMAIL || 'tony@taskany.org'; const adminPassword = process.env.ADMIN_PASSWORD || 'taskany'; -const priorities = ['Highest', 'High', 'Medium', 'Low']; +// const priorities = ['Highest', 'High', 'Medium', 'Low']; +const prioritiesExact = [ + { + id: 4, + title: 'Highest', + value: 4, + }, + { + id: 3, + title: 'High', + value: 3, + }, + { + id: 2, + title: 'Medium', + value: 2, + }, + { + id: 1, + title: 'Low', + value: 1, + }, +]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any -const sample = (arr: any[]) => arr[Math.floor(Math.random() * arr.length)]; +function sample(arr: T[]) { + return arr[Math.floor(Math.random() * arr.length)]; +} async function seed(title: string, cb: () => void) { console.log('SEED:', title, '...'); @@ -23,6 +48,7 @@ assert(adminPassword, "Admin's password isn't provided. Check your environment v let allUsers: User[]; let tags: Tag[]; +// let priorityExact: Priority[]; const init = (async () => { allUsers = await Promise.all( @@ -123,13 +149,13 @@ const init = (async () => { prisma.tag.create({ data: { title: 'frontend', - activityId: sample(allUsers).activityId, + activityId: sample(allUsers).activityId ?? '', }, }), prisma.tag.create({ data: { title: 'backend', - activityId: sample(allUsers).activityId, + activityId: sample(allUsers).activityId ?? '', }, }), ]); @@ -169,6 +195,8 @@ seed('Default projects', async () => { await init; + await Promise.all(prioritiesExact.map((priority) => prisma.priority.create({ data: priority }))); + const allProjects = await Promise.all( [ ['Frontend', sample(allUsers).activityId], @@ -181,14 +209,14 @@ seed('Default projects', async () => { ['Finance department', sample(allUsers).activityId], ['Social promotion team', sample(allUsers).activityId], ['Cyber security', sample(allUsers).activityId], - ].map(([title, activityId]: string[]) => + ].map(([title, activityId]) => prisma.project.create({ data: { - id: keyPredictor(title), - title, + id: keyPredictor(title ?? ''), + title: title ?? '', flowId: f.id, description: faker.lorem.sentence(5), - activityId, + activityId: activityId ?? '', }, }), ), @@ -209,29 +237,33 @@ seed('Default projects', async () => { [faker.lorem.words(2), faker.lorem.sentence(5), sample(allUsers).activityId], [faker.lorem.words(2), faker.lorem.sentence(5), sample(allUsers).activityId], // eslint-disable-next-line no-loop-func - ].map(([title, description, activityId]: string[], index) => - prisma.goal.create({ + ].map(([title, description, activityId], index) => { + const priority = sample(prioritiesExact); + + return prisma.goal.create({ data: { scopeId: index + 1, - title, - description, + title: title ?? '', + description: description ?? '', projectId: project.id, activityId, ownerId: activityId, - priority: sample(priorities), + priority: priority.title, + priorityId: priority.id, + // priorityExact: priority, participants: { connect: Math.random() > 0.5 ? [ { - id: sample(allUsers)?.activityId as string, + id: sample(allUsers)?.activityId ?? '', }, { - id: sample(allUsers)?.activityId as string, + id: sample(allUsers)?.activityId ?? '', }, ] : { - id: sample(allUsers)?.activityId as string, + id: sample(allUsers)?.activityId ?? '', }, }, stateId: sample(f.states)?.id, @@ -261,9 +293,9 @@ seed('Default projects', async () => { [faker.lorem.sentence(5), sample(allUsers).activityId], [faker.lorem.sentence(5), sample(allUsers).activityId], [faker.lorem.sentence(5), sample(allUsers).activityId], - ].map(([description, activityId]: string[]) => ({ - description, - activityId, + ].map(([description, activityId]) => ({ + description: description ?? '', + activityId: activityId ?? '', })), }, }, @@ -273,8 +305,8 @@ seed('Default projects', async () => { blocks: true, relatedTo: true, }, - }), - ), + }); + }), ); for (const goal of allGoals) { // eslint-disable-next-line no-await-in-loop @@ -301,16 +333,16 @@ seed('Default projects', async () => { history: { createMany: { data: [ - [faker.lorem.sentence(2), goal.title, sample(allUsers).activityId, 'title'], + [faker.lorem.sentence(2), goal.title, sample(allUsers).activityId ?? '', 'title'], [ faker.lorem.sentence(5), goal.description, - sample(allUsers).activityId, + sample(allUsers).activityId ?? '', 'description', ], - [sample(allUsers).activityId, null, goal.activityId, 'participants'], - [null, sample(allGoals).id, sample(allUsers).activityId, 'dependencies'], - [sample(allGoals).id, null, sample(allUsers).activityId, 'dependencies'], + [sample(allUsers).activityId ?? '', null, goal.activityId ?? '', 'participants'], + [null, sample(allGoals).id, sample(allUsers).activityId ?? '', 'dependencies'], + [sample(allGoals).id, null, sample(allUsers).activityId ?? '', 'dependencies'], ].map(([previousValue, nextValue, activityId, subject]) => { let action = 'add'; @@ -321,11 +353,11 @@ seed('Default projects', async () => { } return { - subject, + subject: subject ?? '', previousValue, nextValue, action, - activityId, + activityId: activityId ?? '', }; }), }, diff --git a/trpc/queries/goals.ts b/trpc/queries/goals.ts index 601b89ebe..483b8300e 100644 --- a/trpc/queries/goals.ts +++ b/trpc/queries/goals.ts @@ -119,7 +119,7 @@ export const goalsFilter = ( if (data.sort?.priority) { orderBy.push({ - priority: data.sort.priority, + priorityId: data.sort.priority, }); } diff --git a/trpc/router/goal.ts b/trpc/router/goal.ts index aca566ded..7f0e62a4a 100644 --- a/trpc/router/goal.ts +++ b/trpc/router/goal.ts @@ -499,7 +499,7 @@ export const goal = router({ title: input.title, description: input.description, stateId: input.state?.id, - priority: input.priority, + priority: input.priority ?? '', estimate: correctEstimate?.id ? { create: {