Files
scouthub/scouthub-eventi-be/src/repositories/eventi.repository.ts
T
2026-07-25 11:59:25 +02:00

98 lines
3.2 KiB
TypeScript

import { Evento, Prisma, RisorsaCollegata } from '@prisma/client';
import { prisma } from '../db/prisma';
const includeEvento = {
children: true,
risorseCollegate: true,
} satisfies Prisma.EventoInclude;
export type EventoConDettagli = Prisma.EventoGetPayload<{ include: typeof includeEvento }>;
export interface CreateEventoData {
orgId: string;
brancaId: string;
parentId: string | null;
titolo: string;
descrizione: string | null;
dataInizio: Date;
dataFine: Date;
tipo: string;
location: string | null;
creatoDa: string;
}
export interface UpdateEventoData {
titolo?: string;
descrizione?: string | null;
dataInizio?: Date;
dataFine?: Date;
tipo?: string;
location?: string | null;
}
export interface CreateRisorsaCollegataData {
eventoId: string;
tipoRisorsa: string;
risorsaId: string;
servizioOrigine: string;
metadata?: Prisma.InputJsonValue | typeof Prisma.JsonNull;
}
export class EventiRepository {
// id + orgId nella stessa where: un evento di un'altra org risulta semplicemente
// "non trovato", mai un 403 che ne rivela l'esistenza.
findByIdAndOrg(id: string, orgId: string): Promise<EventoConDettagli | null> {
return prisma.evento.findFirst({ where: { id, orgId }, include: includeEvento });
}
// Nessun filtro per org: usata dalle chiamate machine-to-machine (POST /eventi/:id/risorse),
// che non sono legate a un'organizzazione utente.
findById(id: string): Promise<Evento | null> {
return prisma.evento.findUnique({ where: { id } });
}
create(data: CreateEventoData): Promise<EventoConDettagli> {
return prisma.evento.create({ data, include: includeEvento });
}
update(id: string, data: UpdateEventoData): Promise<EventoConDettagli> {
return prisma.evento.update({ where: { id }, data, include: includeEvento });
}
// Nessuna cancellazione esplicita di figli/risorse collegate: se ne occupa il
// vincolo ON DELETE CASCADE definito in migration su evento.parent_id e
// risorsa_collegata.evento_id.
remove(id: string): Promise<void> {
return prisma.evento.delete({ where: { id } }).then(() => undefined);
}
// Solo eventi radice (parent_id null) la cui data_inizio/data_fine intersecano
// [da, a]: usata dalla vista "anno" per l'aggregato leggero per giorno.
findRadiceNellIntervallo(orgId: string, da: Date, a: Date): Promise<Evento[]> {
return prisma.evento.findMany({
where: { orgId, parentId: null, dataInizio: { lte: a }, dataFine: { gte: da } },
orderBy: { dataInizio: 'asc' },
});
}
// Radice e figli la cui data_inizio/data_fine intersecano [da, a]: usata dalla
// vista "mese", lettura trasversale a tutte le branche salvo filtro esplicito.
findNellIntervallo(orgId: string, da: Date, a: Date, brancaId?: string): Promise<Evento[]> {
return prisma.evento.findMany({
where: {
orgId,
dataInizio: { lte: a },
dataFine: { gte: da },
...(brancaId ? { brancaId } : {}),
},
orderBy: { dataInizio: 'asc' },
});
}
createRisorsaCollegata(data: CreateRisorsaCollegataData): Promise<RisorsaCollegata> {
return prisma.risorsaCollegata.create({ data });
}
}
export const eventiRepository = new EventiRepository();