forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
import { relations } from 'drizzle-orm'
|
||||
import { bigint, boolean, char, int, json, mysqlEnum, mysqlTable, primaryKey, text, timestamp, varchar } from 'drizzle-orm/mysql-core'
|
||||
|
||||
export const users = mysqlTable('users', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
name: varchar('name', { length: 50 }).notNull().unique(),
|
||||
email: varchar('email', { length: 255 }).unique(),
|
||||
passwordHash: varchar('password_hash', { length: 255 }).notNull(),
|
||||
color: varchar('color', { length: 7 }),
|
||||
avatar: varchar('avatar', { length: 255 }),
|
||||
cardEffect: varchar('card_effect', { length: 32 }),
|
||||
cardEffectColor: varchar('card_effect_color', { length: 7 }),
|
||||
cardVignette: boolean('card_vignette').default(false).notNull(),
|
||||
cardBorderEffect: varchar('card_border_effect', { length: 32 }),
|
||||
cardBorderEffectColor: varchar('card_border_effect_color', { length: 7 }),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const sessions = mysqlTable('sessions', {
|
||||
id: varchar('id', { length: 64 }).primaryKey(),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
expiresAt: timestamp('expires_at').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const uploads = mysqlTable('uploads', {
|
||||
id: varchar('id', { length: 8 }).primaryKey(),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
type: mysqlEnum('type', ['image', 'video', 'audio', 'youtube', 'twitch', 'link']).notNull(),
|
||||
fileName: varchar('file_name', { length: 255 }),
|
||||
externalUrl: varchar('external_url', { length: 2048 }),
|
||||
originalName: varchar('original_name', { length: 255 }).notNull(),
|
||||
mimeType: varchar('mime_type', { length: 100 }),
|
||||
size: bigint('size', { mode: 'number', unsigned: true }),
|
||||
title: varchar('title', { length: 255 }),
|
||||
previewImage: varchar('preview_image', { length: 2048 }),
|
||||
previewTitle: varchar('preview_title', { length: 500 }),
|
||||
audioMeta: json('audio_meta'),
|
||||
commentCount: int('comment_count', { unsigned: true }).notNull().default(0),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const comments = mysqlTable('comments', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
content: text('content').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const commentAttachments = mysqlTable('comment_attachments', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
commentId: bigint('comment_id', { mode: 'number', unsigned: true }).notNull().references(() => comments.id, { onDelete: 'cascade' }),
|
||||
fileName: varchar('file_name', { length: 255 }).notNull(),
|
||||
originalName: varchar('original_name', { length: 255 }).notNull(),
|
||||
mimeType: varchar('mime_type', { length: 100 }),
|
||||
size: bigint('size', { mode: 'number', unsigned: true }),
|
||||
cover: varchar('cover', { length: 2048 }),
|
||||
meta: json('meta'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const commentReactions = mysqlTable('comment_reactions', {
|
||||
commentId: bigint('comment_id', { mode: 'number', unsigned: true }).notNull().references(() => comments.id, { onDelete: 'cascade' }),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
emoji: varchar('emoji', { length: 32 }).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
}, t => [primaryKey({ columns: [t.commentId, t.userId, t.emoji] })])
|
||||
|
||||
export const uploadReactions = mysqlTable('upload_reactions', {
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
emoji: varchar('emoji', { length: 32 }).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
}, t => [primaryKey({ columns: [t.uploadId, t.userId, t.emoji] })])
|
||||
|
||||
export const favorites = mysqlTable('favorites', {
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
}, t => [primaryKey({ columns: [t.userId, t.uploadId] })])
|
||||
|
||||
export const threadSubscriptions = mysqlTable('thread_subscriptions', {
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
enabled: boolean('enabled').notNull().default(true),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
}, t => [primaryKey({ columns: [t.uploadId, t.userId] })])
|
||||
|
||||
export const linkPreviews = mysqlTable('link_previews', {
|
||||
urlHash: char('url_hash', { length: 64 }).primaryKey(),
|
||||
url: varchar('url', { length: 2048 }).notNull(),
|
||||
image: varchar('image', { length: 2048 }),
|
||||
title: varchar('title', { length: 500 }),
|
||||
fetchedAt: timestamp('fetched_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const notifications = mysqlTable('notifications', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
actorId: bigint('actor_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
commentId: bigint('comment_id', { mode: 'number', unsigned: true }).notNull().references(() => comments.id, { onDelete: 'cascade' }),
|
||||
isRead: boolean('is_read').notNull().default(false),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const roles = mysqlTable('roles', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
name: varchar('name', { length: 50 }).notNull().unique(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const userRoles = mysqlTable('user_roles', {
|
||||
userId: bigint('user_id', { mode: 'number', unsigned: true }).notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
roleId: bigint('role_id', { mode: 'number', unsigned: true }).notNull().references(() => roles.id, { onDelete: 'cascade' }),
|
||||
}, t => [primaryKey({ columns: [t.userId, t.roleId] })])
|
||||
|
||||
export const permissions = mysqlTable('permissions', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
key: varchar('key', { length: 50 }).notNull().unique(),
|
||||
label: varchar('label', { length: 255 }).notNull(),
|
||||
})
|
||||
|
||||
export const rolePermissions = mysqlTable('role_permissions', {
|
||||
roleId: bigint('role_id', { mode: 'number', unsigned: true }).notNull().references(() => roles.id, { onDelete: 'cascade' }),
|
||||
permissionId: bigint('permission_id', { mode: 'number', unsigned: true }).notNull().references(() => permissions.id, { onDelete: 'cascade' }),
|
||||
}, t => [primaryKey({ columns: [t.roleId, t.permissionId] })])
|
||||
|
||||
export const tags = mysqlTable('tags', {
|
||||
id: bigint('id', { mode: 'number', unsigned: true }).autoincrement().primaryKey(),
|
||||
name: varchar('name', { length: 64 }).notNull().unique(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const uploadTags = mysqlTable('upload_tags', {
|
||||
uploadId: varchar('upload_id', { length: 8 }).notNull().references(() => uploads.id, { onDelete: 'cascade' }),
|
||||
tagId: bigint('tag_id', { mode: 'number', unsigned: true }).notNull().references(() => tags.id, { onDelete: 'cascade' }),
|
||||
}, t => [primaryKey({ columns: [t.uploadId, t.tagId] })])
|
||||
|
||||
// Generischer Key-Value-Store für Seiten-Einstellungen (z. B. MOTD)
|
||||
export const settings = mysqlTable('settings', {
|
||||
key: varchar('key', { length: 100 }).primaryKey(),
|
||||
value: text('value'),
|
||||
})
|
||||
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
sessions: many(sessions),
|
||||
uploads: many(uploads),
|
||||
comments: many(comments),
|
||||
userRoles: many(userRoles),
|
||||
commentReactions: many(commentReactions),
|
||||
uploadReactions: many(uploadReactions),
|
||||
threadSubscriptions: many(threadSubscriptions),
|
||||
}))
|
||||
|
||||
export const rolesRelations = relations(roles, ({ many }) => ({
|
||||
userRoles: many(userRoles),
|
||||
rolePermissions: many(rolePermissions),
|
||||
}))
|
||||
|
||||
export const userRolesRelations = relations(userRoles, ({ one }) => ({
|
||||
user: one(users, { fields: [userRoles.userId], references: [users.id] }),
|
||||
role: one(roles, { fields: [userRoles.roleId], references: [roles.id] }),
|
||||
}))
|
||||
|
||||
export const sessionsRelations = relations(sessions, ({ one }) => ({
|
||||
user: one(users, { fields: [sessions.userId], references: [users.id] }),
|
||||
}))
|
||||
|
||||
export const uploadsRelations = relations(uploads, ({ one, many }) => ({
|
||||
user: one(users, { fields: [uploads.userId], references: [users.id] }),
|
||||
comments: many(comments),
|
||||
favorites: many(favorites),
|
||||
reactions: many(uploadReactions),
|
||||
threadSubscriptions: many(threadSubscriptions),
|
||||
}))
|
||||
|
||||
export const commentsRelations = relations(comments, ({ one, many }) => ({
|
||||
upload: one(uploads, { fields: [comments.uploadId], references: [uploads.id] }),
|
||||
user: one(users, { fields: [comments.userId], references: [users.id] }),
|
||||
reactions: many(commentReactions),
|
||||
attachments: many(commentAttachments),
|
||||
}))
|
||||
|
||||
export const commentAttachmentsRelations = relations(commentAttachments, ({ one }) => ({
|
||||
comment: one(comments, { fields: [commentAttachments.commentId], references: [comments.id] }),
|
||||
}))
|
||||
|
||||
export const commentReactionsRelations = relations(commentReactions, ({ one }) => ({
|
||||
comment: one(comments, { fields: [commentReactions.commentId], references: [comments.id] }),
|
||||
user: one(users, { fields: [commentReactions.userId], references: [users.id] }),
|
||||
}))
|
||||
|
||||
export const uploadReactionsRelations = relations(uploadReactions, ({ one }) => ({
|
||||
upload: one(uploads, { fields: [uploadReactions.uploadId], references: [uploads.id] }),
|
||||
user: one(users, { fields: [uploadReactions.userId], references: [users.id] }),
|
||||
}))
|
||||
|
||||
export const favoritesRelations = relations(favorites, ({ one }) => ({
|
||||
upload: one(uploads, { fields: [favorites.uploadId], references: [uploads.id] }),
|
||||
user: one(users, { fields: [favorites.userId], references: [users.id] }),
|
||||
}))
|
||||
|
||||
export const rolePermissionsRelations = relations(rolePermissions, ({ one }) => ({
|
||||
role: one(roles, { fields: [rolePermissions.roleId], references: [roles.id] }),
|
||||
permission: one(permissions, { fields: [rolePermissions.permissionId], references: [permissions.id] }),
|
||||
}))
|
||||
|
||||
export const threadSubscriptionsRelations = relations(threadSubscriptions, ({ one }) => ({
|
||||
upload: one(uploads, { fields: [threadSubscriptions.uploadId], references: [uploads.id] }),
|
||||
user: one(users, { fields: [threadSubscriptions.userId], references: [users.id] }),
|
||||
}))
|
||||
|
||||
export const notificationsRelations = relations(notifications, ({ one }) => ({
|
||||
user: one(users, { fields: [notifications.userId], references: [users.id] }),
|
||||
actor: one(users, { fields: [notifications.actorId], references: [users.id] }),
|
||||
upload: one(uploads, { fields: [notifications.uploadId], references: [uploads.id] }),
|
||||
comment: one(comments, { fields: [notifications.commentId], references: [comments.id] }),
|
||||
}))
|
||||
Reference in New Issue
Block a user