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

194 lines
4.8 KiB
TypeScript
Raw Normal View History

import { z } from "zod/v4";
import { AnnunciUpdateSchema, annunciId } from "~/schemas/public/Annunci";
import { servizioServizioId } from "~/schemas/public/Servizio";
2025-08-04 17:45:44 +02:00
import {
2025-08-28 18:27:07 +02:00
adminProcedure,
apiProcedure,
2025-08-28 18:27:07 +02:00
createTRPCRouter,
protectedProcedure,
publicProcedure,
2025-08-04 17:45:44 +02:00
} from "~/server/api/trpc";
import {
2025-08-28 18:27:07 +02:00
editAnnuncioHandler,
get_AnnunciPositionsHandler,
getAnnunciById_rawImgUrls,
2025-08-28 18:27:07 +02:00
getAnnunciListHandler,
getAnnuncioData,
getAnnunciRicerca,
getAnnunciSchedaData,
2025-08-28 18:27:07 +02:00
getCodici_AnnunciHandler,
getOptions_AnnunciHandler,
getProprietarioDataHandler,
type ImgToRemove,
removeAnnuncioMedia,
type VideoToRemove,
2025-08-04 17:45:44 +02:00
} from "~/server/controllers/annunci.controller";
import { getIncrociAnnuncio } from "~/server/controllers/servizio.controller";
import { db } from "~/server/db";
import { NewMail } from "~/server/services/mailer";
import { TypstGenerate } from "~/server/services/typst.service";
2025-08-04 17:45:44 +02:00
export const annunciRouter = createTRPCRouter({
2025-08-29 16:18:32 +02:00
editAnnuncio: adminProcedure
.input(z.object({ annuncioId: annunciId, data: AnnunciUpdateSchema }))
2025-08-29 16:18:32 +02:00
.mutation(async ({ input }) => {
return await editAnnuncioHandler({
...input,
});
}),
2025-08-28 18:27:07 +02:00
getAnnunciList: publicProcedure.query(async () => {
return await getAnnunciListHandler();
}),
2025-08-29 16:18:32 +02:00
getAnnunciOptions: publicProcedure.query(async () => {
return await getOptions_AnnunciHandler();
2025-08-28 18:27:07 +02:00
}),
getAnnuncioData: publicProcedure
2025-08-28 18:27:07 +02:00
.input(
z.object({
cod: z.string(),
}),
)
2025-08-28 18:27:07 +02:00
.query(async ({ input }) => {
return await getAnnuncioData({ ...input });
2025-08-28 18:27:07 +02:00
}),
getAnnuncioFull: adminProcedure
.input(
z.object({
id: annunciId,
}),
)
.query(async ({ input }) => {
return await db
2026-05-11 16:25:16 +02:00
.$pickTables<"annunci">()
.selectFrom("annunci")
.selectAll()
.where("id", "=", input.id)
.executeTakeFirst();
}),
getAnnuncioById_rawImgUrls: publicProcedure
2025-08-28 18:27:07 +02:00
.input(
z.object({
id: annunciId,
2025-08-28 18:27:07 +02:00
}),
)
.query(async ({ input }) => {
return await getAnnunciById_rawImgUrls({ ...input });
2025-08-28 18:27:07 +02:00
}),
getSchedaAnnuncioData: adminProcedure
.input(
z.object({
id: annunciId,
}),
)
.query(async ({ input }) => {
return await getAnnunciSchedaData(input.id);
}),
getSchedaAnnuncioPdf: adminProcedure
.input(
z.object({
id: annunciId,
}),
)
.mutation(async ({ input }) => {
const data = await getAnnunciSchedaData(input.id);
const pdfBuffer = await TypstGenerate({
templateId: "annuncio.typ",
data,
});
return {
pdf: pdfBuffer.toString("base64"),
title: `scheda-annuncio-${data.codice}.pdf`,
};
}),
2025-08-29 16:18:32 +02:00
getCodici: publicProcedure.query(async () => {
return await getCodici_AnnunciHandler();
}),
2025-08-28 18:27:07 +02:00
getMapping: publicProcedure
.input(
z.object({
comune: z.string().optional(),
consegna: z.number().array().optional(),
2025-08-29 16:18:32 +02:00
tipologia: z.string().optional(),
minBudget: z.number().optional(),
maxBudget: z.number().optional(),
2025-08-28 18:27:07 +02:00
}),
)
.query(async ({ input }) => {
return await get_AnnunciPositionsHandler({
...input,
});
}),
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
getProprietarioData: protectedProcedure
.input(z.object({ annuncioId: annunciId, servizioId: servizioServizioId }))
2025-08-28 18:27:07 +02:00
.query(async ({ input }) => {
return await getProprietarioDataHandler({
annuncioId: input.annuncioId,
servizioId: input.servizioId,
});
}),
annunciRicerca: publicProcedure
2025-08-29 16:18:32 +02:00
.input(
z.object({
comune: z.string().optional(),
consegna: z.number().array().optional(),
2025-08-29 16:18:32 +02:00
sort: z.enum(["Recenti", "Prezzo", "Consegna", "Mq"]).optional(),
tipologia: z.string().optional(),
minBudget: z.number().optional(),
maxBudget: z.number().optional(),
2025-08-29 16:18:32 +02:00
}),
)
.query(async ({ input }) => {
return await getAnnunciRicerca({
2025-08-29 16:18:32 +02:00
...input,
});
}),
/**Used for cron job */
checkAnnunci: apiProcedure.query(async () => {
const hasAnnunci = await db
2026-05-11 16:25:16 +02:00
.$pickTables<"annunci">()
.selectFrom("annunci")
.select("id")
.where("stato", "=", "Attivo")
.where("web", "is", true)
.execute();
if (hasAnnunci.length === 0) {
await NewMail({
template: {
mailType: "generic",
props: {
title: "Attenzione: Nessun annuncio attivo!",
testo:
"Nel sistema non è presente nessun annuncio con stato Attivo e visibile sul web.",
},
},
mail: {
subject: "Attenzione: Nessun annuncio attivo!",
to: "m.pedone98@gmail.com",
},
});
return { status: "no_annunci", timestamp: Date.now() };
}
return { status: "ok", timestamp: Date.now() };
}),
removeAnnuncioMedia: adminProcedure
.input(z.custom<ImgToRemove | VideoToRemove>())
.mutation(async ({ input }) => {
return await removeAnnuncioMedia({
...input,
});
}),
getIncrociAnnuncio: protectedProcedure
.input(
z.object({
annuncioId: annunciId,
}),
)
.query(async ({ input }) => {
return await getIncrociAnnuncio(input.annuncioId);
}),
2025-08-04 17:45:44 +02:00
});