forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import { z } from 'zod'
|
||||
import { settings } from '../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
message: z.string().trim().max(500),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'site.manage')
|
||||
const { message } = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
await db
|
||||
.insert(settings)
|
||||
.values({ key: 'motd', value: message })
|
||||
.onDuplicateKeyUpdate({ set: { value: message } })
|
||||
broadcastToAll({ type: 'motd', message })
|
||||
return { message }
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
import { asc, count, eq } from 'drizzle-orm'
|
||||
import { roles, userRoles } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'admin.access')
|
||||
const roleList = await useDb()
|
||||
.select({
|
||||
id: roles.id,
|
||||
name: roles.name,
|
||||
memberCount: count(userRoles.userId),
|
||||
})
|
||||
.from(roles)
|
||||
.leftJoin(userRoles, eq(userRoles.roleId, roles.id))
|
||||
.groupBy(roles.id)
|
||||
.orderBy(asc(roles.name))
|
||||
const permsByRole = await getRolePermissions()
|
||||
return roleList.map(r => ({ ...r, permissions: permsByRole.get(r.id) ?? [] }))
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
const bodySchema = z.object({
|
||||
name: z.string().trim().min(2).max(50).regex(/^[\w-]+$/, 'Nur Buchstaben, Zahlen, - und _'),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'roles.manage')
|
||||
const { name } = await readValidatedBody(event, bodySchema.parse)
|
||||
const id = await ensureRole(name)
|
||||
return { id, name }
|
||||
})
|
||||
@@ -0,0 +1,21 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { roles } from '../../../db/schema'
|
||||
import { SYSTEM_ROLES } from '../../../../shared/utils/permissions'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'roles.manage')
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
const existing = await db.select({ name: roles.name }).from(roles).where(eq(roles.id, id)).limit(1)
|
||||
if (!existing[0]) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Rolle nicht gefunden' })
|
||||
}
|
||||
if ((SYSTEM_ROLES as readonly string[]).includes(existing[0].name)) {
|
||||
throw createError({ statusCode: 400, statusMessage: `Die ${existing[0].name}-Rolle kann nicht gelöscht werden` })
|
||||
}
|
||||
await db.delete(roles).where(eq(roles.id, id))
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,38 @@
|
||||
import { eq, inArray } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { PERMISSION_KEYS } from '../../../../../shared/utils/permissions'
|
||||
import { permissions, rolePermissions, roles } from '../../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
permissions: z.array(z.string()).max(50),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'roles.manage')
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const { permissions: keys } = await readValidatedBody(event, bodySchema.parse)
|
||||
if (keys.some(k => !PERMISSION_KEYS.includes(k))) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Unbekannte Berechtigung' })
|
||||
}
|
||||
|
||||
const db = useDb()
|
||||
const [role] = await db.select({ name: roles.name }).from(roles).where(eq(roles.id, id)).limit(1)
|
||||
if (!role) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Rolle nicht gefunden' })
|
||||
}
|
||||
if (role.name === 'admin') {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Die Admin-Rolle hat immer alle Berechtigungen' })
|
||||
}
|
||||
|
||||
await db.delete(rolePermissions).where(eq(rolePermissions.roleId, id))
|
||||
if (keys.length) {
|
||||
const rows = await db.select({ id: permissions.id }).from(permissions).where(inArray(permissions.key, keys))
|
||||
if (rows.length) {
|
||||
await db.insert(rolePermissions).values(rows.map(r => ({ roleId: id, permissionId: r.id })))
|
||||
}
|
||||
}
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,26 @@
|
||||
import { asc, eq } from 'drizzle-orm'
|
||||
import { roles, userRoles, users } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'admin.access')
|
||||
const db = useDb()
|
||||
|
||||
const allUsers = await db
|
||||
.select({ id: users.id, name: users.name, email: users.email, createdAt: users.createdAt })
|
||||
.from(users)
|
||||
.orderBy(asc(users.name))
|
||||
|
||||
const roleRows = await db
|
||||
.select({ userId: userRoles.userId, roleId: roles.id, name: roles.name })
|
||||
.from(userRoles)
|
||||
.innerJoin(roles, eq(userRoles.roleId, roles.id))
|
||||
|
||||
const byUser = new Map<number, { id: number, name: string }[]>()
|
||||
for (const row of roleRows) {
|
||||
const list = byUser.get(row.userId) ?? []
|
||||
list.push({ id: row.roleId, name: row.name })
|
||||
byUser.set(row.userId, list)
|
||||
}
|
||||
|
||||
return allUsers.map(u => ({ ...u, roles: byUser.get(u.id) ?? [] }))
|
||||
})
|
||||
@@ -0,0 +1,29 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { roles, users } from '../../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
roleId: z.number().int().positive(),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'users.manage')
|
||||
const userId = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(userId) || userId <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const { roleId } = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
|
||||
const [user] = await db.select({ id: users.id }).from(users).where(eq(users.id, userId)).limit(1)
|
||||
if (!user) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Nutzer nicht gefunden' })
|
||||
}
|
||||
const [role] = await db.select({ id: roles.id }).from(roles).where(eq(roles.id, roleId)).limit(1)
|
||||
if (!role) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Rolle nicht gefunden' })
|
||||
}
|
||||
|
||||
await assignRole(userId, roleId)
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import { and, eq } from 'drizzle-orm'
|
||||
import { roles, userRoles } from '../../../../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const admin = await requirePermission(event, 'users.manage')
|
||||
const userId = Number(getRouterParam(event, 'id'))
|
||||
const roleId = Number(getRouterParam(event, 'roleId'))
|
||||
if (!Number.isInteger(userId) || userId <= 0 || !Number.isInteger(roleId) || roleId <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
|
||||
const [role] = await db.select({ name: roles.name }).from(roles).where(eq(roles.id, roleId)).limit(1)
|
||||
if (!role) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Rolle nicht gefunden' })
|
||||
}
|
||||
if (role.name === 'admin' && userId === admin.id) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Du kannst dir nicht selbst die Admin-Rolle entziehen' })
|
||||
}
|
||||
|
||||
await db.delete(userRoles).where(and(eq(userRoles.userId, userId), eq(userRoles.roleId, roleId)))
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { users } from '../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
name: z.string().trim().min(1),
|
||||
password: z.string().min(1),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
|
||||
const rows = await db.select().from(users).where(eq(users.name, body.name)).limit(1)
|
||||
const user = rows[0]
|
||||
if (!user || !verifyPassword(body.password, user.passwordHash)) {
|
||||
throw createError({ statusCode: 401, statusMessage: 'Name oder Passwort falsch' })
|
||||
}
|
||||
|
||||
await createSession(event, user.id)
|
||||
return { user: { id: user.id, name: user.name, email: user.email, color: user.color, cardEffect: user.cardEffect, cardEffectColor: user.cardEffectColor, cardVignette: user.cardVignette, cardBorderEffect: user.cardBorderEffect, cardBorderEffectColor: user.cardBorderEffectColor, avatarUrl: avatarUrl(user.avatar), roles: await getUserRoles(user.id), permissions: await getUserPermissions(user.id) } }
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
await destroySession(event)
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,6 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await getSessionUser(event)
|
||||
return {
|
||||
user: user ? { id: user.id, name: user.name, email: user.email, color: user.color, cardEffect: user.cardEffect, cardEffectColor: user.cardEffectColor, cardVignette: user.cardVignette, cardBorderEffect: user.cardBorderEffect, cardBorderEffectColor: user.cardBorderEffectColor, avatarUrl: avatarUrl(user.avatar), roles: user.roles, permissions: user.permissions } : null,
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,51 @@
|
||||
import { count, eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { users } from '../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
name: z.string().trim().min(3, 'Mindestens 3 Zeichen').max(50),
|
||||
password: z.string().min(6, 'Mindestens 6 Zeichen').max(128),
|
||||
email: z.union([z.literal(''), z.email().max(255)]).optional(),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
|
||||
const existing = await db
|
||||
.select({ id: users.id })
|
||||
.from(users)
|
||||
.where(eq(users.name, body.name))
|
||||
.limit(1)
|
||||
if (existing.length) {
|
||||
throw createError({ statusCode: 409, statusMessage: 'Name ist bereits vergeben' })
|
||||
}
|
||||
|
||||
try {
|
||||
const color = randomUserColor()
|
||||
const [result] = await db.insert(users).values({
|
||||
name: body.name,
|
||||
email: body.email || null,
|
||||
passwordHash: hashPassword(body.password),
|
||||
color,
|
||||
})
|
||||
const userId = Number(result.insertId)
|
||||
|
||||
const [{ value: userCount }] = await db.select({ value: count() }).from(users)
|
||||
let roleNames: string[] = []
|
||||
if (userCount === 1) {
|
||||
const adminRoleId = await ensureRole('admin')
|
||||
await assignRole(userId, adminRoleId)
|
||||
roleNames = ['admin']
|
||||
}
|
||||
|
||||
await createSession(event, userId)
|
||||
return { user: { id: userId, name: body.name, email: body.email || null, color, cardEffect: null, cardEffectColor: null, cardVignette: false, cardBorderEffect: null, cardBorderEffectColor: null, avatarUrl: null, roles: roleNames, permissions: await getUserPermissions(userId) } }
|
||||
}
|
||||
catch (err: unknown) {
|
||||
if (typeof err === 'object' && err !== null && (err as { errno?: number }).errno === 1062) {
|
||||
throw createError({ statusCode: 409, statusMessage: 'Name oder E-Mail ist bereits vergeben' })
|
||||
}
|
||||
throw err
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
import { unlink } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { eq, sql } from 'drizzle-orm'
|
||||
import { commentAttachments, comments, uploads } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'comment.delete')
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
const comment = await db
|
||||
.select({ uploadId: comments.uploadId })
|
||||
.from(comments)
|
||||
.where(eq(comments.id, id))
|
||||
.limit(1)
|
||||
.then(r => r[0])
|
||||
const files = await db
|
||||
.select({ fileName: commentAttachments.fileName, cover: commentAttachments.cover })
|
||||
.from(commentAttachments)
|
||||
.where(eq(commentAttachments.commentId, id))
|
||||
await db.delete(comments).where(eq(comments.id, id))
|
||||
if (comment) {
|
||||
await db.update(uploads).set({ commentCount: sql`GREATEST(comment_count - 1, 0)` }).where(eq(uploads.id, comment.uploadId))
|
||||
}
|
||||
for (const f of files) {
|
||||
await unlink(join(uploadDir(), 'attachments', f.fileName)).catch(() => {})
|
||||
if (f.cover) {
|
||||
await unlink(join(process.cwd(), 'public', f.cover)).catch(() => {})
|
||||
}
|
||||
}
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,69 @@
|
||||
import { and, eq, sql } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { commentReactions, comments } from '../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
emoji: z.string().min(1).max(32),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const { emoji } = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
|
||||
const [comment] = await db
|
||||
.select({ id: comments.id, uploadId: comments.uploadId })
|
||||
.from(comments)
|
||||
.where(eq(comments.id, id))
|
||||
.limit(1)
|
||||
if (!comment) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Kommentar nicht gefunden' })
|
||||
}
|
||||
|
||||
const existing = await db
|
||||
.select({ userId: commentReactions.userId })
|
||||
.from(commentReactions)
|
||||
.where(and(
|
||||
eq(commentReactions.commentId, id),
|
||||
eq(commentReactions.userId, user.id),
|
||||
eq(commentReactions.emoji, emoji),
|
||||
))
|
||||
.limit(1)
|
||||
|
||||
let active: boolean
|
||||
if (existing.length) {
|
||||
await db.delete(commentReactions).where(and(
|
||||
eq(commentReactions.commentId, id),
|
||||
eq(commentReactions.userId, user.id),
|
||||
eq(commentReactions.emoji, emoji),
|
||||
))
|
||||
active = false
|
||||
}
|
||||
else {
|
||||
await db.insert(commentReactions).values({ commentId: id, userId: user.id, emoji })
|
||||
active = true
|
||||
}
|
||||
|
||||
const [{ total }] = await db
|
||||
.select({ total: sql<number>`count(*)` })
|
||||
.from(commentReactions)
|
||||
.where(and(eq(commentReactions.commentId, id), eq(commentReactions.emoji, emoji)))
|
||||
const count = Number(total)
|
||||
|
||||
broadcastToAll({
|
||||
type: 'reaction',
|
||||
commentId: id,
|
||||
uploadId: comment.uploadId,
|
||||
emoji,
|
||||
actorId: user.id,
|
||||
actorName: user.name,
|
||||
active,
|
||||
count,
|
||||
})
|
||||
|
||||
return { active, count }
|
||||
})
|
||||
@@ -0,0 +1,47 @@
|
||||
import { asc, desc, eq, inArray } from 'drizzle-orm'
|
||||
import { commentAttachments, comments, uploads, users } from '../../db/schema'
|
||||
import type { CommentAttachment } from '~~/shared/utils/attachments'
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const db = useDb()
|
||||
const rows = await db
|
||||
.select({
|
||||
id: comments.id,
|
||||
content: comments.content,
|
||||
createdAt: comments.createdAt,
|
||||
userName: users.name,
|
||||
userId: users.id,
|
||||
userColor: users.color,
|
||||
userAvatar: users.avatar,
|
||||
uploadId: uploads.id,
|
||||
})
|
||||
.from(comments)
|
||||
.innerJoin(users, eq(comments.userId, users.id))
|
||||
.innerJoin(uploads, eq(comments.uploadId, uploads.id))
|
||||
.orderBy(desc(comments.createdAt))
|
||||
.limit(15)
|
||||
|
||||
const commentIds = rows.map(r => r.id)
|
||||
const attachmentRows = commentIds.length
|
||||
? await db
|
||||
.select()
|
||||
.from(commentAttachments)
|
||||
.where(inArray(commentAttachments.commentId, commentIds))
|
||||
.orderBy(asc(commentAttachments.id))
|
||||
: []
|
||||
const attachmentsByComment = new Map<number, CommentAttachment[]>()
|
||||
for (const a of attachmentRows) {
|
||||
let list = attachmentsByComment.get(a.commentId)
|
||||
if (!list) {
|
||||
list = []
|
||||
attachmentsByComment.set(a.commentId, list)
|
||||
}
|
||||
list.push({ id: a.id, name: a.originalName, url: `/uploads/attachments/${a.fileName}`, mimeType: a.mimeType, size: a.size, cover: a.cover, meta: a.meta as CommentAttachment['meta'] })
|
||||
}
|
||||
|
||||
return rows.map(r => ({
|
||||
...r,
|
||||
userAvatarUrl: avatarUrl(r.userAvatar),
|
||||
attachments: attachmentsByComment.get(r.id) ?? [],
|
||||
}))
|
||||
})
|
||||
@@ -0,0 +1,16 @@
|
||||
import { sql } from 'drizzle-orm'
|
||||
import { users } from '../db/schema'
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
try {
|
||||
const db = useDb()
|
||||
await db.execute(sql`SELECT 1`)
|
||||
const [{ count }] = await db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(users)
|
||||
return { status: 'ok', database: 'connected', users: Number(count) }
|
||||
}
|
||||
catch {
|
||||
throw createError({ statusCode: 503, statusMessage: 'Database unavailable' })
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createHash } from 'node:crypto'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { linkPreviews } from '../db/schema'
|
||||
|
||||
const CACHE_TTL_MS = 1000 * 60 * 60 * 24
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const url = String(getQuery(event).url ?? '')
|
||||
if (!/^https?:\/\//i.test(url) || url.length > 2048) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige URL' })
|
||||
}
|
||||
|
||||
const urlHash = createHash('sha256').update(url).digest('hex')
|
||||
const db = useDb()
|
||||
const [cached] = await db
|
||||
.select()
|
||||
.from(linkPreviews)
|
||||
.where(eq(linkPreviews.urlHash, urlHash))
|
||||
.limit(1)
|
||||
|
||||
if (cached && Date.now() - cached.fetchedAt.getTime() < CACHE_TTL_MS) {
|
||||
return { image: cached.image, title: cached.title }
|
||||
}
|
||||
|
||||
const preview = await fetchLinkPreview(url)
|
||||
// Vorschaubild lokal speichern — die Remote-URL ist nicht stabil
|
||||
const image = preview.image
|
||||
? (await savePreviewImage(`links/${urlHash}`, preview.image)) ?? preview.image
|
||||
: null
|
||||
await db
|
||||
.insert(linkPreviews)
|
||||
.values({ urlHash, url, image, title: preview.title, fetchedAt: new Date() })
|
||||
.onDuplicateKeyUpdate({
|
||||
set: { image, title: preview.title, fetchedAt: new Date() },
|
||||
})
|
||||
return { image, title: preview.title }
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { settings } from '../db/schema'
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const db = useDb()
|
||||
const [row] = await db
|
||||
.select({ value: settings.value })
|
||||
.from(settings)
|
||||
.where(eq(settings.key, 'motd'))
|
||||
.limit(1)
|
||||
return { message: row?.value ?? '' }
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
import { and, eq } from 'drizzle-orm'
|
||||
import { notifications, users } from '../../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const id = Number(getRouterParam(event, 'id'))
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
await useDb().transaction(async (tx) => {
|
||||
await tx.select({ id: users.id }).from(users).where(eq(users.id, user.id)).for('update')
|
||||
const [notification] = await tx.select({ uploadId: notifications.uploadId }).from(notifications)
|
||||
.where(and(eq(notifications.id, id), eq(notifications.userId, user.id))).limit(1)
|
||||
if (!notification) return
|
||||
await tx.update(notifications).set({ isRead: true })
|
||||
.where(and(eq(notifications.uploadId, notification.uploadId), eq(notifications.userId, user.id)))
|
||||
})
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,52 @@
|
||||
import { and, count, desc, eq, max } from 'drizzle-orm'
|
||||
import { comments, notifications, uploads, users } from '../../db/schema'
|
||||
import { mentionedUserIds } from '../../../shared/utils/mentions'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await getSessionUser(event)
|
||||
if (!user) {
|
||||
return { notifications: [], unreadCount: 0 }
|
||||
}
|
||||
const db = useDb()
|
||||
const threads = db.select({ id: max(notifications.id).as('thread_notification_id') }).from(notifications)
|
||||
.where(and(eq(notifications.userId, user.id), eq(notifications.isRead, false)))
|
||||
.groupBy(notifications.uploadId).as('thread_notifications')
|
||||
const [total] = await db.select({ count: count() }).from(threads)
|
||||
const rows = await db
|
||||
.select({
|
||||
id: notifications.id,
|
||||
uploadId: notifications.uploadId,
|
||||
commentId: notifications.commentId,
|
||||
isRead: notifications.isRead,
|
||||
createdAt: notifications.createdAt,
|
||||
actorName: users.name,
|
||||
actorColor: users.color,
|
||||
content: comments.content,
|
||||
uploadType: uploads.type,
|
||||
fileName: uploads.fileName,
|
||||
externalUrl: uploads.externalUrl,
|
||||
previewImage: uploads.previewImage,
|
||||
})
|
||||
.from(notifications)
|
||||
.innerJoin(threads, eq(notifications.id, threads.id))
|
||||
.innerJoin(users, eq(notifications.actorId, users.id))
|
||||
.innerJoin(comments, eq(notifications.commentId, comments.id))
|
||||
.innerJoin(uploads, eq(notifications.uploadId, uploads.id))
|
||||
.where(and(eq(notifications.userId, user.id), eq(notifications.isRead, false)))
|
||||
.orderBy(desc(notifications.createdAt), desc(notifications.id))
|
||||
.limit(30)
|
||||
const mentionUsers = rows.some(row => row.content.includes('@'))
|
||||
? await db.select({ id: users.id, name: users.name, color: users.color }).from(users)
|
||||
: []
|
||||
return {
|
||||
notifications: rows.map((row) => {
|
||||
const url = row.externalUrl ?? `/uploads/${row.fileName}`
|
||||
const embedId = row.uploadType === 'youtube' && row.externalUrl ? getYoutubeId(row.externalUrl) : null
|
||||
const thumbUrl = row.uploadType === 'youtube' && embedId
|
||||
? youtubeThumbUrl(embedId)
|
||||
: row.uploadType === 'image' ? url : row.uploadType === 'link' ? row.previewImage : null
|
||||
return { ...row, url, thumbUrl, isMention: mentionedUserIds(row.content, mentionUsers).has(user.id) }
|
||||
}),
|
||||
unreadCount: Number(total?.count ?? 0),
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
import { and, eq } from 'drizzle-orm'
|
||||
import { notifications } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
await useDb()
|
||||
.update(notifications)
|
||||
.set({ isRead: true })
|
||||
.where(and(eq(notifications.userId, user.id), eq(notifications.isRead, false)))
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
import { count, desc, eq, like } from 'drizzle-orm'
|
||||
import { tags, uploadTags } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const q = String(getQuery(event).q ?? '').trim().toLowerCase().slice(0, 64)
|
||||
const db = useDb()
|
||||
|
||||
const rows = await db
|
||||
.select({ name: tags.name, count: count(uploadTags.uploadId) })
|
||||
.from(tags)
|
||||
.leftJoin(uploadTags, eq(uploadTags.tagId, tags.id))
|
||||
.where(q ? like(tags.name, `${q}%`) : undefined)
|
||||
.groupBy(tags.id, tags.name)
|
||||
.orderBy(desc(count(uploadTags.uploadId)), tags.name)
|
||||
.limit(15)
|
||||
|
||||
return rows
|
||||
})
|
||||
@@ -0,0 +1,40 @@
|
||||
import { unlink } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { commentAttachments, comments, uploads } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await requirePermission(event, 'upload.delete')
|
||||
const id = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,16}$/.test(id)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
|
||||
const [upload] = await db
|
||||
.select({ fileName: uploads.fileName })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.id, id))
|
||||
.limit(1)
|
||||
if (!upload) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
|
||||
const attachmentFiles = await db
|
||||
.select({ fileName: commentAttachments.fileName, cover: commentAttachments.cover })
|
||||
.from(commentAttachments)
|
||||
.innerJoin(comments, eq(commentAttachments.commentId, comments.id))
|
||||
.where(eq(comments.uploadId, id))
|
||||
|
||||
await db.delete(uploads).where(eq(uploads.id, id))
|
||||
if (upload.fileName) {
|
||||
await unlink(join(uploadDir(), upload.fileName)).catch(() => {})
|
||||
}
|
||||
for (const f of attachmentFiles) {
|
||||
await unlink(join(uploadDir(), 'attachments', f.fileName)).catch(() => {})
|
||||
if (f.cover) {
|
||||
await unlink(join(process.cwd(), 'public', f.cover)).catch(() => {})
|
||||
}
|
||||
}
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -0,0 +1,183 @@
|
||||
import { and, asc, desc, eq, gt, inArray, lt, or } from 'drizzle-orm'
|
||||
import { commentAttachments, commentReactions, comments, favorites, tags, threadSubscriptions, uploads, uploadReactions, uploadTags, users } from '../../db/schema'
|
||||
import type { CommentAttachment } from '~~/shared/utils/attachments'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,16}$/.test(id)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
|
||||
const uploadRows = await db
|
||||
.select({
|
||||
id: uploads.id,
|
||||
type: uploads.type,
|
||||
fileName: uploads.fileName,
|
||||
externalUrl: uploads.externalUrl,
|
||||
originalName: uploads.originalName,
|
||||
mimeType: uploads.mimeType,
|
||||
previewImage: uploads.previewImage,
|
||||
previewTitle: uploads.previewTitle,
|
||||
audioMeta: uploads.audioMeta,
|
||||
createdAt: uploads.createdAt,
|
||||
userName: users.name,
|
||||
userId: users.id,
|
||||
userColor: users.color,
|
||||
userAvatar: users.avatar,
|
||||
userCardEffect: users.cardEffect,
|
||||
userCardEffectColor: users.cardEffectColor,
|
||||
userCardVignette: users.cardVignette,
|
||||
userCardBorderEffect: users.cardBorderEffect,
|
||||
userCardBorderEffectColor: users.cardBorderEffectColor,
|
||||
})
|
||||
.from(uploads)
|
||||
.innerJoin(users, eq(uploads.userId, users.id))
|
||||
.where(eq(uploads.id, id))
|
||||
.limit(1)
|
||||
const upload = uploadRows[0]
|
||||
if (!upload) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
|
||||
const commentRows = await db
|
||||
.select({
|
||||
id: comments.id,
|
||||
content: comments.content,
|
||||
createdAt: comments.createdAt,
|
||||
userName: users.name,
|
||||
userId: users.id,
|
||||
userColor: users.color,
|
||||
userAvatar: users.avatar,
|
||||
})
|
||||
.from(comments)
|
||||
.innerJoin(users, eq(comments.userId, users.id))
|
||||
.where(eq(comments.uploadId, id))
|
||||
.orderBy(asc(comments.createdAt))
|
||||
|
||||
// Nachbarn in Grid-Reihenfolge (createdAt desc, id desc als Tiebreak)
|
||||
const sessionUser = await getSessionUser(event)
|
||||
const commentIds = commentRows.map(c => c.id)
|
||||
const [reactionRows, uploadReactionRows, favRows, newerRows, olderRows, tagRows, attachmentRows, subscriptionRows] = await Promise.all([
|
||||
commentIds.length
|
||||
? db
|
||||
.select({
|
||||
commentId: commentReactions.commentId,
|
||||
emoji: commentReactions.emoji,
|
||||
userId: commentReactions.userId,
|
||||
userName: users.name,
|
||||
})
|
||||
.from(commentReactions)
|
||||
.innerJoin(users, eq(commentReactions.userId, users.id))
|
||||
.where(inArray(commentReactions.commentId, commentIds))
|
||||
.orderBy(asc(commentReactions.createdAt))
|
||||
: Promise.resolve([]),
|
||||
db
|
||||
.select({
|
||||
emoji: uploadReactions.emoji,
|
||||
userId: uploadReactions.userId,
|
||||
userName: users.name,
|
||||
})
|
||||
.from(uploadReactions)
|
||||
.innerJoin(users, eq(uploadReactions.userId, users.id))
|
||||
.where(eq(uploadReactions.uploadId, id))
|
||||
.orderBy(asc(uploadReactions.createdAt)),
|
||||
db
|
||||
.select({ id: users.id, name: users.name, color: users.color, avatar: users.avatar })
|
||||
.from(favorites)
|
||||
.innerJoin(users, eq(favorites.userId, users.id))
|
||||
.where(eq(favorites.uploadId, id))
|
||||
.orderBy(desc(favorites.createdAt)),
|
||||
db
|
||||
.select({ id: uploads.id })
|
||||
.from(uploads)
|
||||
.where(or(
|
||||
gt(uploads.createdAt, upload.createdAt),
|
||||
and(eq(uploads.createdAt, upload.createdAt), gt(uploads.id, upload.id)),
|
||||
))
|
||||
.orderBy(asc(uploads.createdAt), asc(uploads.id))
|
||||
.limit(1),
|
||||
db
|
||||
.select({ id: uploads.id })
|
||||
.from(uploads)
|
||||
.where(or(
|
||||
lt(uploads.createdAt, upload.createdAt),
|
||||
and(eq(uploads.createdAt, upload.createdAt), lt(uploads.id, upload.id)),
|
||||
))
|
||||
.orderBy(desc(uploads.createdAt), desc(uploads.id))
|
||||
.limit(1),
|
||||
db
|
||||
.select({ name: tags.name })
|
||||
.from(uploadTags)
|
||||
.innerJoin(tags, eq(uploadTags.tagId, tags.id))
|
||||
.where(eq(uploadTags.uploadId, id))
|
||||
.orderBy(asc(tags.name)),
|
||||
commentIds.length
|
||||
? db
|
||||
.select()
|
||||
.from(commentAttachments)
|
||||
.where(inArray(commentAttachments.commentId, commentIds))
|
||||
.orderBy(asc(commentAttachments.id))
|
||||
: Promise.resolve([]),
|
||||
sessionUser
|
||||
? db.select({ enabled: threadSubscriptions.enabled }).from(threadSubscriptions)
|
||||
.where(and(eq(threadSubscriptions.uploadId, id), eq(threadSubscriptions.userId, sessionUser.id))).limit(1)
|
||||
: Promise.resolve([]),
|
||||
])
|
||||
|
||||
const attachmentsByComment = new Map<number, CommentAttachment[]>()
|
||||
for (const a of attachmentRows) {
|
||||
let list = attachmentsByComment.get(a.commentId)
|
||||
if (!list) {
|
||||
list = []
|
||||
attachmentsByComment.set(a.commentId, list)
|
||||
}
|
||||
list.push({ id: a.id, name: a.originalName, url: `/uploads/attachments/${a.fileName}`, mimeType: a.mimeType, size: a.size, cover: a.cover, meta: a.meta as CommentAttachment['meta'] })
|
||||
}
|
||||
|
||||
const reactionsByComment = new Map<number, { emoji: string, count: number, me: boolean, names: string[] }[]>()
|
||||
for (const r of reactionRows) {
|
||||
let list = reactionsByComment.get(r.commentId)
|
||||
if (!list) {
|
||||
list = []
|
||||
reactionsByComment.set(r.commentId, list)
|
||||
}
|
||||
let entry = list.find(e => e.emoji === r.emoji)
|
||||
if (!entry) {
|
||||
entry = { emoji: r.emoji, count: 0, me: false, names: [] }
|
||||
list.push(entry)
|
||||
}
|
||||
entry.count += 1
|
||||
entry.names.push(r.userName)
|
||||
if (r.userId === sessionUser?.id) entry.me = true
|
||||
}
|
||||
|
||||
const uploadReactionList: { emoji: string, count: number, me: boolean, names: string[] }[] = []
|
||||
for (const r of uploadReactionRows) {
|
||||
let entry = uploadReactionList.find(e => e.emoji === r.emoji)
|
||||
if (!entry) {
|
||||
entry = { emoji: r.emoji, count: 0, me: false, names: [] }
|
||||
uploadReactionList.push(entry)
|
||||
}
|
||||
entry.count += 1
|
||||
entry.names.push(r.userName)
|
||||
if (r.userId === sessionUser?.id) entry.me = true
|
||||
}
|
||||
|
||||
const url = upload.externalUrl ?? `/uploads/${upload.fileName}`
|
||||
const embedId = upload.type === 'youtube' && upload.externalUrl
|
||||
? getYoutubeId(upload.externalUrl)
|
||||
: upload.type === 'twitch' && upload.externalUrl
|
||||
? serializeTwitchTarget(getTwitchTarget(upload.externalUrl))
|
||||
: null
|
||||
return {
|
||||
upload: { ...upload, url, embedId, userAvatarUrl: avatarUrl(upload.userAvatar), tags: tagRows.map(t => t.name) },
|
||||
comments: commentRows.map(c => ({ ...c, userAvatarUrl: avatarUrl(c.userAvatar), reactions: reactionsByComment.get(c.id) ?? [], attachments: attachmentsByComment.get(c.id) ?? [] })),
|
||||
uploadReactions: uploadReactionList,
|
||||
favoritedBy: favRows.map(f => ({ id: f.id, name: f.name, color: f.color, avatarUrl: avatarUrl(f.avatar) })),
|
||||
isFavorited: sessionUser ? favRows.some(f => f.id === sessionUser.id) : false,
|
||||
isSubscribed: subscriptionRows[0]?.enabled ?? false,
|
||||
newerId: newerRows[0]?.id ?? null,
|
||||
olderId: olderRows[0]?.id ?? null,
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,130 @@
|
||||
import { mkdir, writeFile } from 'node:fs/promises'
|
||||
import { extname, join } from 'node:path'
|
||||
import { eq, sql } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { commentAttachments, comments, uploads } from '../../../db/schema'
|
||||
import { isAudioAttachment, MAX_COMMENT_ATTACHMENTS } from '~~/shared/utils/attachments'
|
||||
|
||||
const bodySchema = z.object({
|
||||
content: z.string().trim().min(1).max(2000),
|
||||
})
|
||||
|
||||
const attachmentsDir = () => join(uploadDir(), 'attachments')
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const id = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,16}$/.test(id)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
|
||||
let content: string
|
||||
let files: { filename: string, type: string | undefined, data: Buffer, voice: boolean }[] = []
|
||||
|
||||
if ((getRequestHeader(event, 'content-type') ?? '').includes('multipart/form-data')) {
|
||||
const parts = await readMultipartFormData(event)
|
||||
content = (parts?.find(p => p.name === 'content' && !p.filename)?.data.toString('utf8') ?? '').trim()
|
||||
files = (parts ?? [])
|
||||
.filter(p => (p.name === 'files' || p.name === 'voice') && p.filename && p.data?.length)
|
||||
.map(p => ({ filename: p.filename!, type: p.type, data: p.data, voice: p.name === 'voice' }))
|
||||
if (files.length > MAX_COMMENT_ATTACHMENTS) {
|
||||
throw createError({ statusCode: 400, statusMessage: `Maximal ${MAX_COMMENT_ATTACHMENTS} Anhänge pro Kommentar` })
|
||||
}
|
||||
if (files.some(f => f.data.length > MAX_UPLOAD_SIZE)) {
|
||||
throw createError({ statusCode: 413, statusMessage: 'Anhang ist zu groß (max. 200 MB)' })
|
||||
}
|
||||
if (!content && !files.length) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Kommentar darf nicht leer sein' })
|
||||
}
|
||||
if (content.length > 2000) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Kommentar ist zu lang (max. 2000 Zeichen)' })
|
||||
}
|
||||
}
|
||||
else {
|
||||
content = (await readValidatedBody(event, bodySchema.parse)).content
|
||||
}
|
||||
|
||||
const exists = await db
|
||||
.select({ id: uploads.id })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.id, id))
|
||||
.limit(1)
|
||||
if (!exists.length) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
|
||||
const commentId = await db.transaction(async (tx) => {
|
||||
const [result] = await tx.insert(comments).values({ uploadId: id, userId: user.id, content })
|
||||
await ensureThreadSubscription(id, user.id, tx)
|
||||
return Number(result.insertId)
|
||||
})
|
||||
await db.update(uploads).set({ commentCount: sql`comment_count + 1` }).where(eq(uploads.id, id))
|
||||
|
||||
const attachments: { id: number, name: string, url: string, mimeType: string | null, size: number, cover: string | null, meta: unknown }[] = []
|
||||
if (files.length) {
|
||||
await mkdir(attachmentsDir(), { recursive: true })
|
||||
for (const [i, file] of files.entries()) {
|
||||
let data = file.data
|
||||
let filename = file.filename
|
||||
let mimeType = (file.type || 'application/octet-stream').slice(0, 100)
|
||||
if (file.voice) {
|
||||
const mp3 = await transcodeVoiceToMp3(data)
|
||||
if (mp3) {
|
||||
data = mp3
|
||||
mimeType = 'audio/mpeg'
|
||||
filename = filename.replace(/\.[^./]+$/, '') + '.mp3'
|
||||
}
|
||||
}
|
||||
const ext = extname(filename).toLowerCase().replace(/[^a-z0-9.]/g, '').slice(0, 10)
|
||||
const storedName = `${commentId}-${i}${ext}`
|
||||
await writeFile(join(attachmentsDir(), storedName), data)
|
||||
const audioMeta = !file.voice && isAudioAttachment({ mimeType, name: filename })
|
||||
? await extractAudioMeta(`att-${commentId}-${i}`, data, mimeType)
|
||||
: null
|
||||
const meta = file.voice ? { voice: true } : (audioMeta?.meta ?? null)
|
||||
const [row] = await db.insert(commentAttachments).values({
|
||||
commentId,
|
||||
fileName: storedName,
|
||||
originalName: filename.slice(0, 255),
|
||||
mimeType,
|
||||
size: data.length,
|
||||
cover: audioMeta?.cover ?? null,
|
||||
meta,
|
||||
})
|
||||
attachments.push({
|
||||
id: Number(row.insertId),
|
||||
name: filename.slice(0, 255),
|
||||
url: `/uploads/attachments/${storedName}`,
|
||||
mimeType,
|
||||
size: data.length,
|
||||
cover: audioMeta?.cover ?? null,
|
||||
meta,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const createdAt = new Date()
|
||||
broadcastToAll({
|
||||
type: 'comment',
|
||||
comment: {
|
||||
id: commentId,
|
||||
content,
|
||||
createdAt: createdAt.toISOString(),
|
||||
userName: user.name,
|
||||
userId: user.id,
|
||||
userColor: user.color,
|
||||
userAvatarUrl: avatarUrl(user.avatar),
|
||||
uploadId: id,
|
||||
attachments,
|
||||
},
|
||||
})
|
||||
await notifyComment(user.id, commentId, id, content || '[Anhang]')
|
||||
return {
|
||||
id: commentId,
|
||||
content,
|
||||
attachments,
|
||||
userName: user.name,
|
||||
createdAt: new Date(),
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,51 @@
|
||||
import { and, desc, eq } from 'drizzle-orm'
|
||||
import { favorites, threadSubscriptions, uploads, users } from '../../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const id = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,16}$/.test(id)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const db = useDb()
|
||||
|
||||
const exists = await db
|
||||
.select({ id: uploads.id })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.id, id))
|
||||
.limit(1)
|
||||
if (!exists.length) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
|
||||
const existing = await db
|
||||
.select()
|
||||
.from(favorites)
|
||||
.where(and(eq(favorites.uploadId, id), eq(favorites.userId, user.id)))
|
||||
.limit(1)
|
||||
|
||||
if (existing.length) {
|
||||
await db.delete(favorites).where(and(eq(favorites.uploadId, id), eq(favorites.userId, user.id)))
|
||||
}
|
||||
else {
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.insert(favorites).values({ uploadId: id, userId: user.id })
|
||||
await ensureThreadSubscription(id, user.id, tx)
|
||||
})
|
||||
}
|
||||
|
||||
const favRows = await db
|
||||
.select({ id: users.id, name: users.name, color: users.color, avatar: users.avatar })
|
||||
.from(favorites)
|
||||
.innerJoin(users, eq(favorites.userId, users.id))
|
||||
.where(eq(favorites.uploadId, id))
|
||||
.orderBy(desc(favorites.createdAt))
|
||||
|
||||
const [subscription] = await db.select({ enabled: threadSubscriptions.enabled }).from(threadSubscriptions)
|
||||
.where(and(eq(threadSubscriptions.uploadId, id), eq(threadSubscriptions.userId, user.id))).limit(1)
|
||||
return {
|
||||
isSubscribed: subscription?.enabled ?? false,
|
||||
favorited: !existing.length,
|
||||
favoritedBy: favRows.map(f => ({ id: f.id, name: f.name, color: f.color, avatarUrl: avatarUrl(f.avatar) })),
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,70 @@
|
||||
import { and, eq, sql } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { threadSubscriptions, uploadReactions, uploads } from '../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
emoji: z.string().min(1).max(32),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const uploadId = getRouterParam(event, 'id') ?? ''
|
||||
const { emoji } = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
|
||||
const [upload] = await db
|
||||
.select({ id: uploads.id })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.id, uploadId))
|
||||
.limit(1)
|
||||
if (!upload) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
|
||||
const existing = await db
|
||||
.select({ userId: uploadReactions.userId })
|
||||
.from(uploadReactions)
|
||||
.where(and(
|
||||
eq(uploadReactions.uploadId, uploadId),
|
||||
eq(uploadReactions.userId, user.id),
|
||||
eq(uploadReactions.emoji, emoji),
|
||||
))
|
||||
.limit(1)
|
||||
|
||||
let active: boolean
|
||||
if (existing.length) {
|
||||
await db.delete(uploadReactions).where(and(
|
||||
eq(uploadReactions.uploadId, uploadId),
|
||||
eq(uploadReactions.userId, user.id),
|
||||
eq(uploadReactions.emoji, emoji),
|
||||
))
|
||||
active = false
|
||||
}
|
||||
else {
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.insert(uploadReactions).values({ uploadId, userId: user.id, emoji })
|
||||
await ensureThreadSubscription(uploadId, user.id, tx)
|
||||
})
|
||||
active = true
|
||||
}
|
||||
|
||||
const [result] = await db
|
||||
.select({ total: sql<number>`count(*)` })
|
||||
.from(uploadReactions)
|
||||
.where(and(eq(uploadReactions.uploadId, uploadId), eq(uploadReactions.emoji, emoji)))
|
||||
const count = Number(result?.total ?? 0)
|
||||
|
||||
broadcastToAll({
|
||||
type: 'upload-reaction',
|
||||
uploadId,
|
||||
emoji,
|
||||
actorId: user.id,
|
||||
actorName: user.name,
|
||||
active,
|
||||
count,
|
||||
})
|
||||
|
||||
const [subscription] = await db.select({ enabled: threadSubscriptions.enabled }).from(threadSubscriptions)
|
||||
.where(and(eq(threadSubscriptions.uploadId, uploadId), eq(threadSubscriptions.userId, user.id))).limit(1)
|
||||
return { active, count, isSubscribed: subscription?.enabled ?? false }
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { threadSubscriptions, uploads, users } from '../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({ enabled: z.boolean() })
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const uploadId = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,8}$/.test(uploadId)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const { enabled } = await readValidatedBody(event, bodySchema.parse)
|
||||
const db = useDb()
|
||||
const [upload] = await db.select({ id: uploads.id }).from(uploads).where(eq(uploads.id, uploadId)).limit(1)
|
||||
if (!upload) throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.select({ id: users.id }).from(users).where(eq(users.id, user.id)).for('update')
|
||||
await tx.insert(threadSubscriptions).values({ uploadId, userId: user.id, enabled })
|
||||
.onDuplicateKeyUpdate({ set: { enabled } })
|
||||
})
|
||||
return { enabled }
|
||||
})
|
||||
@@ -0,0 +1,64 @@
|
||||
import { inArray, eq } from 'drizzle-orm'
|
||||
import { z } from 'zod'
|
||||
import { sql } from 'drizzle-orm'
|
||||
import { normalizeTagList, MAX_TAGS_PER_UPLOAD } from '../../../../shared/utils/tags'
|
||||
import { tags, uploads, uploadTags } from '../../../db/schema'
|
||||
|
||||
const bodySchema = z.object({
|
||||
tags: z.array(z.string().max(200)).max(MAX_TAGS_PER_UPLOAD),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^[A-Za-z0-9]{1,16}$/.test(id)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
|
||||
}
|
||||
const user = await requireUser(event)
|
||||
const db = useDb()
|
||||
|
||||
const upload = await db
|
||||
.select({ id: uploads.id, userId: uploads.userId })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.id, id))
|
||||
.limit(1)
|
||||
.then(r => r[0])
|
||||
if (!upload) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Upload nicht gefunden' })
|
||||
}
|
||||
const body = await readValidatedBody(event, bodySchema.parse)
|
||||
const names = normalizeTagList(body.tags)
|
||||
|
||||
// Tags hinzufügen darf jeder Eingeloggte — entfernen nur der Uploader
|
||||
// oder Rollen mit tag.delete-Recht
|
||||
const currentRows = await db
|
||||
.select({ name: tags.name })
|
||||
.from(uploadTags)
|
||||
.innerJoin(tags, eq(uploadTags.tagId, tags.id))
|
||||
.where(eq(uploadTags.uploadId, id))
|
||||
const currentNames = new Set(currentRows.map(r => r.name))
|
||||
const removed = currentNames.size ? [...currentNames].filter(n => !names.includes(n)) : []
|
||||
const canDeleteTags = upload.userId === user.id
|
||||
|| user.roles.includes('admin')
|
||||
|| user.permissions.includes('tag.delete')
|
||||
if (removed.length && !canDeleteTags) {
|
||||
throw createError({ statusCode: 403, statusMessage: 'Keine Berechtigung zum Entfernen von Tags' })
|
||||
}
|
||||
|
||||
// Tags finden oder anlegen
|
||||
if (names.length) {
|
||||
await db
|
||||
.insert(tags)
|
||||
.values(names.map(name => ({ name })))
|
||||
.onDuplicateKeyUpdate({ set: { name: sql`name` } })
|
||||
}
|
||||
const tagRows = names.length
|
||||
? await db.select({ id: tags.id, name: tags.name }).from(tags).where(inArray(tags.name, names))
|
||||
: []
|
||||
|
||||
await db.delete(uploadTags).where(eq(uploadTags.uploadId, id))
|
||||
if (tagRows.length) {
|
||||
await db.insert(uploadTags).values(tagRows.map(t => ({ uploadId: id, tagId: t.id })))
|
||||
}
|
||||
|
||||
return { tags: tagRows.map(t => t.name).sort() }
|
||||
})
|
||||
@@ -0,0 +1,71 @@
|
||||
import { and, desc, eq, gte, inArray } from 'drizzle-orm'
|
||||
import { tags, uploads, uploadTags, users } from '../../db/schema'
|
||||
import { normalizeTagName } from '../../../shared/utils/tags'
|
||||
|
||||
type UploadType = typeof uploads.$inferSelect['type']
|
||||
|
||||
// Leichtgewichtige Liste — Thumbnails und Kommentarzahlen lädt der Client
|
||||
// separat über /api/uploads/meta nach.
|
||||
// Pagination per Dense-Pack-Simulation: Der Client schickt, wie viele
|
||||
// Grid-Zellen auf den Bildschirm passen (cells) und wie breit das Grid ist
|
||||
// (cols). Tiles belegen je nach Modus/Kommentarzahl 1x1, 2x2 oder 3x3 Zellen.
|
||||
// grid-flow-dense platziert jedes Tile in die erste freie Position — was
|
||||
// nicht passt, wandert auf die nächste Seite. So passt jede Seite garantiert
|
||||
// ohne Scrollen in den Viewport, auch bei fragmentierten Zeilenenden.
|
||||
export default defineEventHandler(async (event) => {
|
||||
const db = useDb()
|
||||
const q = getQuery(event)
|
||||
const tag = normalizeTagName(String(q.tag ?? ''))
|
||||
const types = String(q.type ?? '')
|
||||
.split(',')
|
||||
.map(t => t.trim())
|
||||
.filter(t => (uploads.type.enumValues as readonly string[]).includes(t)) as UploadType[]
|
||||
const uploaderId = Number(q.uploader)
|
||||
const days = Number(q.days)
|
||||
const { page, cells, cols, uniform } = getGridPageParams(q)
|
||||
|
||||
const conditions = []
|
||||
if (tag) {
|
||||
conditions.push(inArray(
|
||||
uploads.id,
|
||||
db.select({ id: uploadTags.uploadId }).from(uploadTags)
|
||||
.innerJoin(tags, eq(uploadTags.tagId, tags.id))
|
||||
.where(eq(tags.name, tag)),
|
||||
))
|
||||
}
|
||||
if (types.length) conditions.push(inArray(uploads.type, types))
|
||||
if (Number.isInteger(uploaderId) && uploaderId > 0) conditions.push(eq(uploads.userId, uploaderId))
|
||||
if (Number.isFinite(days) && days > 0) {
|
||||
conditions.push(gte(uploads.createdAt, new Date(Date.now() - days * 86400_000)))
|
||||
}
|
||||
|
||||
// Alle Treffer holen (kleine Felder) und clientseitig dieselbe
|
||||
// Span-Logik wie UploadTile anwenden, um Seiten exakt zu füllen
|
||||
const rows = await db
|
||||
.select({
|
||||
id: uploads.id,
|
||||
type: uploads.type,
|
||||
fileName: uploads.fileName,
|
||||
externalUrl: uploads.externalUrl,
|
||||
commentCount: uploads.commentCount,
|
||||
createdAt: uploads.createdAt,
|
||||
userId: users.id,
|
||||
userName: users.name,
|
||||
userColor: users.color,
|
||||
userAvatar: users.avatar,
|
||||
})
|
||||
.from(uploads)
|
||||
.innerJoin(users, eq(uploads.userId, users.id))
|
||||
.where(conditions.length ? and(...conditions) : undefined)
|
||||
.orderBy(desc(uploads.createdAt))
|
||||
|
||||
const pages = paginateGrid(rows, r => gridTileDims(r.commentCount, uniform, cols), cells, cols)
|
||||
|
||||
const pageRows = pages[page - 1] ?? []
|
||||
const items = pageRows.map((row) => {
|
||||
const url = row.externalUrl ?? `/uploads/${row.fileName}`
|
||||
return { id: row.id, type: row.type, url, commentCount: row.commentCount, createdAt: row.createdAt, userId: row.userId, userName: row.userName, userColor: row.userColor, userAvatarUrl: avatarUrl(row.userAvatar) }
|
||||
})
|
||||
|
||||
return { items, total: rows.length, pageCount: pages.length }
|
||||
})
|
||||
@@ -0,0 +1,158 @@
|
||||
import { mkdir, writeFile } from 'node:fs/promises'
|
||||
import { basename, extname, join } from 'node:path'
|
||||
import { z } from 'zod'
|
||||
import { uploads } from '../../db/schema'
|
||||
|
||||
const MAX_SIZE = MAX_UPLOAD_SIZE
|
||||
|
||||
const MIME_EXT: Record<string, string> = {
|
||||
'image/jpeg': '.jpg',
|
||||
'image/png': '.png',
|
||||
'image/gif': '.gif',
|
||||
'image/webp': '.webp',
|
||||
'image/avif': '.avif',
|
||||
'video/mp4': '.mp4',
|
||||
'video/webm': '.webm',
|
||||
'video/quicktime': '.mov',
|
||||
'audio/mpeg': '.mp3',
|
||||
'audio/mp3': '.mp3',
|
||||
'audio/flac': '.flac',
|
||||
'audio/x-flac': '.flac',
|
||||
}
|
||||
|
||||
// Fallback, wenn der Browser keinen MIME-Type mitschickt
|
||||
const EXT_MIME: Record<string, string> = {
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
'.webp': 'image/webp',
|
||||
'.avif': 'image/avif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.mp4': 'video/mp4',
|
||||
'.webm': 'video/webm',
|
||||
'.mov': 'video/quicktime',
|
||||
'.mp3': 'audio/mpeg',
|
||||
'.flac': 'audio/flac',
|
||||
}
|
||||
|
||||
const urlSchema = z.object({
|
||||
url: z.url().max(2048),
|
||||
})
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const db = useDb()
|
||||
|
||||
if ((getRequestHeader(event, 'content-type') ?? '').includes('application/json')) {
|
||||
const body = await readValidatedBody(event, urlSchema.parse)
|
||||
if (!/^https?:\/\//i.test(body.url)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Nur http(s)-URLs erlaubt' })
|
||||
}
|
||||
const type = classifyUrl(body.url)
|
||||
const id = await newUploadId(db)
|
||||
|
||||
// Direkte Bild-/Video-URLs werden heruntergeladen und lokal gespeichert,
|
||||
// als wäre die Datei direkt hochgeladen worden
|
||||
if (type === 'image' || type === 'video' || type === 'audio') {
|
||||
const media = await downloadExternalMedia(body.url)
|
||||
const urlExt = extname(new URL(body.url).pathname).toLowerCase().replace(/[^a-z0-9.]/g, '').slice(0, 10)
|
||||
const ext = MIME_EXT[media.mimeType] ?? urlExt
|
||||
const fileName = `${id}${ext}`
|
||||
await mkdir(uploadDir(), { recursive: true })
|
||||
await writeFile(join(uploadDir(), fileName), media.data)
|
||||
const audioMeta = media.type === 'audio'
|
||||
? await extractAudioMeta(id, media.data, media.mimeType)
|
||||
: null
|
||||
await db.insert(uploads).values({
|
||||
id,
|
||||
userId: user.id,
|
||||
type: media.type,
|
||||
fileName,
|
||||
originalName: decodeURIComponent(basename(new URL(body.url).pathname) || body.url).slice(0, 255),
|
||||
mimeType: media.mimeType.slice(0, 100),
|
||||
size: media.data.length,
|
||||
previewImage: audioMeta?.cover ?? null,
|
||||
audioMeta: audioMeta?.meta ?? null,
|
||||
})
|
||||
await ensureThreadSubscription(id, user.id)
|
||||
return { id, type: media.type, url: `/uploads/${fileName}` }
|
||||
}
|
||||
|
||||
const twitchTarget = type === 'twitch' ? getTwitchTarget(body.url) : null
|
||||
const [preview, twitchPreview] = await Promise.all([
|
||||
type === 'link' || type === 'twitch' ? fetchLinkPreview(body.url) : null,
|
||||
twitchTarget ? fetchTwitchPreview(twitchTarget) : null,
|
||||
])
|
||||
const remotePreviewImage = twitchPreview?.image ?? preview?.image ?? null
|
||||
const previewImage = remotePreviewImage
|
||||
? (await savePreviewImage(id, remotePreviewImage)) ?? remotePreviewImage
|
||||
: null
|
||||
await db.insert(uploads).values({
|
||||
id,
|
||||
userId: user.id,
|
||||
type,
|
||||
externalUrl: body.url,
|
||||
originalName: body.url.slice(0, 255),
|
||||
previewImage,
|
||||
previewTitle: twitchPreview?.title ?? preview?.title ?? null,
|
||||
})
|
||||
await ensureThreadSubscription(id, user.id)
|
||||
return { id, type, url: body.url }
|
||||
}
|
||||
|
||||
const parts = await readMultipartFormData(event)
|
||||
const file = parts?.find(p => p.name === 'file')
|
||||
|
||||
if (!file?.data?.length) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Keine Datei hochgeladen' })
|
||||
}
|
||||
|
||||
// Manche Formate kommen ohne MIME-Type (z. B. .flac) — dann per Endung klassifizieren
|
||||
const fileExt = extname(file.filename ?? '').toLowerCase()
|
||||
const rawMime = file.type ?? ''
|
||||
const mimeType = rawMime && rawMime !== 'application/octet-stream' ? rawMime : (EXT_MIME[fileExt] ?? rawMime)
|
||||
const type = mimeType.startsWith('image/') ? 'image'
|
||||
: mimeType.startsWith('video/') ? 'video'
|
||||
: mimeType.startsWith('audio/') ? 'audio'
|
||||
: IMAGE_EXT.test(fileExt) ? 'image'
|
||||
: VIDEO_EXT.test(fileExt) ? 'video'
|
||||
: AUDIO_EXT.test(fileExt) ? 'audio'
|
||||
: null
|
||||
if (!type) {
|
||||
throw createError({ statusCode: 415, statusMessage: 'Nur Bilder, Videos und Audiodateien sind erlaubt' })
|
||||
}
|
||||
if (file.data.length > MAX_SIZE) {
|
||||
throw createError({ statusCode: 413, statusMessage: 'Datei ist zu groß (max. 200 MB)' })
|
||||
}
|
||||
|
||||
const ext = MIME_EXT[mimeType]
|
||||
?? fileExt.replace(/[^a-z0-9.]/g, '').slice(0, 10)
|
||||
?? ''
|
||||
const id = await newUploadId(db)
|
||||
const fileName = `${id}${ext}`
|
||||
|
||||
await mkdir(uploadDir(), { recursive: true })
|
||||
await writeFile(join(uploadDir(), fileName), file.data)
|
||||
const audioMeta = type === 'audio'
|
||||
? await extractAudioMeta(id, file.data, mimeType)
|
||||
: null
|
||||
await db.insert(uploads).values({
|
||||
id,
|
||||
userId: user.id,
|
||||
type,
|
||||
fileName,
|
||||
originalName: (file.filename ?? fileName).slice(0, 255),
|
||||
mimeType: (mimeType || 'application/octet-stream').slice(0, 100),
|
||||
size: file.data.length,
|
||||
previewImage: audioMeta?.cover ?? null,
|
||||
audioMeta: audioMeta?.meta ?? null,
|
||||
})
|
||||
|
||||
await ensureThreadSubscription(id, user.id)
|
||||
return {
|
||||
id,
|
||||
type,
|
||||
url: `/uploads/${fileName}`,
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import { inArray } from 'drizzle-orm'
|
||||
import { uploads } from '../../db/schema'
|
||||
|
||||
// Nachgeladene Thumbnails pro Upload für das Grid — bewusst ohne Joins,
|
||||
// die Kommentarzahl kommt denormalisiert direkt aus der Upload-Liste
|
||||
export default defineEventHandler(async (event) => {
|
||||
const ids = String(getQuery(event).ids ?? '')
|
||||
.split(',')
|
||||
.filter(id => /^[A-Za-z0-9]{1,16}$/.test(id))
|
||||
.slice(0, 200)
|
||||
if (!ids.length) return []
|
||||
|
||||
const db = useDb()
|
||||
const rows = await db
|
||||
.select({
|
||||
id: uploads.id,
|
||||
type: uploads.type,
|
||||
fileName: uploads.fileName,
|
||||
externalUrl: uploads.externalUrl,
|
||||
previewImage: uploads.previewImage,
|
||||
})
|
||||
.from(uploads)
|
||||
.where(inArray(uploads.id, ids))
|
||||
|
||||
return rows.map((row) => {
|
||||
const url = row.externalUrl ?? `/uploads/${row.fileName}`
|
||||
const embedId = row.type === 'youtube' && row.externalUrl ? getYoutubeId(row.externalUrl) : null
|
||||
const thumbUrl = row.type === 'youtube' && embedId
|
||||
? youtubeThumbUrl(embedId)
|
||||
: row.type === 'image' ? url : row.type === 'link' || row.type === 'twitch' || row.type === 'audio' ? row.previewImage : null
|
||||
return { id: row.id, thumbUrl }
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,49 @@
|
||||
import { count, eq } from 'drizzle-orm'
|
||||
import { comments, uploads, users } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const idParam = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^\d+$/.test(idParam)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Nutzer-ID' })
|
||||
}
|
||||
const userId = Number(idParam)
|
||||
|
||||
const db = useDb()
|
||||
const [user] = await db
|
||||
.select({ id: users.id, name: users.name, color: users.color, avatar: users.avatar, cardEffect: users.cardEffect, cardEffectColor: users.cardEffectColor, cardVignette: users.cardVignette, cardBorderEffect: users.cardBorderEffect, cardBorderEffectColor: users.cardBorderEffectColor, createdAt: users.createdAt })
|
||||
.from(users)
|
||||
.where(eq(users.id, userId))
|
||||
.limit(1)
|
||||
|
||||
if (!user) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Nutzer nicht gefunden' })
|
||||
}
|
||||
|
||||
const [uploadStats] = await db
|
||||
.select({ count: count() })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.userId, user.id))
|
||||
|
||||
const [commentStats] = await db
|
||||
.select({ count: count() })
|
||||
.from(comments)
|
||||
.where(eq(comments.userId, user.id))
|
||||
|
||||
return {
|
||||
user: {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
color: user.color,
|
||||
avatarUrl: avatarUrl(user.avatar),
|
||||
cardEffect: user.cardEffect,
|
||||
cardEffectColor: user.cardEffectColor, cardVignette: user.cardVignette,
|
||||
cardBorderEffect: user.cardBorderEffect,
|
||||
cardBorderEffectColor: user.cardBorderEffectColor,
|
||||
createdAt: user.createdAt,
|
||||
},
|
||||
stats: {
|
||||
uploads: uploadStats?.count ?? 0,
|
||||
comments: commentStats?.count ?? 0,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,85 @@
|
||||
import { asc, count, desc, eq, inArray } from 'drizzle-orm'
|
||||
import { commentAttachments, comments, uploads, users } from '../../../db/schema'
|
||||
import type { CommentAttachment } from '~~/shared/utils/attachments'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const idParam = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^\d+$/.test(idParam)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Nutzer-ID' })
|
||||
}
|
||||
const userId = Number(idParam)
|
||||
|
||||
const q = getQuery(event)
|
||||
const page = Math.max(1, Math.floor(Number(q.page)) || 1)
|
||||
const perPage = Math.min(100, Math.max(1, Math.floor(Number(q.perPage)) || 20))
|
||||
|
||||
const db = useDb()
|
||||
const [user] = await db
|
||||
.select({ id: users.id })
|
||||
.from(users)
|
||||
.where(eq(users.id, userId))
|
||||
.limit(1)
|
||||
|
||||
if (!user) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Nutzer nicht gefunden' })
|
||||
}
|
||||
|
||||
const [totalRow, rows] = await Promise.all([
|
||||
db.select({ count: count() }).from(comments).where(eq(comments.userId, userId)),
|
||||
db
|
||||
.select({
|
||||
id: comments.id,
|
||||
content: comments.content,
|
||||
createdAt: comments.createdAt,
|
||||
uploadId: uploads.id,
|
||||
uploadType: uploads.type,
|
||||
uploadFileName: uploads.fileName,
|
||||
uploadExternalUrl: uploads.externalUrl,
|
||||
uploadPreviewImage: uploads.previewImage,
|
||||
})
|
||||
.from(comments)
|
||||
.innerJoin(uploads, eq(comments.uploadId, uploads.id))
|
||||
.where(eq(comments.userId, userId))
|
||||
.orderBy(desc(comments.createdAt))
|
||||
.limit(perPage)
|
||||
.offset((page - 1) * perPage),
|
||||
])
|
||||
|
||||
const total = totalRow[0]?.count ?? 0
|
||||
|
||||
const commentIds = rows.map(r => r.id)
|
||||
const attachmentRows = commentIds.length
|
||||
? await db
|
||||
.select()
|
||||
.from(commentAttachments)
|
||||
.where(inArray(commentAttachments.commentId, commentIds))
|
||||
.orderBy(asc(commentAttachments.id))
|
||||
: []
|
||||
const attachmentsByComment = new Map<number, CommentAttachment[]>()
|
||||
for (const a of attachmentRows) {
|
||||
let list = attachmentsByComment.get(a.commentId)
|
||||
if (!list) {
|
||||
list = []
|
||||
attachmentsByComment.set(a.commentId, list)
|
||||
}
|
||||
list.push({ id: a.id, name: a.originalName, url: `/uploads/attachments/${a.fileName}`, mimeType: a.mimeType, size: a.size, cover: a.cover, meta: a.meta as CommentAttachment['meta'] })
|
||||
}
|
||||
|
||||
const items = rows.map((row) => {
|
||||
const url = row.uploadExternalUrl ?? `/uploads/${row.uploadFileName}`
|
||||
const embedId = row.uploadType === 'youtube' && row.uploadExternalUrl ? getYoutubeId(row.uploadExternalUrl) : null
|
||||
const uploadThumbUrl = row.uploadType === 'youtube' && embedId
|
||||
? youtubeThumbUrl(embedId)
|
||||
: row.uploadType === 'image' ? url : row.uploadType === 'link' || row.uploadType === 'twitch' || row.uploadType === 'audio' ? row.uploadPreviewImage : null
|
||||
return {
|
||||
id: row.id,
|
||||
content: row.content,
|
||||
createdAt: row.createdAt,
|
||||
uploadId: row.uploadId,
|
||||
uploadThumbUrl,
|
||||
attachments: attachmentsByComment.get(row.id) ?? [],
|
||||
}
|
||||
})
|
||||
|
||||
return { items, total, pageCount: Math.max(1, Math.ceil(total / perPage)) }
|
||||
})
|
||||
@@ -0,0 +1,47 @@
|
||||
import { count, eq } from 'drizzle-orm'
|
||||
import { comments, uploads, users } from '../../../db/schema'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const idParam = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^\d+$/.test(idParam)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Nutzer-ID' })
|
||||
}
|
||||
const userId = Number(idParam)
|
||||
|
||||
const db = useDb()
|
||||
const [user] = await db
|
||||
.select({ id: users.id, name: users.name, color: users.color, avatar: users.avatar, cardEffect: users.cardEffect, cardEffectColor: users.cardEffectColor, cardVignette: users.cardVignette, cardBorderEffect: users.cardBorderEffect, cardBorderEffectColor: users.cardBorderEffectColor, createdAt: users.createdAt })
|
||||
.from(users)
|
||||
.where(eq(users.id, userId))
|
||||
.limit(1)
|
||||
|
||||
if (!user) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Nutzer nicht gefunden' })
|
||||
}
|
||||
|
||||
const [uploadStats] = await db
|
||||
.select({ count: count() })
|
||||
.from(uploads)
|
||||
.where(eq(uploads.userId, user.id))
|
||||
|
||||
const [commentStats] = await db
|
||||
.select({ count: count() })
|
||||
.from(comments)
|
||||
.where(eq(comments.userId, user.id))
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
color: user.color,
|
||||
cardEffect: user.cardEffect,
|
||||
cardEffectColor: user.cardEffectColor, cardVignette: user.cardVignette,
|
||||
cardBorderEffect: user.cardBorderEffect,
|
||||
cardBorderEffectColor: user.cardBorderEffectColor,
|
||||
avatarUrl: avatarUrl(user.avatar),
|
||||
createdAt: user.createdAt,
|
||||
stats: {
|
||||
uploads: uploadStats?.count ?? 0,
|
||||
comments: commentStats?.count ?? 0,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,47 @@
|
||||
import { desc, eq } from 'drizzle-orm'
|
||||
import { uploads, users } from '../../../db/schema'
|
||||
|
||||
// Upload-Liste eines Nutzers mit Viewport-Pagination (wie /api/uploads).
|
||||
// thumbUrl wird hier serverseitig mitgeliefert — kein separater Meta-Call.
|
||||
export default defineEventHandler(async (event) => {
|
||||
const idParam = getRouterParam(event, 'id') ?? ''
|
||||
if (!/^\d+$/.test(idParam)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Nutzer-ID' })
|
||||
}
|
||||
const userId = Number(idParam)
|
||||
|
||||
const q = getQuery(event)
|
||||
const { page, cells, cols, uniform } = getGridPageParams(q)
|
||||
|
||||
const db = useDb()
|
||||
const rows = await db
|
||||
.select({
|
||||
id: uploads.id,
|
||||
type: uploads.type,
|
||||
fileName: uploads.fileName,
|
||||
externalUrl: uploads.externalUrl,
|
||||
previewImage: uploads.previewImage,
|
||||
commentCount: uploads.commentCount,
|
||||
createdAt: uploads.createdAt,
|
||||
userName: users.name,
|
||||
userColor: users.color,
|
||||
userAvatar: users.avatar,
|
||||
})
|
||||
.from(uploads)
|
||||
.innerJoin(users, eq(uploads.userId, users.id))
|
||||
.where(eq(uploads.userId, userId))
|
||||
.orderBy(desc(uploads.createdAt))
|
||||
|
||||
const pages = paginateGrid(rows, r => gridTileDims(r.commentCount, uniform, cols), cells, cols)
|
||||
|
||||
const items = (pages[page - 1] ?? []).map((row) => {
|
||||
const url = row.externalUrl ?? `/uploads/${row.fileName}`
|
||||
const embedId = row.type === 'youtube' && row.externalUrl ? getYoutubeId(row.externalUrl) : null
|
||||
const thumbUrl = row.type === 'youtube' && embedId
|
||||
? youtubeThumbUrl(embedId)
|
||||
: row.type === 'image' ? url : row.type === 'link' || row.type === 'twitch' || row.type === 'audio' ? row.previewImage : null
|
||||
return { ...row, url, thumbUrl, userAvatarUrl: avatarUrl(row.userAvatar) }
|
||||
})
|
||||
|
||||
return { items, total: rows.length, pageCount: pages.length }
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
import { asc, count } from 'drizzle-orm'
|
||||
import { comments, uploads, users } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const db = useDb()
|
||||
|
||||
const rows = await db
|
||||
.select({
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
color: users.color,
|
||||
avatar: users.avatar,
|
||||
cardEffect: users.cardEffect,
|
||||
cardEffectColor: users.cardEffectColor, cardVignette: users.cardVignette,
|
||||
cardBorderEffect: users.cardBorderEffect,
|
||||
cardBorderEffectColor: users.cardBorderEffectColor,
|
||||
createdAt: users.createdAt,
|
||||
})
|
||||
.from(users)
|
||||
.orderBy(asc(users.id))
|
||||
|
||||
const [uploadStats, commentStats] = await Promise.all([
|
||||
db.select({ userId: uploads.userId, count: count() }).from(uploads).groupBy(uploads.userId),
|
||||
db.select({ userId: comments.userId, count: count() }).from(comments).groupBy(comments.userId),
|
||||
])
|
||||
const uploadCount = new Map(uploadStats.map(s => [s.userId, s.count]))
|
||||
const commentCount = new Map(commentStats.map(s => [s.userId, s.count]))
|
||||
|
||||
return rows.map(u => ({
|
||||
id: u.id,
|
||||
name: u.name,
|
||||
color: u.color,
|
||||
avatarUrl: avatarUrl(u.avatar),
|
||||
cardEffect: u.cardEffect,
|
||||
cardEffectColor: u.cardEffectColor, cardVignette: u.cardVignette,
|
||||
cardBorderEffect: u.cardBorderEffect,
|
||||
cardBorderEffectColor: u.cardBorderEffectColor,
|
||||
createdAt: u.createdAt,
|
||||
stats: {
|
||||
uploads: uploadCount.get(u.id) ?? 0,
|
||||
comments: commentCount.get(u.id) ?? 0,
|
||||
},
|
||||
}))
|
||||
})
|
||||
@@ -0,0 +1,125 @@
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { mkdir, unlink, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { isCardBorderEffect } from '../../../shared/utils/cardBorderEffects'
|
||||
import { isCardEffect } from '../../../shared/utils/cardEffects'
|
||||
import { users } from '../../db/schema'
|
||||
|
||||
const AVATAR_MIME_EXT: Record<string, string> = {
|
||||
'image/jpeg': '.jpg',
|
||||
'image/png': '.png',
|
||||
'image/gif': '.gif',
|
||||
'image/webp': '.webp',
|
||||
'image/avif': '.avif',
|
||||
}
|
||||
|
||||
const MAX_AVATAR_SIZE = 5 * 1024 * 1024 // 5 MB
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event)
|
||||
const parts = await readMultipartFormData(event)
|
||||
|
||||
const colorField = parts?.find(p => p.name === 'color')?.data.toString('utf8').trim()
|
||||
const cardEffectField = parts?.find(p => p.name === 'cardEffect')?.data.toString('utf8').trim()
|
||||
const cardEffectColorField = parts?.find(p => p.name === 'cardEffectColor')?.data.toString('utf8').trim()
|
||||
const cardVignetteField = parts?.find(p => p.name === 'cardVignette')?.data.toString('utf8').trim()
|
||||
const cardBorderEffectField = parts?.find(p => p.name === 'cardBorderEffect')?.data.toString('utf8').trim()
|
||||
const cardBorderEffectColorField = parts?.find(p => p.name === 'cardBorderEffectColor')?.data.toString('utf8').trim()
|
||||
const avatarFile = parts?.find(p => p.name === 'avatar')
|
||||
|
||||
let color: string | null | undefined
|
||||
if (colorField !== undefined) {
|
||||
if (colorField === '') {
|
||||
color = null
|
||||
}
|
||||
else if (/^#[0-9a-fA-F]{6}$/.test(colorField)) {
|
||||
color = colorField.toLowerCase()
|
||||
}
|
||||
else {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Farbe' })
|
||||
}
|
||||
}
|
||||
|
||||
let cardEffect: string | null | undefined
|
||||
if (cardEffectField !== undefined) {
|
||||
if (cardEffectField === '') {
|
||||
cardEffect = null
|
||||
}
|
||||
else if (isCardEffect(cardEffectField)) {
|
||||
cardEffect = cardEffectField
|
||||
}
|
||||
else {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültiger Effekt' })
|
||||
}
|
||||
}
|
||||
|
||||
let cardBorderEffect: string | null | undefined
|
||||
if (cardBorderEffectField !== undefined) {
|
||||
if (cardBorderEffectField === '') {
|
||||
cardBorderEffect = null
|
||||
}
|
||||
else if (isCardBorderEffect(cardBorderEffectField)) {
|
||||
cardBorderEffect = cardBorderEffectField
|
||||
}
|
||||
else {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültiger Border-Effekt' })
|
||||
}
|
||||
}
|
||||
|
||||
const parseOptionalColor = (field: string | undefined): string | null | undefined => {
|
||||
if (field === undefined) return undefined
|
||||
if (field === '') return null
|
||||
if (/^#[0-9a-fA-F]{6}$/.test(field)) return field.toLowerCase()
|
||||
throw createError({ statusCode: 400, statusMessage: 'Ungültige Effekt-Farbe' })
|
||||
}
|
||||
const cardEffectColor = parseOptionalColor(cardEffectColorField)
|
||||
const cardBorderEffectColor = parseOptionalColor(cardBorderEffectColorField)
|
||||
const cardVignette = cardVignetteField === undefined ? undefined : cardVignetteField === '1'
|
||||
|
||||
let avatarName: string | undefined
|
||||
if (avatarFile?.data?.length && avatarFile.type) {
|
||||
const ext = AVATAR_MIME_EXT[avatarFile.type]
|
||||
if (!ext) {
|
||||
throw createError({ statusCode: 415, statusMessage: 'Nur Bilder sind als Avatar erlaubt' })
|
||||
}
|
||||
if (avatarFile.data.length > MAX_AVATAR_SIZE) {
|
||||
throw createError({ statusCode: 413, statusMessage: 'Avatar ist zu groß (max. 5 MB)' })
|
||||
}
|
||||
avatarName = `${randomUUID()}${ext}`
|
||||
await mkdir(avatarDir(), { recursive: true })
|
||||
await writeFile(join(avatarDir(), avatarName), avatarFile.data)
|
||||
}
|
||||
|
||||
const db = useDb()
|
||||
await db.update(users).set({
|
||||
...(color !== undefined && { color }),
|
||||
...(cardEffect !== undefined && { cardEffect }),
|
||||
...(cardEffectColor !== undefined && { cardEffectColor }),
|
||||
...(cardVignette !== undefined && { cardVignette }),
|
||||
...(cardBorderEffect !== undefined && { cardBorderEffect }),
|
||||
...(cardBorderEffectColor !== undefined && { cardBorderEffectColor }),
|
||||
...(avatarName && { avatar: avatarName }),
|
||||
}).where(eq(users.id, user.id))
|
||||
|
||||
if (avatarName && user.avatar) {
|
||||
await unlink(join(avatarDir(), user.avatar)).catch(() => {})
|
||||
}
|
||||
|
||||
const [updated] = await db.select().from(users).where(eq(users.id, user.id)).limit(1)
|
||||
return {
|
||||
user: {
|
||||
id: updated!.id,
|
||||
name: updated!.name,
|
||||
email: updated!.email,
|
||||
color: updated!.color,
|
||||
cardEffect: updated!.cardEffect,
|
||||
cardEffectColor: updated!.cardEffectColor,
|
||||
cardVignette: updated!.cardVignette,
|
||||
cardBorderEffect: updated!.cardBorderEffect,
|
||||
cardBorderEffectColor: updated!.cardBorderEffectColor,
|
||||
avatarUrl: avatarUrl(updated!.avatar),
|
||||
roles: user.roles,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,7 @@
|
||||
import { asc } from 'drizzle-orm'
|
||||
import { users } from '../../db/schema'
|
||||
|
||||
export default defineEventHandler(() => useDb()
|
||||
.select({ id: users.id, name: users.name, color: users.color })
|
||||
.from(users)
|
||||
.orderBy(asc(users.name)))
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`password_hash` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `users_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `users_email_unique` UNIQUE(`email`)
|
||||
);
|
||||
@@ -0,0 +1,37 @@
|
||||
CREATE TABLE `comments` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`upload_id` bigint unsigned NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `comments_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(64) NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`expires_at` timestamp NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `sessions_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `uploads` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`type` enum('image','video') NOT NULL,
|
||||
`file_name` varchar(255) NOT NULL,
|
||||
`original_name` varchar(255) NOT NULL,
|
||||
`mime_type` varchar(100) NOT NULL,
|
||||
`size` bigint unsigned NOT NULL,
|
||||
`title` varchar(255),
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `uploads_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `users` MODIFY COLUMN `name` varchar(50) NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `users` MODIFY COLUMN `email` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `users` ADD CONSTRAINT `users_name_unique` UNIQUE(`name`);--> statement-breakpoint
|
||||
ALTER TABLE `comments` ADD CONSTRAINT `comments_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `comments` ADD CONSTRAINT `comments_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `sessions` ADD CONSTRAINT `sessions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `uploads` ADD CONSTRAINT `uploads_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE `roles` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `roles_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `roles_name_unique` UNIQUE(`name`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `user_roles` (
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
CONSTRAINT `user_roles_user_id_role_id_pk` PRIMARY KEY(`user_id`,`role_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
INSERT INTO `roles` (`name`) VALUES ('admin');--> statement-breakpoint
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`) SELECT `u`.`id`, `r`.`id` FROM `users` `u`, `roles` `r` WHERE `r`.`name` = 'admin' ORDER BY `u`.`id` LIMIT 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `type` enum('image','video','youtube','link') NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `file_name` varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `mime_type` varchar(100);--> statement-breakpoint
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `size` bigint unsigned;--> statement-breakpoint
|
||||
ALTER TABLE `uploads` ADD `external_url` varchar(2048);
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `comments` DROP FOREIGN KEY `comments_upload_id_uploads_id_fk`;--> statement-breakpoint
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `id` varchar(8) NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `comments` MODIFY COLUMN `upload_id` varchar(8) NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE `comments` ADD CONSTRAINT `comments_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `users` ADD `color` varchar(7);--> statement-breakpoint
|
||||
ALTER TABLE `users` ADD `avatar` varchar(255);
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE `favorites` (
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`upload_id` varchar(8) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `favorites_user_id_upload_id_pk` PRIMARY KEY(`user_id`,`upload_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `favorites` ADD CONSTRAINT `favorites_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `favorites` ADD CONSTRAINT `favorites_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `notifications` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`actor_id` bigint unsigned NOT NULL,
|
||||
`upload_id` varchar(8) NOT NULL,
|
||||
`comment_id` bigint unsigned NOT NULL,
|
||||
`is_read` boolean NOT NULL DEFAULT false,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `notifications_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `notifications` ADD CONSTRAINT `notifications_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `notifications` ADD CONSTRAINT `notifications_actor_id_users_id_fk` FOREIGN KEY (`actor_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `notifications` ADD CONSTRAINT `notifications_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `notifications` ADD CONSTRAINT `notifications_comment_id_comments_id_fk` FOREIGN KEY (`comment_id`) REFERENCES `comments`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `uploads` ADD `preview_image` varchar(2048);--> statement-breakpoint
|
||||
ALTER TABLE `uploads` ADD `preview_title` varchar(500);
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE `link_previews` (
|
||||
`url_hash` char(64) NOT NULL,
|
||||
`url` varchar(2048) NOT NULL,
|
||||
`image` varchar(2048),
|
||||
`title` varchar(500),
|
||||
`fetched_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `link_previews_url_hash` PRIMARY KEY(`url_hash`)
|
||||
);
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE `comment_reactions` (
|
||||
`comment_id` bigint unsigned NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`emoji` varchar(32) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `comment_reactions_comment_id_user_id_emoji_pk` PRIMARY KEY(`comment_id`,`user_id`,`emoji`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `comment_reactions` ADD CONSTRAINT `comment_reactions_comment_id_comments_id_fk` FOREIGN KEY (`comment_id`) REFERENCES `comments`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `comment_reactions` ADD CONSTRAINT `comment_reactions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE `permissions` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`key` varchar(50) NOT NULL,
|
||||
`label` varchar(255) NOT NULL,
|
||||
CONSTRAINT `permissions_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `permissions_key_unique` UNIQUE(`key`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `role_permissions` (
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
CONSTRAINT `role_permissions_role_id_permission_id_pk` PRIMARY KEY(`role_id`,`permission_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `role_permissions` ADD CONSTRAINT `role_permissions_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `role_permissions` ADD CONSTRAINT `role_permissions_permission_id_permissions_id_fk` FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `users` ADD `card_effect` varchar(32);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `users` ADD `card_border_effect` varchar(32);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `type` enum('image','video','youtube','twitch','link') NOT NULL;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE `tags` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`name` varchar(64) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `tags_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `tags_name_unique` UNIQUE(`name`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `upload_tags` (
|
||||
`upload_id` varchar(8) NOT NULL,
|
||||
`tag_id` bigint unsigned NOT NULL,
|
||||
CONSTRAINT `upload_tags_upload_id_tag_id_pk` PRIMARY KEY(`upload_id`,`tag_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `upload_tags` ADD CONSTRAINT `upload_tags_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `upload_tags` ADD CONSTRAINT `upload_tags_tag_id_tags_id_fk` FOREIGN KEY (`tag_id`) REFERENCES `tags`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `uploads` ADD `comment_count` int unsigned DEFAULT 0 NOT NULL;
|
||||
--> statement-breakpoint
|
||||
UPDATE `uploads` u SET `comment_count` = (SELECT COUNT(*) FROM `comments` c WHERE c.`upload_id` = u.`id`);
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE `upload_reactions` (
|
||||
`upload_id` varchar(8) NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`emoji` varchar(32) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `upload_reactions_upload_id_user_id_emoji_pk` PRIMARY KEY(`upload_id`,`user_id`,`emoji`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `upload_reactions` ADD CONSTRAINT `upload_reactions_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `upload_reactions` ADD CONSTRAINT `upload_reactions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `uploads` MODIFY COLUMN `type` enum('image','video','audio','youtube','twitch','link') NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `uploads` ADD `audio_meta` json;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `users` ADD `card_effect_color` varchar(7);--> statement-breakpoint
|
||||
ALTER TABLE `users` ADD `card_border_effect_color` varchar(7);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `users` ADD `card_vignette` boolean DEFAULT false NOT NULL;
|
||||
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE `comment_attachments` (
|
||||
`id` bigint unsigned AUTO_INCREMENT NOT NULL,
|
||||
`comment_id` bigint unsigned NOT NULL,
|
||||
`file_name` varchar(255) NOT NULL,
|
||||
`original_name` varchar(255) NOT NULL,
|
||||
`mime_type` varchar(100),
|
||||
`size` bigint unsigned,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `comment_attachments_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `comment_attachments` ADD CONSTRAINT `comment_attachments_comment_id_comments_id_fk` FOREIGN KEY (`comment_id`) REFERENCES `comments`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `comment_attachments` ADD `cover` varchar(2048);--> statement-breakpoint
|
||||
ALTER TABLE `comment_attachments` ADD `meta` json;
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE TABLE `settings` (
|
||||
`key` varchar(100) NOT NULL,
|
||||
`value` text,
|
||||
CONSTRAINT `settings_key` PRIMARY KEY(`key`)
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE `thread_subscriptions` (
|
||||
`upload_id` varchar(8) NOT NULL,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`enabled` boolean NOT NULL DEFAULT true,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `thread_subscriptions_upload_id_user_id_pk` PRIMARY KEY(`upload_id`,`user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `thread_subscriptions` ADD CONSTRAINT `thread_subscriptions_upload_id_uploads_id_fk` FOREIGN KEY (`upload_id`) REFERENCES `uploads`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `thread_subscriptions` ADD CONSTRAINT `thread_subscriptions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `thread_subscriptions` (`upload_id`, `user_id`)
|
||||
SELECT `id`, `user_id` FROM `uploads`
|
||||
UNION
|
||||
SELECT `upload_id`, `user_id` FROM `comments`
|
||||
UNION
|
||||
SELECT `upload_id`, `user_id` FROM `favorites`
|
||||
UNION
|
||||
SELECT `upload_id`, `user_id` FROM `upload_reactions`;
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "09d8b567-8356-447d-937d-af1911a4a8e2",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "00af97be-75c3-4edf-a0da-5f2f5c843557",
|
||||
"prevId": "09d8b567-8356-447d-937d-af1911a4a8e2",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "8f3b34de-8887-41ec-b26a-1e1483cb10a9",
|
||||
"prevId": "00af97be-75c3-4edf-a0da-5f2f5c843557",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "5e677494-4bb8-4a04-8d5a-903e9039e915",
|
||||
"prevId": "8f3b34de-8887-41ec-b26a-1e1483cb10a9",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "b62a4f15-402f-4deb-93d7-46a6e702a3a8",
|
||||
"prevId": "5e677494-4bb8-4a04-8d5a-903e9039e915",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "9843a268-2e96-477a-b171-f86e524f01a1",
|
||||
"prevId": "b62a4f15-402f-4deb-93d7-46a6e702a3a8",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "b7c2cac9-a612-4d12-b0ab-8d5b77fb51f1",
|
||||
"prevId": "9843a268-2e96-477a-b171-f86e524f01a1",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "c07cfc65-aada-4595-a8d1-4736c858c104",
|
||||
"prevId": "b7c2cac9-a612-4d12-b0ab-8d5b77fb51f1",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,647 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "31523494-9f1f-4a98-a7fd-d89eb6c6dcb9",
|
||||
"prevId": "c07cfc65-aada-4595-a8d1-4736c858c104",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,700 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "d7e55315-bf9d-4a0e-a4b2-fd892746c61e",
|
||||
"prevId": "31523494-9f1f-4a98-a7fd-d89eb6c6dcb9",
|
||||
"tables": {
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,775 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "b32b6b4b-df8f-470e-a46e-24bd192f8970",
|
||||
"prevId": "d7e55315-bf9d-4a0e-a4b2-fd892746c61e",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,879 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "ea87dc4c-34dc-4f3c-9079-4f8a0abd9057",
|
||||
"prevId": "b32b6b4b-df8f-470e-a46e-24bd192f8970",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"permissions_id": {
|
||||
"name": "permissions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"permissions_key_unique": {
|
||||
"name": "permissions_key_unique",
|
||||
"columns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"role_permissions": {
|
||||
"name": "role_permissions",
|
||||
"columns": {
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission_id": {
|
||||
"name": "permission_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"role_permissions_role_id_roles_id_fk": {
|
||||
"name": "role_permissions_role_id_roles_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"role_permissions_permission_id_permissions_id_fk": {
|
||||
"name": "role_permissions_permission_id_permissions_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "permissions",
|
||||
"columnsFrom": [
|
||||
"permission_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"role_permissions_role_id_permission_id_pk": {
|
||||
"name": "role_permissions_role_id_permission_id_pk",
|
||||
"columns": [
|
||||
"role_id",
|
||||
"permission_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,886 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "88fe40d5-5a91-4ca5-a1db-7a228da105db",
|
||||
"prevId": "ea87dc4c-34dc-4f3c-9079-4f8a0abd9057",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"permissions_id": {
|
||||
"name": "permissions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"permissions_key_unique": {
|
||||
"name": "permissions_key_unique",
|
||||
"columns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"role_permissions": {
|
||||
"name": "role_permissions",
|
||||
"columns": {
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission_id": {
|
||||
"name": "permission_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"role_permissions_role_id_roles_id_fk": {
|
||||
"name": "role_permissions_role_id_roles_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"role_permissions_permission_id_permissions_id_fk": {
|
||||
"name": "role_permissions_permission_id_permissions_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "permissions",
|
||||
"columnsFrom": [
|
||||
"permission_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"role_permissions_role_id_permission_id_pk": {
|
||||
"name": "role_permissions_role_id_permission_id_pk",
|
||||
"columns": [
|
||||
"role_id",
|
||||
"permission_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_effect": {
|
||||
"name": "card_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,893 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "79b8947a-3845-40c6-b17f-b633e75b7dde",
|
||||
"prevId": "88fe40d5-5a91-4ca5-a1db-7a228da105db",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"permissions_id": {
|
||||
"name": "permissions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"permissions_key_unique": {
|
||||
"name": "permissions_key_unique",
|
||||
"columns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"role_permissions": {
|
||||
"name": "role_permissions",
|
||||
"columns": {
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission_id": {
|
||||
"name": "permission_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"role_permissions_role_id_roles_id_fk": {
|
||||
"name": "role_permissions_role_id_roles_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"role_permissions_permission_id_permissions_id_fk": {
|
||||
"name": "role_permissions_permission_id_permissions_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "permissions",
|
||||
"columnsFrom": [
|
||||
"permission_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"role_permissions_role_id_permission_id_pk": {
|
||||
"name": "role_permissions_role_id_permission_id_pk",
|
||||
"columns": [
|
||||
"role_id",
|
||||
"permission_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_effect": {
|
||||
"name": "card_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_border_effect": {
|
||||
"name": "card_border_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,893 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "0fb5f7ec-45ab-450a-a79e-ad28a5c5ee4b",
|
||||
"prevId": "79b8947a-3845-40c6-b17f-b633e75b7dde",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"permissions_id": {
|
||||
"name": "permissions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"permissions_key_unique": {
|
||||
"name": "permissions_key_unique",
|
||||
"columns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"role_permissions": {
|
||||
"name": "role_permissions",
|
||||
"columns": {
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission_id": {
|
||||
"name": "permission_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"role_permissions_role_id_roles_id_fk": {
|
||||
"name": "role_permissions_role_id_roles_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"role_permissions_permission_id_permissions_id_fk": {
|
||||
"name": "role_permissions_permission_id_permissions_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "permissions",
|
||||
"columnsFrom": [
|
||||
"permission_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"role_permissions_role_id_permission_id_pk": {
|
||||
"name": "role_permissions_role_id_permission_id_pk",
|
||||
"columns": [
|
||||
"role_id",
|
||||
"permission_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','twitch','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_effect": {
|
||||
"name": "card_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_border_effect": {
|
||||
"name": "card_border_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,998 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "1b3fd5f2-f0b3-46fa-aada-e7cf271ac26d",
|
||||
"prevId": "0fb5f7ec-45ab-450a-a79e-ad28a5c5ee4b",
|
||||
"tables": {
|
||||
"comment_reactions": {
|
||||
"name": "comment_reactions",
|
||||
"columns": {
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"emoji": {
|
||||
"name": "emoji",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comment_reactions_comment_id_comments_id_fk": {
|
||||
"name": "comment_reactions_comment_id_comments_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comment_reactions_user_id_users_id_fk": {
|
||||
"name": "comment_reactions_user_id_users_id_fk",
|
||||
"tableFrom": "comment_reactions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comment_reactions_comment_id_user_id_emoji_pk": {
|
||||
"name": "comment_reactions_comment_id_user_id_emoji_pk",
|
||||
"columns": [
|
||||
"comment_id",
|
||||
"user_id",
|
||||
"emoji"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"comments": {
|
||||
"name": "comments",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"comments_upload_id_uploads_id_fk": {
|
||||
"name": "comments_upload_id_uploads_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"comments_user_id_users_id_fk": {
|
||||
"name": "comments_user_id_users_id_fk",
|
||||
"tableFrom": "comments",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"comments_id": {
|
||||
"name": "comments_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"favorites": {
|
||||
"name": "favorites",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"favorites_user_id_users_id_fk": {
|
||||
"name": "favorites_user_id_users_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"favorites_upload_id_uploads_id_fk": {
|
||||
"name": "favorites_upload_id_uploads_id_fk",
|
||||
"tableFrom": "favorites",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"favorites_user_id_upload_id_pk": {
|
||||
"name": "favorites_user_id_upload_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"upload_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"link_previews": {
|
||||
"name": "link_previews",
|
||||
"columns": {
|
||||
"url_hash": {
|
||||
"name": "url_hash",
|
||||
"type": "char(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"fetched_at": {
|
||||
"name": "fetched_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"link_previews_url_hash": {
|
||||
"name": "link_previews_url_hash",
|
||||
"columns": [
|
||||
"url_hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"notifications": {
|
||||
"name": "notifications",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor_id": {
|
||||
"name": "actor_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"comment_id": {
|
||||
"name": "comment_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"is_read": {
|
||||
"name": "is_read",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"notifications_user_id_users_id_fk": {
|
||||
"name": "notifications_user_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_actor_id_users_id_fk": {
|
||||
"name": "notifications_actor_id_users_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"actor_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_upload_id_uploads_id_fk": {
|
||||
"name": "notifications_upload_id_uploads_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"notifications_comment_id_comments_id_fk": {
|
||||
"name": "notifications_comment_id_comments_id_fk",
|
||||
"tableFrom": "notifications",
|
||||
"tableTo": "comments",
|
||||
"columnsFrom": [
|
||||
"comment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"notifications_id": {
|
||||
"name": "notifications_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"label": {
|
||||
"name": "label",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"permissions_id": {
|
||||
"name": "permissions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"permissions_key_unique": {
|
||||
"name": "permissions_key_unique",
|
||||
"columns": [
|
||||
"key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"role_permissions": {
|
||||
"name": "role_permissions",
|
||||
"columns": {
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"permission_id": {
|
||||
"name": "permission_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"role_permissions_role_id_roles_id_fk": {
|
||||
"name": "role_permissions_role_id_roles_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"role_permissions_permission_id_permissions_id_fk": {
|
||||
"name": "role_permissions_permission_id_permissions_id_fk",
|
||||
"tableFrom": "role_permissions",
|
||||
"tableTo": "permissions",
|
||||
"columnsFrom": [
|
||||
"permission_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"role_permissions_role_id_permission_id_pk": {
|
||||
"name": "role_permissions_role_id_permission_id_pk",
|
||||
"columns": [
|
||||
"role_id",
|
||||
"permission_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"roles": {
|
||||
"name": "roles",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"roles_id": {
|
||||
"name": "roles_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"roles_name_unique": {
|
||||
"name": "roles_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"sessions": {
|
||||
"name": "sessions",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"sessions_id": {
|
||||
"name": "sessions_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"tags": {
|
||||
"name": "tags",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"tags_id": {
|
||||
"name": "tags_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"tags_name_unique": {
|
||||
"name": "tags_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"upload_tags": {
|
||||
"name": "upload_tags",
|
||||
"columns": {
|
||||
"upload_id": {
|
||||
"name": "upload_id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"tag_id": {
|
||||
"name": "tag_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"upload_tags_upload_id_uploads_id_fk": {
|
||||
"name": "upload_tags_upload_id_uploads_id_fk",
|
||||
"tableFrom": "upload_tags",
|
||||
"tableTo": "uploads",
|
||||
"columnsFrom": [
|
||||
"upload_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"upload_tags_tag_id_tags_id_fk": {
|
||||
"name": "upload_tags_tag_id_tags_id_fk",
|
||||
"tableFrom": "upload_tags",
|
||||
"tableTo": "tags",
|
||||
"columnsFrom": [
|
||||
"tag_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"upload_tags_upload_id_tag_id_pk": {
|
||||
"name": "upload_tags_upload_id_tag_id_pk",
|
||||
"columns": [
|
||||
"upload_id",
|
||||
"tag_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"uploads": {
|
||||
"name": "uploads",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"type": "enum('image','video','youtube','twitch','link')",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"external_url": {
|
||||
"name": "external_url",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"original_name": {
|
||||
"name": "original_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "varchar(100)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"size": {
|
||||
"name": "size",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_image": {
|
||||
"name": "preview_image",
|
||||
"type": "varchar(2048)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"preview_title": {
|
||||
"name": "preview_title",
|
||||
"type": "varchar(500)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"uploads_user_id_users_id_fk": {
|
||||
"name": "uploads_user_id_users_id_fk",
|
||||
"tableFrom": "uploads",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"uploads_id": {
|
||||
"name": "uploads_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user_roles": {
|
||||
"name": "user_roles",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"role_id": {
|
||||
"name": "role_id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"user_roles_user_id_users_id_fk": {
|
||||
"name": "user_roles_user_id_users_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"user_roles_role_id_roles_id_fk": {
|
||||
"name": "user_roles_role_id_roles_id_fk",
|
||||
"tableFrom": "user_roles",
|
||||
"tableTo": "roles",
|
||||
"columnsFrom": [
|
||||
"role_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {
|
||||
"user_roles_user_id_role_id_pk": {
|
||||
"name": "user_roles_user_id_role_id_pk",
|
||||
"columns": [
|
||||
"user_id",
|
||||
"role_id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "bigint unsigned",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(50)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password_hash": {
|
||||
"name": "password_hash",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_effect": {
|
||||
"name": "card_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"card_border_effect": {
|
||||
"name": "card_border_effect",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"columns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {
|
||||
"users_name_unique": {
|
||||
"name": "users_name_unique",
|
||||
"columns": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "mysql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "5",
|
||||
"when": 1789842188719,
|
||||
"tag": "0000_marvelous_the_spike",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "5",
|
||||
"when": 1789851450541,
|
||||
"tag": "0001_cuddly_betty_brant",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "5",
|
||||
"when": 1789857172319,
|
||||
"tag": "0002_colossal_night_nurse",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "5",
|
||||
"when": 1789859432013,
|
||||
"tag": "0003_many_zarek",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "5",
|
||||
"when": 1789860013310,
|
||||
"tag": "0004_closed_mister_fear",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "5",
|
||||
"when": 1789910520999,
|
||||
"tag": "0005_sparkling_quasar",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "5",
|
||||
"when": 1789920696042,
|
||||
"tag": "0006_old_frog_thor",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "5",
|
||||
"when": 1789924974989,
|
||||
"tag": "0007_windy_joshua_kane",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "5",
|
||||
"when": 1789935573559,
|
||||
"tag": "0008_flashy_magdalene",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "5",
|
||||
"when": 1789936119560,
|
||||
"tag": "0009_new_legion",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "5",
|
||||
"when": 1790019345617,
|
||||
"tag": "0010_perpetual_aqueduct",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "5",
|
||||
"when": 1790102908283,
|
||||
"tag": "0011_permissions",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "5",
|
||||
"when": 1790108064546,
|
||||
"tag": "0012_whole_sir_ram",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "5",
|
||||
"when": 1790108517670,
|
||||
"tag": "0013_worried_beyonder",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "5",
|
||||
"when": 1790450943938,
|
||||
"tag": "0014_big_venus",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "5",
|
||||
"when": 1790452144567,
|
||||
"tag": "0015_pink_kingpin",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "5",
|
||||
"when": 1790453684144,
|
||||
"tag": "0016_aromatic_punisher",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "5",
|
||||
"when": 1790465843836,
|
||||
"tag": "0017_cuddly_lady_bullseye",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "5",
|
||||
"when": 1790466433142,
|
||||
"tag": "0018_eminent_storm",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 19,
|
||||
"version": "5",
|
||||
"when": 1790469274404,
|
||||
"tag": "0019_sharp_chimera",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 20,
|
||||
"version": "5",
|
||||
"when": 1790536757531,
|
||||
"tag": "0020_cooing_crusher_hogan",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 21,
|
||||
"version": "5",
|
||||
"when": 1790538016436,
|
||||
"tag": "0021_brave_cardiac",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 22,
|
||||
"version": "5",
|
||||
"when": 1790540511153,
|
||||
"tag": "0022_panoramic_shocker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 23,
|
||||
"version": "5",
|
||||
"when": 1790618393528,
|
||||
"tag": "0023_new_nova",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 24,
|
||||
"version": "5",
|
||||
"when": 1790626717328,
|
||||
"tag": "0024_brainy_peter_parker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 25,
|
||||
"version": "5",
|
||||
"when": 1791040007768,
|
||||
"tag": "0025_rare_william_stryker",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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] }),
|
||||
}))
|
||||
@@ -0,0 +1,22 @@
|
||||
import { drizzle } from 'drizzle-orm/mysql2'
|
||||
import { migrate } from 'drizzle-orm/mysql2/migrator'
|
||||
import mysql from 'mysql2/promise'
|
||||
import { seedPermissions } from '../../shared/utils/permissions'
|
||||
|
||||
export default defineNitroPlugin(async () => {
|
||||
if (!import.meta.dev) return
|
||||
const { databaseUrl } = useRuntimeConfig()
|
||||
if (!databaseUrl) {
|
||||
console.warn('[db] DATABASE_URL is not set, skipping migrations')
|
||||
return
|
||||
}
|
||||
const connection = await mysql.createConnection(databaseUrl)
|
||||
try {
|
||||
await migrate(drizzle(connection), { migrationsFolder: './server/db/migrations' })
|
||||
await seedPermissions(connection)
|
||||
console.log('[db] migrations applied')
|
||||
}
|
||||
finally {
|
||||
await connection.end()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
export default defineWebSocketHandler({
|
||||
async open(peer) {
|
||||
try {
|
||||
registerGlobalPeer(peer)
|
||||
const headers = peer.request?.headers as { cookie?: string, get?: (name: string) => string | null } | undefined
|
||||
const cookie = headers?.get?.('cookie') ?? headers?.cookie
|
||||
const userId = await getUserIdFromCookieHeader(cookie)
|
||||
if (userId !== null) {
|
||||
;(peer.context as { userId?: number }).userId = userId
|
||||
registerPeer(userId, peer)
|
||||
}
|
||||
} catch {
|
||||
// Peer kann während des async-Lookups schon weg sein — nicht als Crash propagieren
|
||||
}
|
||||
},
|
||||
close(peer) {
|
||||
unregisterGlobalPeer(peer)
|
||||
unregisterPeer((peer.context as { userId?: number }).userId, peer)
|
||||
},
|
||||
error(peer, error) {
|
||||
console.warn('[ws] Fehler bei Peer:', error instanceof Error ? error.message : error)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../.nuxt/tsconfig.server.json"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { randomBytes, scryptSync, timingSafeEqual } from 'node:crypto'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { H3Event } from 'h3'
|
||||
import { sessions, users } from '../db/schema'
|
||||
|
||||
const SESSION_COOKIE = 'session'
|
||||
const SESSION_TTL_MS = 1000 * 60 * 60 * 24 * 30 // 30 Tage
|
||||
|
||||
export function hashPassword(password: string) {
|
||||
const salt = randomBytes(16).toString('hex')
|
||||
const hash = scryptSync(password, salt, 64).toString('hex')
|
||||
return `${salt}:${hash}`
|
||||
}
|
||||
|
||||
export function verifyPassword(password: string, stored: string) {
|
||||
const [salt, hash] = stored.split(':')
|
||||
if (!salt || !hash) return false
|
||||
const candidate = scryptSync(password, salt, 64)
|
||||
const expected = Buffer.from(hash, 'hex')
|
||||
return candidate.length === expected.length && timingSafeEqual(candidate, expected)
|
||||
}
|
||||
|
||||
export async function createSession(event: H3Event, userId: number) {
|
||||
const token = randomBytes(32).toString('hex')
|
||||
const expiresAt = new Date(Date.now() + SESSION_TTL_MS)
|
||||
await useDb().insert(sessions).values({ id: token, userId, expiresAt })
|
||||
setCookie(event, SESSION_COOKIE, token, {
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
path: '/',
|
||||
maxAge: SESSION_TTL_MS / 1000,
|
||||
})
|
||||
}
|
||||
|
||||
export async function getSessionUser(event: H3Event) {
|
||||
const token = getCookie(event, SESSION_COOKIE)
|
||||
if (!token) return null
|
||||
const db = useDb()
|
||||
const rows = await db
|
||||
.select({ user: users, session: sessions })
|
||||
.from(sessions)
|
||||
.innerJoin(users, eq(sessions.userId, users.id))
|
||||
.where(eq(sessions.id, token))
|
||||
.limit(1)
|
||||
const row = rows[0]
|
||||
if (!row) return null
|
||||
if (row.session.expiresAt < new Date()) {
|
||||
await db.delete(sessions).where(eq(sessions.id, token))
|
||||
deleteCookie(event, SESSION_COOKIE, { path: '/' })
|
||||
return null
|
||||
}
|
||||
return { ...row.user, roles: await getUserRoles(row.user.id), permissions: await getUserPermissions(row.user.id) }
|
||||
}
|
||||
|
||||
export async function requireUser(event: H3Event) {
|
||||
const user = await getSessionUser(event)
|
||||
if (!user) {
|
||||
throw createError({ statusCode: 401, statusMessage: 'Nicht angemeldet' })
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
export async function requirePermission(event: H3Event, permission: string) {
|
||||
const user = await requireUser(event)
|
||||
if (!user.roles.includes('admin') && !user.permissions.includes(permission)) {
|
||||
throw createError({ statusCode: 403, statusMessage: 'Kein Zugriff' })
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
export async function destroySession(event: H3Event) {
|
||||
const token = getCookie(event, SESSION_COOKIE)
|
||||
if (token) {
|
||||
await useDb().delete(sessions).where(eq(sessions.id, token))
|
||||
}
|
||||
deleteCookie(event, SESSION_COOKIE, { path: '/' })
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { MySql2Database } from 'drizzle-orm/mysql2'
|
||||
import { drizzle } from 'drizzle-orm/mysql2'
|
||||
import mysql from 'mysql2/promise'
|
||||
import * as schema from '../db/schema'
|
||||
|
||||
let db: MySql2Database<typeof schema> | undefined
|
||||
|
||||
export function useDb() {
|
||||
if (!db) {
|
||||
const { databaseUrl } = useRuntimeConfig()
|
||||
if (!databaseUrl) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'DATABASE_URL is not configured' })
|
||||
}
|
||||
db = drizzle(mysql.createPool(databaseUrl), { schema, mode: 'default' })
|
||||
}
|
||||
return db
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Gemeinsame Viewport-Pagination für Upload-Grids (Mainseite, Profilseite).
|
||||
// Der Client schickt cells (Zeilen x Spalten, die ohne Scrollen passen), cols
|
||||
// und den Modus — der Server simuliert grid-auto-flow: dense exakt nach.
|
||||
|
||||
export function getGridPageParams(q: Record<string, unknown>) {
|
||||
const page = Math.max(1, Math.floor(Number(q.page)) || 1)
|
||||
const cells = Math.min(400, Math.max(1, Math.floor(Number(q.cells)) || 48))
|
||||
const cols = Math.min(12, Math.max(1, Math.floor(Number(q.cols)) || 12))
|
||||
const uniform = q.mode === 'uniform'
|
||||
return { page, cells, cols, uniform }
|
||||
}
|
||||
|
||||
// Gleiche Maße wie UploadTile: uniform = 1x1, >=7 Kommentare = 3x3
|
||||
// (ab sm/cols>=6) bzw. 2x2, >=1 Kommentar = 2x2, sonst 1x1
|
||||
export function gridTileDims(commentCount: number, uniform: boolean, cols: number): [h: number, w: number] {
|
||||
return uniform ? [1, 1] : commentCount >= 7 ? (cols >= 6 ? [3, 3] : [2, 2]) : commentCount >= 1 ? [2, 2] : [1, 1]
|
||||
}
|
||||
|
||||
// Simuliert grid-auto-flow: dense — jedes Tile geht in die erste freie
|
||||
// Rechteck-Position (zeilenweise von oben links). Passt es nirgends in die
|
||||
// maxRows-Zeilen, wird es auf die nächste Seite verschoben (Reihenfolge der
|
||||
// übrigen Items bleibt erhalten). Kleinere Tiles danach füllen noch Lücken.
|
||||
export function paginateGrid<T>(items: T[], dims: (item: T) => [h: number, w: number], cells: number, cols: number): T[][] {
|
||||
const maxRows = Math.max(1, Math.floor(cells / cols))
|
||||
|
||||
const pack = (input: T[]) => {
|
||||
const occupied: boolean[][] = []
|
||||
const placed: T[] = []
|
||||
const deferred: T[] = []
|
||||
const fits = (r: number, c: number, h: number, w: number) => {
|
||||
if (r + h > maxRows || c + w > cols) return false
|
||||
for (let dr = 0; dr < h; dr++)
|
||||
for (let dc = 0; dc < w; dc++)
|
||||
if (occupied[r + dr]?.[c + dc]) return false
|
||||
return true
|
||||
}
|
||||
for (const item of input) {
|
||||
const [h, w] = dims(item)
|
||||
let done = false
|
||||
for (let r = 0; r + h <= maxRows && !done; r++) {
|
||||
for (let c = 0; c + w <= cols; c++) {
|
||||
if (fits(r, c, h, w)) {
|
||||
for (let dr = 0; dr < h; dr++) {
|
||||
const line = (occupied[r + dr] ??= new Array(cols).fill(false))
|
||||
for (let dc = 0; dc < w; dc++) line[c + dc] = true
|
||||
}
|
||||
placed.push(item)
|
||||
done = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!done) deferred.push(item)
|
||||
}
|
||||
return { placed, deferred }
|
||||
}
|
||||
|
||||
const pages: T[][] = []
|
||||
let rest = items
|
||||
while (rest.length) {
|
||||
const { placed, deferred } = pack(rest)
|
||||
if (!placed.length) {
|
||||
// Sicherheitsnetz: kann bei cols>=1 nie leer sein (1x1 passt immer)
|
||||
pages.push(rest)
|
||||
break
|
||||
}
|
||||
pages.push(placed)
|
||||
rest = deferred
|
||||
}
|
||||
return pages
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
const MAX_HTML_BYTES = 512 * 1024
|
||||
|
||||
function metaContent(html: string, keys: string[]): string | null {
|
||||
for (const key of keys) {
|
||||
const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
const before = new RegExp(`<meta[^>]+(?:property|name)=["']${escaped}["'][^>]+content=["']([^"']+)["']`, 'i')
|
||||
const after = new RegExp(`<meta[^>]+content=["']([^"']+)["'][^>]+(?:property|name)=["']${escaped}["']`, 'i')
|
||||
const match = before.exec(html) ?? after.exec(html)
|
||||
if (match?.[1]?.trim()) return match[1].trim()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export interface LinkPreview {
|
||||
image: string | null
|
||||
title: string | null
|
||||
}
|
||||
|
||||
const BLOCKED_HOST = /^(localhost|127\.|0\.0\.0\.0|::1|\[::1\]|169\.254\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|.*\.(local|internal|lan)$)/i
|
||||
|
||||
export function isBlockedHost(hostname: string): boolean {
|
||||
return BLOCKED_HOST.test(hostname)
|
||||
}
|
||||
|
||||
export async function fetchLinkPreview(url: string): Promise<LinkPreview> {
|
||||
try {
|
||||
const hostname = new URL(url).hostname
|
||||
if (isBlockedHost(hostname)) return { image: null, title: null }
|
||||
const res = await fetch(url, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
redirect: 'follow',
|
||||
headers: {
|
||||
'user-agent': 'Mozilla/5.0 (compatible; 4Brett-LinkPreview/1.0)',
|
||||
'accept': 'text/html,application/xhtml+xml',
|
||||
},
|
||||
})
|
||||
if (!res.ok) return { image: null, title: null }
|
||||
const contentType = res.headers.get('content-type') ?? ''
|
||||
if (!contentType.includes('text/html') && !contentType.includes('application/xhtml')) {
|
||||
return { image: null, title: null }
|
||||
}
|
||||
const html = (await res.text()).slice(0, MAX_HTML_BYTES)
|
||||
const base = res.url || url
|
||||
|
||||
const image = metaContent(html, ['og:image', 'og:image:url', 'og:image:secure_url', 'twitter:image', 'twitter:image:src'])
|
||||
const title = metaContent(html, ['og:title', 'twitter:title'])
|
||||
?? /<title[^>]*>([^<]+)<\/title>/i.exec(html)?.[1]?.trim()
|
||||
?? null
|
||||
|
||||
return {
|
||||
image: image ? new URL(image, base).href.slice(0, 2048) : null,
|
||||
title: title?.slice(0, 500) ?? null,
|
||||
}
|
||||
}
|
||||
catch {
|
||||
return { image: null, title: null }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user