import { all, first, run } from "./db";
import { badRequest, notFoundError } from "./errors";
import { recordAdminAction } from "./admin-audit";
import { publicUrl } from "./events/emit";
import { invalidateUnread } from "./user-inbox";
import { dropMcpAccess } from "./access-revocation";
import { HIDEABLE_KINDS } from "~/lib/abuse";
import type { AbuseTargetKind } from "~/lib/abuse";
type Hideable = "repo" | "issue" | "comment" | "review_comment" | "discussion_comment";
type Target = { table: string; key: string; column: string; counter?: string };
/** `counter` keeps the parent's comment count in step, so hidden comments don't show up as a number either. */
const TARGETS: Record<Hideable, Target> = {
repo: { table: "repos", key: "id", column: "hidden_at" },
issue: { table: "issues", key: "id", column: "hidden_at" },
comment: {
table: "comments",
key: "id",
column: "hidden_at",
counter: `UPDATE issues SET comments_count = MAX(comments_count + ?, 0)
WHERE id = (SELECT issue_id FROM comments WHERE id = ?)`,
},
review_comment: { table: "review_comments", key: "id", column: "hidden_at" },
discussion_comment: {
table: "discussion_comments",
key: "id",
column: "hidden_at",
counter: `UPDATE discussions SET comments_count = MAX(comments_count + ?, 0)
WHERE id = (SELECT discussion_id FROM discussion_comments WHERE id = ?)`,
},
};
export function isHideable(kind: string): kind is Hideable {
return HIDEABLE_KINDS.has(kind as AbuseTargetKind);
}
/** An open issue or pull request leaves (or rejoins) the repository's open counter as it is hidden (or restored). */
async function adjustOpenCounter(issueId: string, delta: number): Promise<void> {