Files
erika/db/schema/share.ts
T

86 lines
2.3 KiB
TypeScript

import { randomBytes } from "node:crypto";
import {
index,
pgSchema,
text,
timestamp,
} from "drizzle-orm/pg-core";
import { uuidv7 } from "uuidv7";
import { users } from "./account";
import { cdn } from "./form";
export const shareSchema = pgSchema("share");
export type ShareSource = "web" | "bot";
const SHARE_ID_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
export function createShareId() {
let id = "";
while (id.length < 8) {
for (const value of randomBytes(8)) {
if (value >= 252) continue;
id += SHARE_ID_ALPHABET[value % SHARE_ID_ALPHABET.length];
if (id.length === 8) break;
}
}
return id;
}
export const shareTexts = shareSchema.table(
"text",
{
id: text("id").primaryKey().$defaultFn(createShareId),
content: text("content").notNull(),
description: text("description"),
imageCdnId: text("image_cdn_id").references(() => cdn.id, {
onDelete: "set null",
}),
source: text("source").$type<ShareSource>().notNull(),
authorId: text("author_id").references(() => users.id, {
onDelete: "set null",
}),
authorDiscordId: text("author_discord_id").notNull(),
authorName: text("author_name").notNull(),
authorAvatarUrl: text("author_avatar_url"),
createdAt: timestamp("created_at", { mode: "date", withTimezone: true })
.defaultNow()
.notNull(),
},
(share) => [
index("share_text_author_created_idx").on(
share.authorDiscordId,
share.createdAt
),
]
);
export const shareComments = shareSchema.table(
"comment",
{
id: text("id")
.primaryKey()
.$defaultFn(() => uuidv7()),
shareId: text("share_id")
.notNull()
.references(() => shareTexts.id, { onDelete: "cascade" }),
body: text("body").notNull(),
authorId: text("author_id").references(() => users.id, {
onDelete: "set null",
}),
authorDiscordId: text("author_discord_id").notNull(),
authorName: text("author_name").notNull(),
authorAvatarUrl: text("author_avatar_url"),
createdAt: timestamp("created_at", { mode: "date", withTimezone: true })
.defaultNow()
.notNull(),
},
(comment) => [
index("share_comment_share_created_id_idx").on(
comment.shareId,
comment.createdAt,
comment.id
),
]
);