infoalloggi-monorepo/apps/infoalloggi/src/server/controllers/chat.controller.ts

179 lines
4.1 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import { TRPCError } from "@trpc/server";
2025-08-28 18:27:07 +02:00
import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres";
2025-08-04 17:45:44 +02:00
import type { Chats, ChatsChatid } from "~/schemas/public/Chats";
import type { Etichette } from "~/schemas/public/Etichette";
import type { Users, UsersId } from "~/schemas/public/Users";
import type { Message } from "~/server/api/routers/chat_sse";
2025-08-04 17:45:44 +02:00
import { db } from "~/server/db";
2025-08-28 18:27:07 +02:00
import { add, type ChatUserInfo, getRaw } from "~/server/services/chat.service";
import { getUserInfo } from "~/utils/kysely-helper";
2025-08-04 17:45:44 +02:00
export type ActiveChatsType = Pick<Chats, "chatid" | "created_at"> &
Pick<Users, "id" | "username" | "email" | "nome"> & {
lastmessage: Pick<
Message,
"messageid" | "message" | "time" | "sender" | "isread"
> | null;
etichette: Etichette[];
};
2025-08-04 17:45:44 +02:00
export const getActiveInfos = async (): Promise<ActiveChatsType[]> => {
2025-08-28 18:27:07 +02:00
const chats = await db
2026-05-11 16:25:16 +02:00
.$pickTables<
"messages" | "chats" | "users" | "etichette" | "chats_etichette"
>()
2025-08-28 18:27:07 +02:00
.selectFrom("chats")
.innerJoin("users", "users.id", "chats.user_ref")
2025-08-28 18:27:07 +02:00
.select((eb) => [
"chatid",
"chats.created_at",
"id",
"username",
"email",
"nome",
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
jsonObjectFrom(
eb
.selectFrom("messages")
.whereRef("messages.chatid", "=", "chats.chatid")
.innerJoin("users", "users.id", "messages.sender")
.select((eb) => [
"messages.message",
"messages.messageid",
eb
.cast<string>(
eb.fn("to_char", [
"messages.time",
eb.val("YYYY-MM-DD HH24:MI:SS"),
]),
"text",
)
.as("time"),
"messages.sender",
"messages.isread",
2025-08-28 18:27:07 +02:00
])
.orderBy("messages.messageid", "desc")
2025-08-28 18:27:07 +02:00
.limit(1),
).as("lastmessage"),
2025-08-28 18:27:07 +02:00
jsonArrayFrom(
eb
.selectFrom("etichette")
.selectAll("etichette")
.innerJoin(
"chats_etichette",
"etichette.id_etichetta",
"chats_etichette.etichettaid",
)
.whereRef("chats_etichette.chatid", "=", "chats.chatid")
.select([
"etichette.id_etichetta",
"etichette.title",
"etichette.color_hex",
]),
).as("etichette"),
])
.orderBy("created_at", "desc")
.execute();
2025-08-04 17:45:44 +02:00
return chats;
2025-08-04 17:45:44 +02:00
};
export const getChatInfo = async ({
2025-08-28 18:27:07 +02:00
chatId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
chatId: ChatsChatid;
2025-08-04 17:45:44 +02:00
}): Promise<Chats> => {
2025-08-29 16:18:32 +02:00
return await getRaw({ chatId, db });
2025-08-04 17:45:44 +02:00
};
export const getChatByUser = async ({ userId }: { userId: UsersId }) => {
2025-08-28 18:27:07 +02:00
try {
const chat = await db
2026-05-11 16:25:16 +02:00
.$pickTables<"chats">()
2025-08-28 18:27:07 +02:00
.selectFrom("chats")
.select(["chatid", getUserInfo()])
.where("chats.user_ref", "=", userId)
.executeTakeFirst();
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
if (!chat) {
await add({
db,
userId: userId,
});
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
const chat = await db
2026-05-11 16:25:16 +02:00
.$pickTables<"chats">()
2025-08-28 18:27:07 +02:00
.selectFrom("chats")
.select(["chatid", getUserInfo()])
.where("chats.user_ref", "=", userId)
.executeTakeFirst();
if (!chat) {
throw new TRPCError({ code: "NOT_FOUND" });
}
return chat;
}
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
return chat;
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting chat: ${(e as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const deleteChatHandler = async ({
2025-08-28 18:27:07 +02:00
chatId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
chatId: ChatsChatid;
2025-08-04 17:45:44 +02:00
}) => {
2025-08-28 18:27:07 +02:00
try {
return await db
2026-05-11 16:25:16 +02:00
.$pickTables<"chats">()
2025-08-28 18:27:07 +02:00
.deleteFrom("chats")
.where("chats.chatid", "=", chatId)
.returning("chatid")
.execute();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
message: `Error while deleting chat: ${(e as Error).message}`,
});
}
2025-08-04 17:45:44 +02:00
};
export const getUserByChatHandler = async ({
2025-08-28 18:27:07 +02:00
chatId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
chatId: ChatsChatid;
2025-08-04 17:45:44 +02:00
}) => {
2025-08-28 18:27:07 +02:00
const chat = await db
2026-05-11 16:25:16 +02:00
.$pickTables<"chats">()
2025-08-28 18:27:07 +02:00
.selectFrom("chats")
.select(["chatid", "created_at", "user_ref", getUserInfo()])
.where("chats.chatid", "=", chatId)
.executeTakeFirstOrThrow(
() => new Error(`Chat not found - chatId: ${chatId}`),
);
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
if (!chat.userinfo) {
throw new TRPCError({ code: "NOT_FOUND" });
}
return chat.userinfo as ChatUserInfo;
2025-08-04 17:45:44 +02:00
};
export const getChatByUserIdHandler = async ({
2025-08-28 18:27:07 +02:00
userId,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
userId: UsersId;
2025-08-04 17:45:44 +02:00
}) => {
2025-08-28 18:27:07 +02:00
const chat = await db
2026-05-11 16:25:16 +02:00
.$pickTables<"chats">()
2025-08-28 18:27:07 +02:00
.selectFrom("chats")
.select("chatid")
.where("chats.user_ref", "=", userId)
.executeTakeFirst();
return chat?.chatid || null;
2025-08-04 17:45:44 +02:00
};