Add database migration snapshots for comment_votes, comments, movies, and users tables

- Created 0009_snapshot.json with initial structure for comment_votes, comments, movies, and users tables.
- Created 0010_snapshot.json with updated structure for comments, including new fields: pinned and spoiler.
- Created 0011_snapshot.json with further updates to comments, adding anonymous field and refining existing structures.
This commit is contained in:
ngthanhvu
2026-07-24 00:06:03 -04:00
parent 70d8fc5bfa
commit 3d075f320c
22 changed files with 2832 additions and 74 deletions
+69
View File
@@ -0,0 +1,69 @@
export type CommentDraft = {
slug: string
source: string
content: string
movieName?: string
savedAt: number
}
const draftKey = 'cinek-comment-drafts'
function readDrafts(): CommentDraft[] {
if (!import.meta.client) return []
try {
const raw = window.localStorage.getItem(draftKey)
const drafts = raw ? JSON.parse(raw) : []
return Array.isArray(drafts) ? drafts : []
} catch {
return []
}
}
function writeDrafts(drafts: CommentDraft[]) {
if (!import.meta.client) return
window.localStorage.setItem(draftKey, JSON.stringify(drafts))
}
function findDraftKey(slug: string, source: string) {
return `${source}::${slug}`
}
export function useCommentDraft() {
function getDraft(slug: string, source: string): CommentDraft | null {
const drafts = readDrafts()
const key = findDraftKey(slug, source)
return drafts.find(d => findDraftKey(d.slug, d.source) === key) || null
}
function saveDraft(slug: string, source: string, content: string, movieName?: string) {
const drafts = readDrafts()
const key = findDraftKey(slug, source)
const filtered = drafts.filter(d => findDraftKey(d.slug, d.source) !== key)
filtered.unshift({ slug, source, content, movieName, savedAt: Date.now() })
writeDrafts(filtered.slice(0, 50))
}
function deleteDraft(slug: string, source: string) {
const drafts = readDrafts()
const key = findDraftKey(slug, source)
const filtered = drafts.filter(d => findDraftKey(d.slug, d.source) !== key)
writeDrafts(filtered)
}
function getAllDrafts(): CommentDraft[] {
return readDrafts()
}
function clearAllDrafts() {
if (import.meta.client) {
window.localStorage.removeItem(draftKey)
}
}
function clearExpiredDrafts(maxAgeMs = 7 * 24 * 60 * 60 * 1000) {
const drafts = readDrafts().filter(d => Date.now() - d.savedAt < maxAgeMs)
writeDrafts(drafts)
}
return { getDraft, saveDraft, deleteDraft, getAllDrafts, clearAllDrafts, clearExpiredDrafts }
}
+83
View File
@@ -0,0 +1,83 @@
export type CommentReply = {
id: number
userId: number
userName: string
userAvatar?: string
parentId: number
content: string
likeCount: number
dislikeCount: number
createdAt: string
userVote: number
pinned: boolean
spoiler: boolean
anonymous: boolean
}
export type Comment = {
id: number
userId: number
userName: string
userAvatar?: string
source: string
slug: string
movieName?: string
content: string
likeCount: number
dislikeCount: number
createdAt: string
userVote: number
replies: CommentReply[]
pinned: boolean
spoiler: boolean
anonymous: boolean
}
export function useComments() {
async function fetchComments(source: string, slug: string, userId?: number) {
try {
const data = await $fetch('/api/comments', {
query: { source, slug, userId },
})
return data.items as Comment[]
} catch {
return [] as Comment[]
}
}
async function postComment(
source: string,
slug: string,
content: string,
movieName?: string,
parentId?: number,
spoiler?: boolean,
anonymous?: boolean,
) {
return $fetch('/api/comments', {
method: 'POST',
body: { source, slug, content, movieName, parentId, spoiler, anonymous },
})
}
async function deleteComment(id: number) {
return $fetch(`/api/comments/${id}`, {
method: 'DELETE',
})
}
async function voteComment(commentId: number, vote: number) {
return $fetch('/api/comments/vote', {
method: 'POST',
body: { commentId, vote },
})
}
async function togglePinComment(id: number) {
return $fetch(`/api/comments/${id}/pin`, {
method: 'POST',
})
}
return { fetchComments, postComment, deleteComment, voteComment, togglePinComment }
}