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] }), }))