Refactor: Remove unused procedures and clean up router files

- Deleted contact router and its associated mail functionality.
- Removed addEvent mutation from event_queue router.
- Cleaned up fatture router by removing createClient and getListClienti procedures.
- Commented out deletePrezziario mutation in prezziario router.
- Removed unused procedures in servizio router, including getServizioOrdini and getPreOnboardData.
- Cleaned up stats router by removing commented-out code.
- Updated stripe router to restrict health check to admin users and changed several public procedures to protected.
- Commented out sync router procedures and related types.
- Removed unused client-related functions in fic controller.
- Cleaned up servizio controller by removing getServizioOrdini and commented-out code.
- Refactored auth service to inline pwResetTokenFromMailHandler logic.
- Commented out deletePrezziario function in prezziario service.
- Cleaned up zod types by commenting out unused types.
- Commented out getMessagesArray function in kysely helper.
This commit is contained in:
Marco Pedone 2026-03-05 12:32:03 +01:00
parent b27c06a18b
commit ba4debdd1d
27 changed files with 307 additions and 693 deletions

View file

@ -54,7 +54,7 @@ export const FormContattoAnnucio = ({ codice }: { codice: string }) => {
}, },
}); });
const { mutate } = api.servizio.sendContattoEmail.useMutation({ const { mutate } = api.comunicazioni.sendContattoAnnuncioEmail.useMutation({
onError: (error) => { onError: (error) => {
console.error(error); console.error(error);
toast.error("Errore durante l'invio dell'email", { toast.error("Errore durante l'invio dell'email", {

View file

@ -21,7 +21,7 @@ const ResetWToken: NextPageWithLayout<ResetWTokenProps> = ({
<meta content={t.heads.main_description} name="description" /> <meta content={t.heads.main_description} name="description" />
</Head> </Head>
<main className="py-14"> <main className="py-14">
<div className="mx-auto max-w-screen-xl px-4 text-neutral-600 md:px-8 dark:text-white"> <div className="mx-auto max-w-7xl px-4 text-neutral-600 md:px-8 dark:text-white">
<div className="mx-auto max-w-lg space-y-3 sm:text-center"> <div className="mx-auto max-w-lg space-y-3 sm:text-center">
<p className="font-semibold text-3xl text-accent-foreground sm:text-4xl dark:text-white"> <p className="font-semibold text-3xl text-accent-foreground sm:text-4xl dark:text-white">
{t.pwReset.titolo} {t.pwReset.titolo}

View file

@ -46,12 +46,13 @@ const Contatto: NextPage = () => {
}, },
}); });
const { mutate: contactMutation } = api.contact.postContact.useMutation({ const { mutate: contactMutation } =
onSuccess: () => { api.comunicazioni.sendEmailContatto.useMutation({
setHasSent(true); onSuccess: () => {
form.reset(); setHasSent(true);
}, form.reset();
}); },
});
const onSubmit = (data: z.infer<typeof ContactFormSchema>) => { const onSubmit = (data: z.infer<typeof ContactFormSchema>) => {
contactMutation({ contactMutation({
cognome: data.cognome, cognome: data.cognome,

View file

@ -4,7 +4,6 @@ import { banlistRouter } from "~/server/api/routers/banlist";
import { chatRouter } from "~/server/api/routers/chat"; import { chatRouter } from "~/server/api/routers/chat";
import { chatSSERouter } from "~/server/api/routers/chat_sse"; import { chatSSERouter } from "~/server/api/routers/chat_sse";
import { comunicazioniRouter } from "~/server/api/routers/comunicazioni"; import { comunicazioniRouter } from "~/server/api/routers/comunicazioni";
import { contactRouter } from "~/server/api/routers/contact";
import { eventQueueRouter } from "~/server/api/routers/event_queue"; import { eventQueueRouter } from "~/server/api/routers/event_queue";
import { fattureRouter } from "~/server/api/routers/fatture"; import { fattureRouter } from "~/server/api/routers/fatture";
import { intrestsRouter } from "~/server/api/routers/interests"; import { intrestsRouter } from "~/server/api/routers/interests";
@ -27,7 +26,6 @@ import { inviteRouter } from "./routers/invite";
import { potenzialiRouter } from "./routers/potenziali"; import { potenzialiRouter } from "./routers/potenziali";
import { revalidationRouter } from "./routers/revalidation"; import { revalidationRouter } from "./routers/revalidation";
import { stringsRouter } from "./routers/strings"; import { stringsRouter } from "./routers/strings";
import { syncRouter } from "./routers/sync";
//import { lazy } from '@trpc/server'; //import { lazy } from '@trpc/server';
@ -38,7 +36,6 @@ export const appRouter = createTRPCRouter({
chat: chatRouter, chat: chatRouter,
chatSSE: chatSSERouter, chatSSE: chatSSERouter,
comunicazioni: comunicazioniRouter, comunicazioni: comunicazioniRouter,
contact: contactRouter,
eventQueue: eventQueueRouter, eventQueue: eventQueueRouter,
fatture: fattureRouter, fatture: fattureRouter,
intrests: intrestsRouter, intrests: intrestsRouter,
@ -51,7 +48,7 @@ export const appRouter = createTRPCRouter({
stripe: stripeRouter, stripe: stripeRouter,
test: testRouter, test: testRouter,
users: usersRouter, users: usersRouter,
sync: syncRouter, //sync: syncRouter,
catasto: catastoRouter, catasto: catastoRouter,
banners: bannersRouter, banners: bannersRouter,
flags: flagsRouter, flags: flagsRouter,

View file

@ -17,7 +17,6 @@ import {
getAnnunciMetaByCod, getAnnunciMetaByCod,
getAnnunciRicerca, getAnnunciRicerca,
getCodici_AnnunciHandler, getCodici_AnnunciHandler,
getOnline_AnnuncioIdCodice_AnnunciHandler,
getOptions_AnnunciHandler, getOptions_AnnunciHandler,
getProprietarioDataHandler, getProprietarioDataHandler,
type ImgToRemove, type ImgToRemove,
@ -53,9 +52,7 @@ export const annunciRouter = createTRPCRouter({
getAnnunciOptions: publicProcedure.query(async () => { getAnnunciOptions: publicProcedure.query(async () => {
return await getOptions_AnnunciHandler(); return await getOptions_AnnunciHandler();
}), }),
getOnline_AnnuncioIdCodice: publicProcedure.query(async () => {
return await getOnline_AnnuncioIdCodice_AnnunciHandler();
}),
getAnnuncio: publicProcedure getAnnuncio: publicProcedure
.input( .input(
z.object({ z.object({
@ -128,6 +125,7 @@ export const annunciRouter = createTRPCRouter({
...input, ...input,
}); });
}), }),
/**Used for cron job */
checkAnnunci: apiProcedure.query(async () => { checkAnnunci: apiProcedure.query(async () => {
const hasAnnunci = await db const hasAnnunci = await db
.selectFrom("annunci") .selectFrom("annunci")

View file

@ -18,7 +18,6 @@ import {
isTokenValid, isTokenValid,
passwordOverrideHandler, passwordOverrideHandler,
pwResetSendLinkHandler, pwResetSendLinkHandler,
pwResetTokenFromMailHandler,
resetPasswordFromTokenHandler, resetPasswordFromTokenHandler,
} from "~/server/services/auth.service"; } from "~/server/services/auth.service";
import { zUserId } from "~/server/utils/zod_types"; import { zUserId } from "~/server/utils/zod_types";
@ -105,13 +104,7 @@ export const authRouter = createTRPCRouter({
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
return await passwordOverrideHandler({ ...input }); return await passwordOverrideHandler({ ...input });
}), }),
pwResetGenTokenMail: publicProcedure
.input(z.object({ email: z.string() }))
.mutation(async ({ input }) => {
return await pwResetTokenFromMailHandler({
email: input.email,
});
}),
resetPasswordFromToken: publicProcedure resetPasswordFromToken: publicProcedure
.input( .input(
z.object({ z.object({

View file

@ -1,16 +1,12 @@
import z from "zod"; import z from "zod";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc"; import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
import { import {
getComuneById,
getComuni, getComuni,
getNazioneById,
getNazioni, getNazioni,
getProvincie, getProvincie,
searchComuniByCatasto, searchComuniByCatasto,
} from "~/server/controllers/catasto.controller"; } from "~/server/controllers/catasto.controller";
import { zComuneId, zNazioneId } from "~/server/utils/zod_types";
export const catastoRouter = createTRPCRouter({ export const catastoRouter = createTRPCRouter({
getComuni: publicProcedure.query(async () => { getComuni: publicProcedure.query(async () => {
return await getComuni(); return await getComuni();
@ -24,28 +20,11 @@ export const catastoRouter = createTRPCRouter({
.query(async ({ input }) => { .query(async ({ input }) => {
return await searchComuniByCatasto(input.catasto); return await searchComuniByCatasto(input.catasto);
}), }),
getComuneById: publicProcedure
.input(
z.object({
id: zComuneId,
}),
)
.query(async ({ input }) => {
return await getComuneById(input.id);
}),
getProvincie: publicProcedure.query(async () => { getProvincie: publicProcedure.query(async () => {
return await getProvincie(); return await getProvincie();
}), }),
getNazioni: publicProcedure.query(async () => { getNazioni: publicProcedure.query(async () => {
return await getNazioni(); return await getNazioni();
}), }),
getNazioneById: publicProcedure
.input(
z.object({
id: zNazioneId,
}),
)
.query(async ({ input }) => {
return await getNazioneById(input.id);
}),
}); });

View file

@ -1,10 +1,6 @@
import { TRPCError, tracked } from "@trpc/server"; import { TRPCError, tracked } from "@trpc/server";
import { z } from "zod/v4"; import { z } from "zod/v4";
import { import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
createTRPCRouter,
protectedProcedure,
publicProcedure,
} from "~/server/api/trpc";
import { import {
addTyping, addTyping,
getCurrentlyTyping, getCurrentlyTyping,
@ -16,7 +12,6 @@ import { add } from "~/server/services/chat.service";
import { ee, type OnlineStatus } from "~/server/sse"; import { ee, type OnlineStatus } from "~/server/sse";
import { zChatId, zUserId } from "~/server/utils/zod_types"; import { zChatId, zUserId } from "~/server/utils/zod_types";
import { getKeydbClient } from "~/utils/keydb"; import { getKeydbClient } from "~/utils/keydb";
import { getMessagesArray } from "~/utils/kysely-helper";
//IDEA forse cambiare in semplice interval polling invece di sse //IDEA forse cambiare in semplice interval polling invece di sse
export const chatSSERouter = createTRPCRouter({ export const chatSSERouter = createTRPCRouter({
create: protectedProcedure create: protectedProcedure
@ -94,20 +89,20 @@ export const chatSSERouter = createTRPCRouter({
}); });
return parsedUsers; return parsedUsers;
}), }),
list: publicProcedure.query(async () => { // list: publicProcedure.query(async () => {
return await db // return await db
.selectFrom("chats") // .selectFrom("chats")
.select([ // .select([
"chats.chatid", // "chats.chatid",
"chats.created_at", // "chats.created_at",
"chats.user_ref", // "chats.user_ref",
getMessagesArray(), // getMessagesArray(),
]) // ])
.innerJoin("users", "users.id", "chats.user_ref") // .innerJoin("users", "users.id", "chats.user_ref")
.select(["users.username", "users.email", "users.nome"]) // .select(["users.username", "users.email", "users.nome"])
.orderBy("chats.created_at", "desc") // .orderBy("chats.created_at", "desc")
.execute(); // .execute();
}), // }),
onChatEvent: protectedProcedure onChatEvent: protectedProcedure
.input( .input(

View file

@ -4,7 +4,9 @@ import {
adminProcedure, adminProcedure,
createTRPCRouter, createTRPCRouter,
protectedProcedure, protectedProcedure,
publicProcedure,
} from "~/server/api/trpc"; } from "~/server/api/trpc";
import { SendContattoAnnuncioEmail } from "~/server/controllers/servizio.controller";
import { db } from "~/server/db"; import { db } from "~/server/db";
import { import {
deleteAllUserEmails, deleteAllUserEmails,
@ -16,17 +18,6 @@ import { genPdfSchedaAnnuncioBase64 } from "~/server/services/puppeteer.service"
import { zAnnuncioId, zUserId } from "~/server/utils/zod_types"; import { zAnnuncioId, zUserId } from "~/server/utils/zod_types";
export const comunicazioniRouter = createTRPCRouter({ export const comunicazioniRouter = createTRPCRouter({
// genEmail: publicProcedure
// .input(
// z.object({
// mail: z.custom<MailsTemplates>(),
// }),
// )
// .query(async ({ input }) => {
// return await genMail({
// ...input.mail,
// });
// }),
getEmails: protectedProcedure getEmails: protectedProcedure
.input(z.object({ userId: zUserId })) .input(z.object({ userId: zUserId }))
.query(async ({ input }) => { .query(async ({ input }) => {
@ -52,6 +43,35 @@ export const comunicazioniRouter = createTRPCRouter({
userId: input.userId, userId: input.userId,
}); });
}), }),
sendEmailContatto: publicProcedure
.input(
z.object({
cognome: z.string(),
email: z.email(),
messaggio: z.string(),
nome: z.string(),
telefono: z.string(),
}),
)
.mutation(async ({ input }) => {
await NewMail({
template: {
mailType: "contattoAdminEmail",
props: {
cognome: input.cognome,
email: input.email,
messaggio: input.messaggio,
nome: input.nome,
telefono: input.telefono,
},
},
mail: {
subject: `Richiesta di contatto da ${input.nome}`,
to: "web@infoalloggi.it",
},
});
return { success: true };
}),
sendSchedaAnnuncioEmail: adminProcedure sendSchedaAnnuncioEmail: adminProcedure
.input( .input(
z.object({ z.object({
@ -172,45 +192,20 @@ export const comunicazioniRouter = createTRPCRouter({
); );
} }
}), }),
sendAnnunciEmail: adminProcedure
sendContattoAnnuncioEmail: publicProcedure
.input( .input(
z.object({ z.object({
annunci: zAnnuncioId.array(), codice: z.string(),
to: z.email(), email: z.string(),
messaggio: z.string(),
nome: z.string(),
telefono: z.string(),
}), }),
) )
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
try { return await SendContattoAnnuncioEmail({
const annunci = await db ...input,
.selectFrom("annunci") });
.select([
"annunci.titolo_it as titolo",
"annunci.codice",
"annunci.prezzo",
])
.innerJoin("images_refs", "images_refs.codice", "annunci.codice")
.select("images_refs.img as immagine")
.where("images_refs.ordine", "=", 0)
.where("annunci.id", "in", input.annunci)
.execute();
await NewMail({
template: {
mailType: "shareAnnunci",
props: {
nome: "Admin",
annunci,
},
},
mail: {
subject: `Scheda Annuncio - Infoalloggi.it`,
to: input.to,
},
});
} catch (e) {
throw new Error(
`Errore nell'invio dell'email: ${(e as Error).message}`,
);
}
}), }),
}); });

View file

@ -1,42 +0,0 @@
import { z } from "zod/v4";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
import { NewMail } from "~/server/services/mailer";
// Create a new ratelimiter, that allows 10 requests per 10 seconds
/*
const ratelimit = new RateLimiterHandler({
windowSize: 10,
maxRequests: 10,
analytics: true,
});
*/
export const contactRouter = createTRPCRouter({
postContact: publicProcedure
.input(
z.object({
cognome: z.string(),
email: z.email(),
messaggio: z.string(),
nome: z.string(),
telefono: z.string(),
}),
)
.mutation(async ({ input }) => {
await NewMail({
template: {
mailType: "contattoAdminEmail",
props: {
cognome: input.cognome,
email: input.email,
messaggio: input.messaggio,
nome: input.nome,
telefono: input.telefono,
},
},
mail: {
subject: `Richiesta di contatto da ${input.nome}`,
to: "web@infoalloggi.it",
},
});
return { success: true };
}),
});

View file

@ -1,26 +1,7 @@
import { z } from "zod/v4"; import { apiProcedure, createTRPCRouter } from "~/server/api/trpc";
import { import { processEvents } from "~/server/controllers/event_queue.controller";
apiProcedure,
createTRPCRouter,
publicProcedure,
} from "~/server/api/trpc";
import {
addEventToQueue,
processEvents,
} from "~/server/controllers/event_queue.controller";
import { zEventDataTypes } from "~/server/utils/zod_types";
export const eventQueueRouter = createTRPCRouter({ export const eventQueueRouter = createTRPCRouter({
addEvent: publicProcedure
.input(
z.object({
data: zEventDataTypes,
lock_expires: z.date(),
}),
)
.mutation(async ({ input }) => {
return await addEventToQueue(input);
}),
processEvents: apiProcedure.query(async () => { processEvents: apiProcedure.query(async () => {
return await processEvents(); return await processEvents();
}), }),

View file

@ -1,30 +1,10 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
adminProcedure, import { getClientFromCF } from "~/server/controllers/fic.controller";
createTRPCRouter,
protectedProcedure,
publicProcedure,
} from "~/server/api/trpc";
import {
addClient,
getClientFromCF,
getClientList,
searchClient,
} from "~/server/controllers/fic.controller";
import { ClientSchema } from "~/server/services/fic.service";
export const fattureRouter = createTRPCRouter({ export const fattureRouter = createTRPCRouter({
createClient: protectedProcedure getClientFromCF: adminProcedure
.input(
z.object({
client: ClientSchema,
}),
)
.mutation(async ({ input }) => {
return await addClient(input.client);
}),
getClientFromCF: publicProcedure
.input( .input(
z.object({ z.object({
cf: z.string(), cf: z.string(),
@ -33,16 +13,4 @@ export const fattureRouter = createTRPCRouter({
.query(async ({ input }) => { .query(async ({ input }) => {
return await getClientFromCF(input.cf); return await getClientFromCF(input.cf);
}), }),
getListClienti: adminProcedure.query(async () => {
return await getClientList();
}),
searchClient: adminProcedure
.input(
z.object({
cognome: z.string(),
}),
)
.query(async ({ input }) => {
return await searchClient(input.cognome);
}),
}); });

View file

@ -13,7 +13,6 @@ import {
import { db } from "~/server/db"; import { db } from "~/server/db";
import { import {
addPrezziario, addPrezziario,
deletePrezziario,
getPrezziario, getPrezziario,
getPrezziarioByIdHandler, getPrezziarioByIdHandler,
getPrezziarioByTipologia, getPrezziarioByTipologia,
@ -39,18 +38,18 @@ export const prezziarioRouter = createTRPCRouter({
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
return await addPrezziario({ db, input: input.data }); return await addPrezziario({ db, input: input.data });
}), }),
deletePrezziario: adminProcedure // deletePrezziario: adminProcedure
.input( // .input(
z.object({ // z.object({
idprezziario: zPrezziarioId, // idprezziario: zPrezziarioId,
}), // }),
) // )
.mutation(async ({ input }) => { // .mutation(async ({ input }) => {
return await deletePrezziario({ // return await deletePrezziario({
db, // db,
prezziarioId: input.idprezziario, // prezziarioId: input.idprezziario,
}); // });
}), // }),
getPrezziario: publicProcedure.query(async () => { getPrezziario: publicProcedure.query(async () => {
return await getPrezziario(); return await getPrezziario();
}), }),

View file

@ -10,7 +10,6 @@ import {
createTRPCRouter, createTRPCRouter,
overridableProcedure, overridableProcedure,
protectedProcedure, protectedProcedure,
publicProcedure,
} from "~/server/api/trpc"; } from "~/server/api/trpc";
import { import {
createOrdine, createOrdine,
@ -32,12 +31,10 @@ import {
getDataPerAcquisto, getDataPerAcquisto,
getOrdineRicevutaData, getOrdineRicevutaData,
getPacksPerServizio, getPacksPerServizio,
getPreOnboardData,
getServiziByUserId, getServiziByUserId,
getServizioAnnuncio, getServizioAnnuncio,
getServizioById, getServizioById,
getServizioDataById, getServizioDataById,
getServizioOrdini,
getServizioPagamentoData, getServizioPagamentoData,
getUserPagamenti, getUserPagamenti,
InteractionLogicTipologia, InteractionLogicTipologia,
@ -46,7 +43,6 @@ import {
postAcquistoDataHandler, postAcquistoDataHandler,
removePagamento, removePagamento,
SbloccaContatti, SbloccaContatti,
SendContactEmail,
setupSaldoConsulenzaServizio, setupSaldoConsulenzaServizio,
setupSaldoServizio, setupSaldoServizio,
updatePagamento, updatePagamento,
@ -179,15 +175,6 @@ export const servizioRouter = createTRPCRouter({
.query(async ({ input }) => { .query(async ({ input }) => {
return await getOrdineRicevutaData({ ordineId: input.ordineId }); return await getOrdineRicevutaData({ ordineId: input.ordineId });
}), }),
getServizioOrdini: protectedProcedure
.input(
z.object({
servizioId: zServizioId,
}),
)
.query(async ({ input }) => {
return await getServizioOrdini(input.servizioId);
}),
getOrdini: protectedProcedure getOrdini: protectedProcedure
.input( .input(
@ -198,15 +185,7 @@ export const servizioRouter = createTRPCRouter({
.query(async ({ input }) => { .query(async ({ input }) => {
return await getOrdini(input.userId); return await getOrdini(input.userId);
}), }),
getPreOnboardData: publicProcedure
.input(
z.object({
servizioId: zServizioId,
}),
)
.query(async ({ input }) => {
return await getPreOnboardData(input.servizioId);
}),
getServizio: protectedProcedure getServizio: protectedProcedure
.input( .input(
z.object({ z.object({
@ -322,22 +301,6 @@ export const servizioRouter = createTRPCRouter({
return await removePagamento(input.pagamentoId); return await removePagamento(input.pagamentoId);
}), }),
sendContattoEmail: publicProcedure
.input(
z.object({
codice: z.string(),
email: z.string(),
messaggio: z.string(),
nome: z.string(),
telefono: z.string(),
}),
)
.mutation(async ({ input }) => {
return await SendContactEmail({
...input,
});
}),
setupSaldoConsulenzaServizio: protectedProcedure setupSaldoConsulenzaServizio: protectedProcedure
.input( .input(
z.object({ z.object({

View file

@ -3,77 +3,6 @@ import { db } from "~/server/db";
export const statsRouter = createTRPCRouter({ export const statsRouter = createTRPCRouter({
adminDashStats: adminProcedure.query(async () => { adminDashStats: adminProcedure.query(async () => {
// const userTimeserie = (
// await db
// .selectFrom("users")
// .select((eb) => [
// sql<Date>`date_trunc('day', created_at)`.as("date"),
// eb.fn.count<number>("id").as("value"),
// ])
// .where("isAdmin", "=", false)
// .groupBy("date")
// .orderBy("date")
// .execute()
// ).map((item) => ({
// date: item.date,
// value: parseInt(String(item.value)),
// }));
// const serviziTimeserie = {
// data: Object.values(
// (
// await db
// .selectFrom("servizio")
// .select((eb) => [
// sql<Date>`date_trunc('day', created_at)`.as("date"),
// eb.fn.count<number>("servizio_id").as("value"),
// "tipologia",
// ])
// .groupBy(["date", "tipologia"])
// .orderBy("date")
// .execute()
// ).reduce(
// (acc, item) => {
// const dateStr = item.date.toISOString().slice(0, 10);
// if (!acc[dateStr]) {
// acc[dateStr] = {
// date: item.date,
// valueA: 0,
// valueB: 0,
// };
// }
// if (item.tipologia === TipologiaPosizioneEnum.Transitorio) {
// acc[dateStr].valueA = parseInt(String(item.value));
// } else if (item.tipologia === TipologiaPosizioneEnum.Stabile) {
// acc[dateStr].valueB = parseInt(String(item.value));
// }
// return acc;
// },
// {} as Record<string, StackedTimeserie>,
// ),
// ),
// valueALabel: "Transitorio",
// valueBLabel: "Stabile",
// };
// const contattiTimeserie = (
// await db
// .selectFrom("servizio_annunci")
// .select((eb) => [
// sql<Date>`date_trunc('day', created_at)`.as("date"),
// eb.fn
// .count<number>(eb.fn("concat", ["servizio_id", "annunci_id"]))
// .as("value"),
// ])
// .where("open_contatti_at", "is not", null)
// .groupBy("date")
// .orderBy("date")
// .execute()
// ).map((item) => ({
// date: item.date,
// value: parseInt(String(item.value)),
// }));
const userCount = const userCount =
( (
await db await db

View file

@ -1,8 +1,9 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { import {
adminProcedure,
createTRPCRouter, createTRPCRouter,
protectedApiProcedure,
protectedProcedure, protectedProcedure,
publicProcedure,
} from "~/server/api/trpc"; } from "~/server/api/trpc";
import { import {
createIntentHandler, createIntentHandler,
@ -14,7 +15,7 @@ import {
import { zPagamentoId } from "~/server/utils/zod_types"; import { zPagamentoId } from "~/server/utils/zod_types";
export const stripeRouter = createTRPCRouter({ export const stripeRouter = createTRPCRouter({
health: publicProcedure.query(async () => { health: adminProcedure.query(async () => {
return await stripeHealthCheck(); return await stripeHealthCheck();
}), }),
createIntent: protectedProcedure createIntent: protectedProcedure
@ -28,28 +29,28 @@ export const stripeRouter = createTRPCRouter({
paymentId: input.paymentId, paymentId: input.paymentId,
}); });
}), }),
whIntentCreated: publicProcedure whIntentCreated: protectedApiProcedure
.input( .input(
z.object({ z.object({
paymentId: zPagamentoId, paymentId: zPagamentoId,
pIntentId: z.string(), pIntentId: z.string(),
}), }),
) )
.query(async ({ input }) => { .mutation(async ({ input }) => {
return await whIntentCreatedHandler({ return await whIntentCreatedHandler({
paymentId: input.paymentId, paymentId: input.paymentId,
pIntentId: input.pIntentId, pIntentId: input.pIntentId,
}); });
}), }),
whIntentFailed: publicProcedure whIntentFailed: protectedApiProcedure
.input(z.object({ pIntentId: z.string() })) .input(z.object({ pIntentId: z.string() }))
.query(async ({ input }) => { .mutation(async ({ input }) => {
return await whIntentFailedHandler({ return await whIntentFailedHandler({
pIntentId: input.pIntentId, pIntentId: input.pIntentId,
}); });
}), }),
whIntentSucceeded: publicProcedure whIntentSucceeded: protectedApiProcedure
.input( .input(
z.object({ z.object({
paymentId: zPagamentoId, paymentId: zPagamentoId,
@ -57,7 +58,7 @@ export const stripeRouter = createTRPCRouter({
pm_id: z.string(), pm_id: z.string(),
}), }),
) )
.query(async ({ input }) => { .mutation(async ({ input }) => {
return await whIntentSucceededHandler({ return await whIntentSucceededHandler({
paymentId: input.paymentId, paymentId: input.paymentId,
pIntentId: input.pIntentId, pIntentId: input.pIntentId,

View file

@ -1,96 +1,96 @@
import z from "zod"; // import z from "zod";
import { createTRPCRouter, protectedApiProcedure } from "~/server/api/trpc"; // import { createTRPCRouter, protectedApiProcedure } from "~/server/api/trpc";
import { db } from "~/server/db"; // import { db } from "~/server/db";
type ClienteData = { // type ClienteData = {
cognome?: string | undefined; // cognome?: string | undefined;
nome?: string | undefined; // nome?: string | undefined;
cf?: string | undefined; // cf?: string | undefined;
telefono?: string | undefined; // telefono?: string | undefined;
email?: string | undefined; // email?: string | undefined;
data_nascita?: string | undefined; // data_nascita?: string | undefined;
luogo_nascita?: string | undefined; // luogo_nascita?: string | undefined;
naz_residenza?: string | undefined; // naz_residenza?: string | undefined;
provincia_residenza?: string | undefined; // provincia_residenza?: string | undefined;
cap_residenza?: string | undefined; // cap_residenza?: string | undefined;
comune_residenza?: string | undefined; // comune_residenza?: string | undefined;
indirizzo_residenza?: string | undefined; // indirizzo_residenza?: string | undefined;
civico_residenza?: string | undefined; // civico_residenza?: string | undefined;
}; // };
const clienteDataSchema = z.object({ // const clienteDataSchema = z.object({
cap_residenza: z.string().optional(), // cap_residenza: z.string().optional(),
cf: z.string().optional(), // cf: z.string().optional(),
civico_residenza: z.string().optional(), // civico_residenza: z.string().optional(),
cognome: z.string().optional(), // cognome: z.string().optional(),
comune_residenza: z.string().optional(), // comune_residenza: z.string().optional(),
data_nascita: z.string().optional(), // data_nascita: z.string().optional(),
email: z.string().optional(), // email: z.string().optional(),
indirizzo_residenza: z.string().optional(), // indirizzo_residenza: z.string().optional(),
luogo_nascita: z.string().optional(), // luogo_nascita: z.string().optional(),
naz_residenza: z.string().optional(), // naz_residenza: z.string().optional(),
nome: z.string().optional(), // nome: z.string().optional(),
provincia_residenza: z.string().optional(), // provincia_residenza: z.string().optional(),
telefono: z.string().optional(), // telefono: z.string().optional(),
}); // });
export const syncRouter = createTRPCRouter({ // export const syncRouter = createTRPCRouter({
syncGet: protectedApiProcedure // syncGet: protectedApiProcedure
.input(z.object({ cf: z.string() })) // .input(z.object({ cf: z.string() }))
.query(async ({ input }) => { // .query(async ({ input }) => {
const user = await db // const user = await db
.selectFrom("users_anagrafica") // .selectFrom("users_anagrafica")
.select([ // .select([
"users_anagrafica.codice_fiscale", // "users_anagrafica.codice_fiscale",
"users_anagrafica.userid", // "users_anagrafica.userid",
"users_anagrafica.data_nascita", // "users_anagrafica.data_nascita",
"users_anagrafica.luogo_nascita", // "users_anagrafica.luogo_nascita",
"users_anagrafica.nazione_residenza", // "users_anagrafica.nazione_residenza",
"users_anagrafica.provincia_residenza", // "users_anagrafica.provincia_residenza",
"users_anagrafica.cap_residenza", // "users_anagrafica.cap_residenza",
"users_anagrafica.comune_residenza", // "users_anagrafica.comune_residenza",
"users_anagrafica.via_residenza", // "users_anagrafica.via_residenza",
"users_anagrafica.civico_residenza", // "users_anagrafica.civico_residenza",
]) // ])
.innerJoin("users", "users.id", "users_anagrafica.userid") // .innerJoin("users", "users.id", "users_anagrafica.userid")
.select([ // .select([
"users.nome", // "users.nome",
"users.cognome", // "users.cognome",
"users.email", // "users.email",
"users.telefono", // "users.telefono",
]) // ])
.where("users_anagrafica.codice_fiscale", "=", input.cf) // .where("users_anagrafica.codice_fiscale", "=", input.cf)
.executeTakeFirst(); // .executeTakeFirst();
const result: ClienteData = { // const result: ClienteData = {
cognome: user?.cognome, // cognome: user?.cognome,
nome: user?.nome, // nome: user?.nome,
cf: user?.codice_fiscale || undefined, // cf: user?.codice_fiscale || undefined,
telefono: user?.telefono, // telefono: user?.telefono,
email: user?.email, // email: user?.email,
data_nascita: user?.data_nascita?.toLocaleDateString("it-IT", { // data_nascita: user?.data_nascita?.toLocaleDateString("it-IT", {
year: "numeric", // year: "numeric",
month: "2-digit", // month: "2-digit",
day: "2-digit", // day: "2-digit",
}), // }),
luogo_nascita: user?.luogo_nascita || undefined, // luogo_nascita: user?.luogo_nascita || undefined,
naz_residenza: user?.nazione_residenza || undefined, // naz_residenza: user?.nazione_residenza || undefined,
provincia_residenza: user?.provincia_residenza || undefined, // provincia_residenza: user?.provincia_residenza || undefined,
cap_residenza: user?.cap_residenza || undefined, // cap_residenza: user?.cap_residenza || undefined,
comune_residenza: user?.comune_residenza || undefined, // comune_residenza: user?.comune_residenza || undefined,
indirizzo_residenza: user?.via_residenza || undefined, // indirizzo_residenza: user?.via_residenza || undefined,
civico_residenza: user?.civico_residenza || undefined, // civico_residenza: user?.civico_residenza || undefined,
}; // };
return result; // return result;
}), // }),
syncPost: protectedApiProcedure // syncPost: protectedApiProcedure
.input(z.object({ data: clienteDataSchema })) // .input(z.object({ data: clienteDataSchema }))
.mutation(async ({ input }) => { // .mutation(async ({ input }) => {
console.log("input", input); // console.log("input", input);
// const parsed = clienteDataSchema.safeParse(JSON.parse(input.data)); // // const parsed = clienteDataSchema.safeParse(JSON.parse(input.data));
// console.log("parsed", parsed); // // console.log("parsed", parsed);
return { message: "Data received" }; // return { message: "Data received" };
}), // }),
}); // });

View file

@ -20,6 +20,43 @@ import { getClientProfilo } from "~/server/services/user.service";
import { zUserId } from "~/server/utils/zod_types"; import { zUserId } from "~/server/utils/zod_types";
export const usersRouter = createTRPCRouter({ export const usersRouter = createTRPCRouter({
getUser: protectedProcedure
.input(
z.object({
id: zUserId,
}),
)
.query(async ({ input }) => {
return await getUserHandler({ db, id: input.id });
}),
getUsers: adminProcedure.query(async () => {
return await db
.selectFrom("users")
.selectAll()
.orderBy("id", "desc")
.execute();
}),
getAdmins: adminProcedure.query(async () => {
return await db
.selectFrom("users")
.selectAll()
.where("isAdmin", "=", true)
.orderBy("id", "desc")
.execute();
}),
getClientProfilo: protectedProcedure
.input(
z.object({
userId: zUserId,
}),
)
.query(async ({ input }) => {
return getClientProfilo({
db,
userId: input.userId,
});
}),
blockUser: adminProcedure blockUser: adminProcedure
.input( .input(
z.object({ z.object({
@ -61,46 +98,8 @@ export const usersRouter = createTRPCRouter({
getActiveUsersWithoutChat: adminProcedure.query(async () => { getActiveUsersWithoutChat: adminProcedure.query(async () => {
return await getActiveUserWithoutChatHandler({ db }); return await getActiveUserWithoutChatHandler({ db });
}), }),
getClientProfilo: protectedProcedure
.input(
z.object({
userId: zUserId,
}),
)
.query(async ({ input }) => {
return getClientProfilo({
db,
userId: input.userId,
});
}),
getUser: protectedProcedure
.input(
z.object({
id: zUserId,
}),
)
.query(async ({ input }) => {
return await getUserHandler({ db, id: input.id });
}),
getUsers: adminProcedure.query(async () => {
const query = await db
.selectFrom("users")
.selectAll()
.orderBy("id", "desc")
.execute();
return query;
}),
getUsersWChatInfo: adminProcedure.query(async () => { getUsersWChatInfo: adminProcedure.query(async () => {
return await getUsersWithChatInfoHandler({ db }); return await getUsersWithChatInfoHandler({ db });
}), }),
getAdmins: adminProcedure.query(async () => {
return await db
.selectFrom("users")
.selectAll()
.where("isAdmin", "=", true)
.orderBy("id", "desc")
.execute();
}),
}); });

View file

@ -51,27 +51,6 @@ export const getAnnunciListHandler = async (): Promise<
} }
}; };
export const getOnline_AnnuncioIdCodice_AnnunciHandler = async () => {
try {
const data = await db
.selectFrom("annunci")
.select(["codice", "id"])
.where("annunci.web", "=", true)
.where("stato", "!=", "Sospeso")
.execute();
if (!data) {
return [];
}
return data.filter((c) => c.id && c.codice);
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore query getOnline_AnnuncioIdCodice_AnnunciHandler: ${(e as Error).message}`,
});
}
};
export const getCodici_AnnunciHandler = async (): Promise<string[]> => { export const getCodici_AnnunciHandler = async (): Promise<string[]> => {
try { try {
const codici = await db const codici = await db

View file

@ -1,6 +1,4 @@
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import type { ComuniId } from "~/schemas/public/Comuni";
import type { NazioniId } from "~/schemas/public/Nazioni";
import { db } from "../db"; import { db } from "../db";
export const getComuni = async () => { export const getComuni = async () => {
@ -28,20 +26,6 @@ export const searchComuniByCatasto = async (catasto: string[]) => {
}); });
} }
}; };
export const getComuneById = async (id: ComuniId) => {
try {
return await db
.selectFrom("comuni")
.selectAll()
.where("id", "=", id)
.executeTakeFirst();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting ComuneById: ${(e as Error).message}`,
});
}
};
export const getProvincie = async () => { export const getProvincie = async () => {
try { try {
@ -64,17 +48,3 @@ export const getNazioni = async () => {
}); });
} }
}; };
export const getNazioneById = async (id: NazioniId) => {
try {
return await db
.selectFrom("nazioni")
.selectAll()
.where("id", "=", id)
.executeTakeFirst();
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error while getting NazioneById: ${(e as Error).message}`,
});
}
};

View file

@ -67,7 +67,7 @@ export const nextTimeForNotification = () => {
return lock_expires; return lock_expires;
}; };
export type EventDataTypes = Email_EventData | SMS_EventData; type EventDataTypes = Email_EventData | SMS_EventData;
type NewEventQueueProps = Override<NewEventQueue, { data: EventDataTypes }>; type NewEventQueueProps = Override<NewEventQueue, { data: EventDataTypes }>;

View file

@ -1,30 +1,29 @@
import type { Client } from "@fattureincloud/fattureincloud-ts-sdk";
import { clientsApi, companyId } from "~/server/FattureInCloud"; import { clientsApi, companyId } from "~/server/FattureInCloud";
export const getClientList = async () => { // export const getClientList = async () => {
const clients = await clientsApi.listClients( // const clients = await clientsApi.listClients(
companyId, // companyId,
undefined, // undefined,
"detailed", // "detailed",
undefined, // undefined,
undefined, // undefined,
100, // 100,
); // );
return clients.data; // return clients.data;
}; // };
export const searchClient = async (cognome: string) => { // export const searchClient = async (cognome: string) => {
const clients = await clientsApi.listClients( // const clients = await clientsApi.listClients(
companyId, // companyId,
undefined, // undefined,
"detailed", // "detailed",
undefined, // undefined,
undefined, // undefined,
100, // 100,
`name contains '${cognome}'`, // `name contains '${cognome}'`,
); // );
return clients.data; // return clients.data;
}; // };
export const getClientFromCF = async (cf: string) => { export const getClientFromCF = async (cf: string) => {
if (cf.length < 11) { if (cf.length < 11) {
return null; return null;
@ -41,7 +40,7 @@ export const getClientFromCF = async (cf: string) => {
return clients.data; return clients.data;
}; };
export const addClient = async (client: Client) => { // export const addClient = async (client: Client) => {
const newClient = await clientsApi.createClient(companyId, { data: client }); // const newClient = await clientsApi.createClient(companyId, { data: client });
return newClient.data; // return newClient.data;
}; // };

View file

@ -158,53 +158,7 @@ export const getServiziByUserId = async (userId: UsersId) => {
}); });
} }
}; };
export const getPreOnboardData = async (servizioId: ServizioServizioId) => {
try {
const servizio = await getServizioById(servizioId);
if (!servizio) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Servizio not found",
});
}
const userData = await db
.selectFrom("users")
.select([
"users.id",
"users.nome",
"users.cognome",
"users.email",
"users.telefono",
])
.where("id", "=", servizio.user_id)
.executeTakeFirstOrThrow(
() => new Error(`User not found - userId: ${servizio.user_id}`),
);
if (!userData) {
throw new TRPCError({
code: "NOT_FOUND",
message: "User not found",
});
}
const hasPrevious = await db
.selectFrom("servizio")
.select("servizio_id")
.where("user_id", "=", servizio.user_id)
.where("servizio_id", "!=", servizioId)
.where("isOkAcconto", "=", true)
.executeTakeFirst();
return { hasPrevious: !!hasPrevious, servizio, userData };
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error fetching pre-onboard data: ${(e as Error).message}`,
});
}
};
export const getDataPerAcquisto = async (servizioId: ServizioServizioId) => { export const getDataPerAcquisto = async (servizioId: ServizioServizioId) => {
try { try {
const servizio = await getServizioById(servizioId); const servizio = await getServizioById(servizioId);
@ -1946,7 +1900,7 @@ export const getUserPagamenti = async (
} }
}; };
export const SendContactEmail = async ({ export const SendContattoAnnuncioEmail = async ({
codice, codice,
nome, nome,
email, email,
@ -2154,37 +2108,3 @@ export const getOrdineRicevutaData = async ({
}); });
} }
}; };
export const getServizioOrdini = async (servizioId: ServizioServizioId) => {
try {
const data = await db
.selectFrom("ordini")
.selectAll("ordini")
.select((eb) => [
jsonArrayFrom(
eb
.selectFrom("payments")
.whereRef("payments.ordine_id", "=", "ordini.ordine_id")
.selectAll("payments")
.orderBy("created_at", "desc"),
).as("pagamenti"),
])
.where("servizio_id", "=", servizioId)
.orderBy("created_at", "desc")
.execute();
return data.map((ordine) => ({
...ordine,
pagamenti: ordine.pagamenti.map((payment) => ({
...payment,
created_at: new Date(payment.created_at),
paid_at: payment.paid_at ? new Date(payment.paid_at) : null,
})),
}));
} catch (e) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Error fetching servizio ordini: ${(e as Error).message}`,
});
}
};

View file

@ -53,22 +53,6 @@ export const isTokenValid = async ({ token }: { token: string }) => {
}); });
} }
}; };
export const pwResetTokenFromMailHandler = async ({
email,
}: {
email: string;
}) => {
const user = await findUser_byEmail({ email });
if (!user) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Utente non trovato",
});
}
const token = await genPasswordResetToken({ id: user.id });
return { token, userId: user.id };
};
export const resetPasswordFromTokenHandler = async ({ export const resetPasswordFromTokenHandler = async ({
token, token,
@ -113,7 +97,16 @@ export const resetPasswordFromTokenHandler = async ({
}; };
export const pwResetSendLinkHandler = async ({ email }: { email: string }) => { export const pwResetSendLinkHandler = async ({ email }: { email: string }) => {
const { token, userId } = await pwResetTokenFromMailHandler({ email }); const user = await findUser_byEmail({ email });
if (!user) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Utente non trovato",
});
}
const token = await genPasswordResetToken({ id: user.id });
await NewMail({ await NewMail({
template: { template: {
mailType: "pwResetLink", mailType: "pwResetLink",
@ -125,7 +118,7 @@ export const pwResetSendLinkHandler = async ({ email }: { email: string }) => {
subject: `Richiesta di reset password Infoalloggi.it`, subject: `Richiesta di reset password Infoalloggi.it`,
to: email, to: email,
}, },
userId, userId: user.id,
}); });
}; };

View file

@ -92,26 +92,26 @@ export const updatePrezziario = async ({
} }
}; };
export const deletePrezziario = async ({ // export const deletePrezziario = async ({
db, // db,
prezziarioId, // prezziarioId,
}: { // }: {
db: Querier; // db: Querier;
prezziarioId: PrezziarioIdprezziario; // prezziarioId: PrezziarioIdprezziario;
}): Promise<void> => { // }): Promise<void> => {
try { // try {
await db // await db
.deleteFrom("prezziario") // .deleteFrom("prezziario")
.where("prezziario.idprezziario", "=", prezziarioId) // .where("prezziario.idprezziario", "=", prezziarioId)
.execute(); // .execute();
} catch (error) { // } catch (error) {
throw new TRPCError({ // throw new TRPCError({
code: "INTERNAL_SERVER_ERROR", // code: "INTERNAL_SERVER_ERROR",
message: `Error deleting prezziario: ${(error as Error).message}`, // message: `Error deleting prezziario: ${(error as Error).message}`,
}); // });
} // }
}; // };
type MinimalPrezziario = Pick< type MinimalPrezziario = Pick<
Prezziario, Prezziario,

View file

@ -3,18 +3,15 @@ import type { AnnunciId } from "~/schemas/public/Annunci";
import type { BanlistId } from "~/schemas/public/Banlist"; import type { BanlistId } from "~/schemas/public/Banlist";
import BanType from "~/schemas/public/BanType"; import BanType from "~/schemas/public/BanType";
import type { ChatsChatid } from "~/schemas/public/Chats"; import type { ChatsChatid } from "~/schemas/public/Chats";
import type { ComuniId } from "~/schemas/public/Comuni";
import type { EtichetteIdEtichetta } from "~/schemas/public/Etichette"; import type { EtichetteIdEtichetta } from "~/schemas/public/Etichette";
import type { FlagsId } from "~/schemas/public/Flags"; import type { FlagsId } from "~/schemas/public/Flags";
import type { MessagesMessageid } from "~/schemas/public/Messages"; import type { MessagesMessageid } from "~/schemas/public/Messages";
import type { NazioniId } from "~/schemas/public/Nazioni";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini"; import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
import type { PaymentsId } from "~/schemas/public/Payments"; import type { PaymentsId } from "~/schemas/public/Payments";
import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario"; import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario";
import type { ServizioServizioId } from "~/schemas/public/Servizio"; import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe"; import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe";
import type { UsersId } from "~/schemas/public/Users"; import type { UsersId } from "~/schemas/public/Users";
import type { EventDataTypes } from "~/server/controllers/event_queue.controller";
export const zUserId = z.custom<UsersId>( export const zUserId = z.custom<UsersId>(
(val) => typeof val === "string", (val) => typeof val === "string",
@ -61,10 +58,10 @@ export const zTestiEStringheStingaId = z.custom<TestiEStringheStingaId>(
"falied to validate TestiEStringheStingaId", "falied to validate TestiEStringheStingaId",
); );
export const zEventDataTypes = z.custom<EventDataTypes>( // export const zEventDataTypes = z.custom<EventDataTypes>(
(val) => typeof val === "object", // (val) => typeof val === "object",
"falied to validate EventDataTypes", // "falied to validate EventDataTypes",
); // );
export const zBanlistId = z.custom<BanlistId>( export const zBanlistId = z.custom<BanlistId>(
(val) => typeof val === "number", (val) => typeof val === "number",
@ -85,12 +82,12 @@ export const zPagamentoId = z.custom<PaymentsId>(
"falied to validate PagamentoId", "falied to validate PagamentoId",
); );
export const zComuneId = z.custom<ComuniId>( // export const zComuneId = z.custom<ComuniId>(
(val) => typeof val === "number", // (val) => typeof val === "number",
"falied to validate ComuneId", // "falied to validate ComuneId",
); // );
export const zNazioneId = z.custom<NazioniId>( // export const zNazioneId = z.custom<NazioniId>(
(val) => typeof val === "number", // (val) => typeof val === "number",
"falied to validate NazioneId", // "falied to validate NazioneId",
); // );

View file

@ -3,18 +3,18 @@ import { expressionBuilder } from "kysely";
import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres"; import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/postgres";
import type Database from "~/schemas/Database"; import type Database from "~/schemas/Database";
import type { UsersId } from "~/schemas/public/Users"; import type { UsersId } from "~/schemas/public/Users";
export function getMessagesArray() { // export function getMessagesArray() {
const eb = expressionBuilder<Database, "chats">(); // const eb = expressionBuilder<Database, "chats">();
return jsonArrayFrom( // return jsonArrayFrom(
eb // eb
.selectFrom("messages") // .selectFrom("messages")
.selectAll("messages") // .selectAll("messages")
.whereRef("messages.chatid", "=", "chats.chatid") // .whereRef("messages.chatid", "=", "chats.chatid")
.leftJoin("users", "users.id", "messages.sender") // .leftJoin("users", "users.id", "messages.sender")
.select(["users.nome as sender_nome", "users.isAdmin as sender_isAdmin"]) // .select(["users.nome as sender_nome", "users.isAdmin as sender_isAdmin"])
.orderBy("messages.time", "asc"), // .orderBy("messages.time", "asc"),
).as("messagesArray"); // ).as("messagesArray");
} // }
export type UserInfoQueryType = { export type UserInfoQueryType = {
id: UsersId; id: UsersId;
username: string; username: string;