import { APIErrorCode, APIException, type Comment, } from "../model/interfaces.ts"; import { commentRowToApi, type CommentRow, db, isCommentRow, } from "../model/db.ts"; const SELECT_COLS = `c.id, c.dump_id, c.user_id, c.parent_id, c.body, c.created_at, c.deleted, u.username as author_username, u.avatar_mime as author_avatar_mime`; function fetchComment(commentId: string): Comment { const row = db.prepare( `SELECT ${SELECT_COLS} FROM comments c JOIN users u ON c.user_id = u.id WHERE c.id = ?;`, ).get(commentId); if (!row || !isCommentRow(row as Record)) { throw new APIException(APIErrorCode.NOT_FOUND, 404, "Comment not found"); } return commentRowToApi(row as CommentRow); } export function getComments(dumpId: string): Comment[] { const rows = db.prepare( `SELECT ${SELECT_COLS} FROM comments c JOIN users u ON c.user_id = u.id WHERE c.dump_id = ? ORDER BY c.created_at ASC;`, ).all(dumpId); const typed = rows as Parameters[0][]; if (!typed.every(isCommentRow)) { throw new APIException( APIErrorCode.SERVER_ERROR, 500, "Malformed comment data", ); } return typed.map(commentRowToApi); } export function createComment( dumpId: string, userId: string, body: string, parentId?: string, ): Comment { const id = crypto.randomUUID(); const createdAt = new Date(); db.prepare( `INSERT INTO comments (id, dump_id, user_id, parent_id, body, created_at) VALUES (?, ?, ?, ?, ?, ?);`, ).run(id, dumpId, userId, parentId ?? null, body.trim(), createdAt.toISOString()); return fetchComment(id); } export function deleteComment( commentId: string, requestingUserId: string, isAdmin: boolean, ): { dumpId: string; isPrivate: boolean } { const row = db.prepare( `SELECT c.dump_id, d.is_private FROM comments c JOIN dumps d ON c.dump_id = d.id WHERE c.id = ?;`, ).get(commentId) as { dump_id: string; is_private: number } | undefined; if (!row) { throw new APIException(APIErrorCode.NOT_FOUND, 404, "Comment not found"); } const comment = fetchComment(commentId); if (comment.userId !== requestingUserId && !isAdmin) { throw new APIException( APIErrorCode.UNAUTHORIZED, 401, "Not authorized to delete this comment", ); } db.prepare(`UPDATE comments SET deleted = 1, body = '' WHERE id = ?;`).run(commentId); return { dumpId: row.dump_id, isPrivate: Boolean(row.is_private) }; }