83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
import {
|
|
pgSchema,
|
|
text,
|
|
timestamp,
|
|
boolean,
|
|
integer,
|
|
jsonb,
|
|
uniqueIndex,
|
|
} from "drizzle-orm/pg-core";
|
|
import { uuidv7 } from "uuidv7";
|
|
|
|
export const formSchema = pgSchema("form");
|
|
|
|
export const forms = formSchema.table("form", {
|
|
id: text("id")
|
|
.primaryKey()
|
|
.$defaultFn(() => uuidv7()),
|
|
title: text("title").notNull(),
|
|
description: text("description"),
|
|
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
|
|
isOpen: boolean("is_open").notNull().default(true),
|
|
discordWebhookUrl: text("discord_webhook_url"),
|
|
discordWebhookTemplate: text("discord_webhook_template"),
|
|
discordWebhookUpdateTemplate: text("discord_webhook_update_template"),
|
|
allowedRoles: jsonb("allowed_roles").$type<string[]>().default([]),
|
|
deniedRoles: jsonb("denied_roles").$type<string[]>().default([]),
|
|
});
|
|
|
|
export type QuestionType = "text" | "textarea" | "radio" | "checkbox";
|
|
|
|
export const questions = formSchema.table("question", {
|
|
id: text("id")
|
|
.primaryKey()
|
|
.$defaultFn(() => uuidv7()),
|
|
formId: text("form_id")
|
|
.notNull()
|
|
.references(() => forms.id, { onDelete: "cascade" }),
|
|
type: text("type").$type<QuestionType>().notNull().default("text"),
|
|
label: text("label").notNull(),
|
|
imageUrl: text("image_url"),
|
|
displayOrder: integer("display_order").notNull().default(0),
|
|
required: boolean("required").notNull().default(false),
|
|
options: jsonb("options").$type<string[]>().default([]),
|
|
allowOther: boolean("allow_other").notNull().default(false),
|
|
});
|
|
|
|
export const submissions = formSchema.table(
|
|
"submission",
|
|
{
|
|
id: text("id")
|
|
.primaryKey()
|
|
.$defaultFn(() => uuidv7()),
|
|
formId: text("form_id")
|
|
.notNull()
|
|
.references(() => forms.id, { onDelete: "cascade" }),
|
|
userDiscordId: text("user_discord_id"),
|
|
userName: text("user_name"),
|
|
submittedAt: timestamp("submitted_at", { mode: "date" }).defaultNow().notNull(),
|
|
editHistory: jsonb("edit_history")
|
|
.$type<{ editedAt: string; oldAnswers: Record<string, string> }[]>()
|
|
.default([]),
|
|
},
|
|
(submission) => [
|
|
uniqueIndex("submission_form_user_discord_id_unique").on(
|
|
submission.formId,
|
|
submission.userDiscordId
|
|
),
|
|
]
|
|
);
|
|
|
|
export const answers = formSchema.table("answer", {
|
|
id: text("id")
|
|
.primaryKey()
|
|
.$defaultFn(() => uuidv7()),
|
|
submissionId: text("submission_id")
|
|
.notNull()
|
|
.references(() => submissions.id, { onDelete: "cascade" }),
|
|
questionId: text("question_id")
|
|
.notNull()
|
|
.references(() => questions.id, { onDelete: "cascade" }),
|
|
value: text("value").notNull().default(""),
|
|
});
|