feat: add survey view with voting functionality and admin panel
- Implemented SurveyView.vue for displaying and managing polls, including voting, comments, and results. - Added new database tables for vote polls, votes, and comments in migration script. - Created unique lottery logic for handling unique item rewards based on voting. - Developed unit tests for unique lottery functionality to ensure deterministic behavior and correct counting of occupied unique items.
This commit is contained in:
@@ -514,3 +514,55 @@ model BoardComment {
|
||||
@@index([postId, createdAt])
|
||||
@@map("board_comment")
|
||||
}
|
||||
|
||||
model VotePoll {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
body String @default("")
|
||||
options Json
|
||||
multipleOptions Int @default(1) @map("multiple_options")
|
||||
revealMode String @map("reveal_mode")
|
||||
openerGeneralId Int @map("opener_general_id")
|
||||
openerName String @map("opener_name")
|
||||
startAt DateTime @default(now()) @map("start_at")
|
||||
endAt DateTime? @map("end_at")
|
||||
closedAt DateTime? @map("closed_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
votes Vote[]
|
||||
comments VoteComment[]
|
||||
|
||||
@@map("vote_poll")
|
||||
}
|
||||
|
||||
model Vote {
|
||||
id Int @id @default(autoincrement())
|
||||
voteId Int @map("vote_id")
|
||||
generalId Int @map("general_id")
|
||||
nationId Int @map("nation_id")
|
||||
selection Json
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
poll VotePoll @relation(fields: [voteId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([voteId, generalId])
|
||||
@@index([voteId])
|
||||
@@map("vote")
|
||||
}
|
||||
|
||||
model VoteComment {
|
||||
id Int @id @default(autoincrement())
|
||||
voteId Int @map("vote_id")
|
||||
generalId Int @map("general_id")
|
||||
nationId Int @map("nation_id")
|
||||
generalName String @map("general_name")
|
||||
nationName String @map("nation_name")
|
||||
text String
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
poll VotePoll @relation(fields: [voteId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([voteId, createdAt])
|
||||
@@map("vote_comment")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE "vote_poll" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"title" TEXT NOT NULL,
|
||||
"body" TEXT NOT NULL DEFAULT '',
|
||||
"options" JSONB NOT NULL,
|
||||
"multiple_options" INTEGER NOT NULL DEFAULT 1,
|
||||
"reveal_mode" TEXT NOT NULL,
|
||||
"opener_general_id" INTEGER NOT NULL,
|
||||
"opener_name" TEXT NOT NULL,
|
||||
"start_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"end_at" TIMESTAMP(3) NULL,
|
||||
"closed_at" TIMESTAMP(3) NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE "vote" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"vote_id" INTEGER NOT NULL REFERENCES "vote_poll"("id") ON DELETE CASCADE,
|
||||
"general_id" INTEGER NOT NULL,
|
||||
"nation_id" INTEGER NOT NULL,
|
||||
"selection" JSONB NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "vote_vote_general_uidx" ON "vote"("vote_id", "general_id");
|
||||
CREATE INDEX "vote_vote_idx" ON "vote"("vote_id");
|
||||
|
||||
CREATE TABLE "vote_comment" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"vote_id" INTEGER NOT NULL REFERENCES "vote_poll"("id") ON DELETE CASCADE,
|
||||
"general_id" INTEGER NOT NULL,
|
||||
"nation_id" INTEGER NOT NULL,
|
||||
"general_name" TEXT NOT NULL,
|
||||
"nation_name" TEXT NOT NULL,
|
||||
"text" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX "vote_comment_vote_created_idx" ON "vote_comment"("vote_id", "created_at");
|
||||
Reference in New Issue
Block a user