Files
MineGeo/shared/community.ts
pavel444-byte e1a6ab5730
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 3m22s
Add map community reactions, comments, and moderation
2026-10-17 12:45:18 +05:00

90 lines
2.5 KiB
TypeScript

import { z } from "zod";
import type { ProfileAppearance } from "./profile-appearance";
export const communityCategories = {
spam: "Spam",
advertising: "Advertising",
inappropriate: "Inappropriate content",
harassment: "Harassment",
other: "Other",
} as const;
export const reactionInput = z
.object({ value: z.union([z.literal(-1), z.literal(0), z.literal(1)]) })
.strict();
export const commentInput = z
.object({ body: z.string().trim().min(1).max(2000) })
.strict();
export const communityReportInput = z.discriminatedUnion("target", [
z
.object({
target: z.literal("comment"),
targetId: z.string().uuid(),
category: z.enum(
Object.keys(communityCategories) as [
keyof typeof communityCategories,
...Array<keyof typeof communityCategories>,
],
),
reason: z.string().trim().min(10).max(2000),
})
.strict(),
z
.object({
target: z.literal("account"),
targetId: z.string().uuid(),
category: z.enum(
Object.keys(communityCategories) as [
keyof typeof communityCategories,
...Array<keyof typeof communityCategories>,
],
),
reason: z.string().trim().min(10).max(2000),
})
.strict(),
]);
export const communityReviewInput = z
.object({
decision: z.enum(["resolved", "dismissed"]),
reason: z.string().trim().min(10).max(2000),
})
.strict();
export type MapCommentRecord = {
id: string;
dataset_id: string;
author_id: string | null;
body: string;
created_at: string;
removed_at: string | null;
removed_by: string | null;
};
export type CommunityReportRecord = {
id: string;
reporter_id: string | null;
target: "comment" | "account";
comment_id: string | null;
account_id: string | null;
category: keyof typeof communityCategories;
reason: string;
state: "open" | "resolved" | "dismissed";
reviewer_id: string | null;
reviewed_at: string | null;
review_reason: string | null;
created_at: string;
};
export type CommunityComment = Pick<
MapCommentRecord,
"id" | "body" | "created_at" | "author_id"
> & { author: string; appearance?: ProfileAppearance };
export type MapCommunityView = {
likes: number;
dislikes: number;
reaction: number;
viewer: { id: string; canModerate: boolean } | null;
comments: CommunityComment[];
nextCursor: string | null;
};
export type CommunityReportView = CommunityReportRecord & {
comment: MapCommentRecord | null;
accountName: string | null;
};