mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-21 12:56:21 +02:00
🏗️ Update how we store date values
This also fixes a few bugs: - some values had end times that were before the start times - some values has end times a couple of days in the future It’s not entirely clear how users were able to set these values but this update fixes these values and helps avoid similar issues in the future.
This commit is contained in:
parent
8a9159c322
commit
51c5016656
12 changed files with 203 additions and 158 deletions
|
@ -0,0 +1,35 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "options"
|
||||
ADD COLUMN "duration_minutes" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "start" TIMESTAMP(0);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "polls" DROP COLUMN "type";
|
||||
|
||||
-- DropEnum
|
||||
DROP TYPE "poll_type";
|
||||
|
||||
-- Reformat option value into new columns
|
||||
UPDATE "options"
|
||||
SET "start" = CASE
|
||||
WHEN POSITION('/' IN "value") = 0 THEN (value || 'T00:00:00')::TIMESTAMP WITHOUT TIME ZONE
|
||||
ELSE SPLIT_PART("value", '/', 1)::TIMESTAMP WITHOUT TIME ZONE
|
||||
END,
|
||||
"duration_minutes" = CASE
|
||||
WHEN POSITION('/' IN "value") = 0 THEN 0
|
||||
ELSE
|
||||
LEAST(EXTRACT(EPOCH FROM (split_part("value", '/', 2)::timestamp - split_part("value", '/', 1)::timestamp)) / 60, 1440)
|
||||
END;
|
||||
|
||||
-- Fix cases where we have a negative duration due to the end time being in the past
|
||||
-- eg. Some polls have value 2023-03-29T23:00:00/2023-03-29T01:00:00
|
||||
UPDATE "options"
|
||||
SET "duration_minutes" = "duration_minutes" + 1440
|
||||
WHERE "duration_minutes" < 0;
|
||||
|
||||
-- Set start date to be not null now that we have all the data and drop the old value column
|
||||
ALTER TABLE "options"
|
||||
DROP COLUMN "value",
|
||||
DROP COLUMN "updated_at",
|
||||
ALTER COLUMN "start" SET NOT NULL;
|
||||
|
|
@ -22,19 +22,12 @@ model User {
|
|||
@@map("users")
|
||||
}
|
||||
|
||||
enum PollType {
|
||||
date
|
||||
|
||||
@@map("poll_type")
|
||||
}
|
||||
|
||||
model Poll {
|
||||
id String @id @unique @map("id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
deadline DateTime?
|
||||
title String
|
||||
type PollType
|
||||
description String?
|
||||
location String?
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
|
@ -88,11 +81,11 @@ model Participant {
|
|||
|
||||
model Option {
|
||||
id String @id @default(cuid())
|
||||
value String
|
||||
start DateTime @db.Timestamp(0)
|
||||
duration Int @default(0) @map("duration_minutes")
|
||||
pollId String @map("poll_id")
|
||||
poll Poll @relation(fields: [pollId], references: [id])
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime? @updatedAt @map("updated_at")
|
||||
|
||||
@@index([pollId], type: Hash)
|
||||
@@map("options")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { faker } from "@faker-js/faker";
|
||||
import { PrismaClient, VoteType } from "@prisma/client";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
|
@ -11,14 +11,16 @@ async function main() {
|
|||
// Create some users
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
name: faker.name.fullName(),
|
||||
email: faker.internet.email(),
|
||||
name: "Dev User",
|
||||
email: "dev@rallly.co",
|
||||
},
|
||||
});
|
||||
|
||||
// Create some polls
|
||||
const polls = await Promise.all(
|
||||
Array.from({ length: 20 }).map(async () => {
|
||||
Array.from({ length: 20 }).map(async (_, i) => {
|
||||
// create some polls with no duration (all day) and some with a random duration.
|
||||
const duration = i % 5 === 0 ? 15 * randInt(8) : 0;
|
||||
const poll = await prisma.poll.create({
|
||||
include: {
|
||||
participants: true,
|
||||
|
@ -30,7 +32,6 @@ async function main() {
|
|||
description: faker.lorem.paragraph(),
|
||||
location: faker.address.streetAddress(),
|
||||
deadline: faker.date.future(),
|
||||
type: "date",
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
|
@ -46,7 +47,8 @@ async function main() {
|
|||
) //
|
||||
.map((date) => {
|
||||
return {
|
||||
value: date.toISOString().substring(0, 10),
|
||||
start: date,
|
||||
duration,
|
||||
};
|
||||
}),
|
||||
},
|
||||
|
@ -73,7 +75,7 @@ async function main() {
|
|||
data: poll.options.map((option) => {
|
||||
const randomNumber = randInt(100);
|
||||
const vote =
|
||||
randomNumber > 90 ? "ifNeedBe" : randomNumber > 50 ? "yes" : "no";
|
||||
randomNumber > 95 ? "ifNeedBe" : randomNumber > 50 ? "yes" : "no";
|
||||
return {
|
||||
participantId: participant.id,
|
||||
pollId: poll.id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue