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 { 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 { return prisma.evento.findUnique({ where: { id } }); } create(data: CreateEventoData): Promise { return prisma.evento.create({ data, include: includeEvento }); } update(id: string, data: UpdateEventoData): Promise { 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 { 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 { 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 { return prisma.evento.findMany({ where: { orgId, dataInizio: { lte: a }, dataFine: { gte: da }, ...(brancaId ? { brancaId } : {}), }, orderBy: { dataInizio: 'asc' }, }); } createRisorsaCollegata(data: CreateRisorsaCollegataData): Promise { return prisma.risorsaCollegata.create({ data }); } } export const eventiRepository = new EventiRepository();