vibe coded v1

This commit is contained in:
khannurien
2026-03-16 07:34:49 +00:00
parent 6207a7549f
commit e88fed4e98
48 changed files with 4303 additions and 595 deletions

View File

@@ -2,12 +2,29 @@
* Backend
*/
export interface RichContent {
type: string;
url: string;
siteName?: string;
title?: string;
description?: string;
thumbnailUrl?: string;
videoId?: string;
}
export interface Dump {
id: string;
kind: "url" | "file";
title: string;
description?: string;
comment?: string;
userId: string;
createdAt: Date;
url?: string;
richContent?: RichContent;
fileName?: string;
fileMime?: string;
fileSize?: number;
voteCount: number;
}
/**
@@ -20,6 +37,7 @@ export interface User {
passwordHash: string;
isAdmin: boolean;
createdAt: Date;
avatarMime?: string;
}
export interface LoginUserRequest {
@@ -127,28 +145,94 @@ export class APIException extends Error {
* Request DTOs
*/
export interface CreateDumpRequest {
title: string;
description?: string;
export interface CreateUrlDumpRequest {
url: string;
comment?: string;
}
export function isCreateDumpRequest(obj: unknown): obj is CreateDumpRequest {
export function isCreateUrlDumpRequest(
obj: unknown,
): obj is CreateUrlDumpRequest {
return !!obj &&
typeof obj === "object" &&
"title" in obj && typeof obj.title === "string" &&
(!("description" in obj) ||
(typeof obj.description === "string" || obj.description === null));
"url" in obj && typeof obj.url === "string" &&
(!("comment" in obj) ||
typeof obj.comment === "string" || obj.comment === null);
}
export interface UpdateDumpRequest {
title?: string;
description?: string;
url?: string;
comment?: string;
}
export function isUpdateDumpRequest(obj: unknown): obj is UpdateDumpRequest {
return !!obj &&
typeof obj === "object" &&
(!("title" in obj) || typeof obj.title === "string") &&
(!("description" in obj) ||
(typeof obj.description === "string" || obj.description === null));
(!("url" in obj) || typeof obj.url === "string" || obj.url === null) &&
(!("comment" in obj) ||
typeof obj.comment === "string" || obj.comment === null);
}
/**
* WebSockets
*/
export interface VoteCastMessage {
type: "vote_cast";
dumpId: string;
userId: string;
}
export interface VoteAckMessageFailure {
type: "vote_ack";
dumpId: string;
success: false;
error: APIError;
}
export interface VoteAckMessageSuccess {
type: "vote_ack";
dumpId: string;
action: "cast" | "remove";
success: true;
voteCount: number;
error?: never;
}
export type VoteAckMessage = VoteAckMessageSuccess | VoteAckMessageFailure;
export interface VoteRemoveMessage {
type: "vote_remove";
dumpId: string;
}
export interface VotesUpdateMessage {
type: "votes_update";
dumpId: string;
voteCount: number;
}
export interface OnlineUser {
userId: string;
username: string;
hasAvatar: boolean;
}
export interface WelcomeMessage {
type: "welcome";
users: OnlineUser[];
myVotes: string[];
}
export interface PresenceUpdateMessage {
type: "presence_update";
users: OnlineUser[];
}
export interface PingMessage {
type: "ping";
}
export interface PongMessage {
type: "pong";
}