infoalloggi-monorepo/apps/infoalloggi/src/server/api/routers/interests.ts

134 lines
3.7 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import {
AddIntrest,
GetUserInterests,
HasUserInterest,
RemoveInterest,
} from "~/server/services/interests.service";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import z from "zod/v4";
2025-08-04 17:45:44 +02:00
import { zAnnuncioId, zUserId } from "~/server/utils/zod_types";
import { NewMail } from "~/server/services/mailer";
import { findUser_byId_MINI } from "~/server/services/user.service";
import { db } from "~/server/db";
import { env } from "~/env.mjs";
import { TRPCError } from "@trpc/server";
export const intrestsRouter = createTRPCRouter({
addIntrest: protectedProcedure
.input(
z.object({
annuncioId: zAnnuncioId,
/**Optional */
userId: zUserId.optional(),
}),
)
.mutation(async ({ ctx, input }) => {
const userId = input.userId || ctx.session.id;
await AddIntrest({
annuncioId: input.annuncioId,
userId,
});
const annuncio = await db
.selectFrom("annunci")
.select(["id", "codice", "titolo_it"])
.where("id", "=", input.annuncioId)
.executeTakeFirst();
if (!annuncio) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Annuncio not found",
});
}
const user = await findUser_byId_MINI({
userId,
});
if (!user) {
throw new TRPCError({
code: "NOT_FOUND",
message: "User not found",
});
}
await NewMail({
userId,
mailType: "generic",
to: "web@infoalloggi.it",
subject: "Utente interessato ad un annuncio",
props: {
title: "Nuovo interesse per un annuncio",
testo: `L'utente ${user.username} (${user.email}) ha mostrato interesse per l'annuncio "${annuncio.titolo_it}" (Codice: ${annuncio.codice}).`,
link: {
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/admin/user-view/ricerca/${userId}`,
label: "Visualizza utente",
},
},
});
return { success: true };
}),
removeIntrest: protectedProcedure
.input(
z.object({
annuncioId: zAnnuncioId,
userId: zUserId.optional(),
}),
)
.mutation(async ({ ctx, input }) => {
return await RemoveInterest({
annuncioId: input.annuncioId,
userId: input.userId || ctx.session.id,
});
}),
hasUserInterest: protectedProcedure
.input(
z.object({
annuncioId: zAnnuncioId,
userId: zUserId.optional(),
}),
)
.query(async ({ ctx, input }) => {
return await HasUserInterest({
annuncioId: input.annuncioId,
userId: input.userId || ctx.session.id,
});
}),
getUserInterests: protectedProcedure
.input(
z.object({
userId: zUserId.optional(),
}),
)
.query(async ({ input, ctx }) => {
return await GetUserInterests(input.userId || ctx.session.id);
}),
getUserInterestsAnnunci: protectedProcedure
.input(
z.object({
userId: zUserId.optional(),
}),
)
.query(async ({ input, ctx }) => {
const interests = await GetUserInterests(input.userId || ctx.session.id);
return await db
.selectFrom("annunci")
.select([
"annunci.id",
"annunci.codice",
"annunci.prezzo",
"annunci.desc_en",
"annunci.desc_it",
"annunci.url_immagini",
"annunci.titolo_en",
"annunci.titolo_it",
"annunci.tipo",
"annunci.consegna",
"annunci.stato",
"annunci.web",
])
.where("web", "=", true)
.where("stato", "!=", "Sospeso")
.where("annunci.id", "in", interests)
.execute();
}),
});