Sistemato magazzino
This commit is contained in:
@@ -23,6 +23,68 @@ enum StatoMagazzinoVoce {
|
||||
@@map("stato_magazzino_voce")
|
||||
}
|
||||
|
||||
enum StatoLista {
|
||||
bozza
|
||||
privato
|
||||
gruppo
|
||||
pubblico
|
||||
|
||||
@@map("stato_lista")
|
||||
}
|
||||
|
||||
enum StatoModerazioneLista {
|
||||
proposto
|
||||
approvato
|
||||
rifiutato
|
||||
|
||||
@@map("stato_moderazione_lista")
|
||||
}
|
||||
|
||||
enum StatoCategoria {
|
||||
confermata
|
||||
da_approvare
|
||||
|
||||
@@map("stato_categoria")
|
||||
}
|
||||
|
||||
enum TipoNotifica {
|
||||
MATERIALE_PROPOSTO
|
||||
CATEGORIA_PROPOSTA
|
||||
TIPO_EVENTO_PROPOSTO
|
||||
LISTA_PROPOSTA
|
||||
|
||||
@@map("tipo_notifica")
|
||||
}
|
||||
|
||||
// Coda di notifiche di moderazione (nuove proposte di materiale/categoria/tipo
|
||||
// evento/lista in attesa di revisione): visibile solo a chi ha ruolo 'moderatore',
|
||||
// non ci sono ancora notifiche personali nel dominio magazzino.
|
||||
model Notifica {
|
||||
id Int @id @default(autoincrement())
|
||||
tipo TipoNotifica
|
||||
messaggio String
|
||||
link String?
|
||||
letta Boolean @default(false)
|
||||
dataCreazione DateTime @default(now()) @map("data_creazione")
|
||||
|
||||
@@map("notifica")
|
||||
}
|
||||
|
||||
// Tassonomia delle categorie di materiale, gestita dal moderatore (CRUD diretto,
|
||||
// sempre creata "confermata") con un flusso di proposta aperto a qualsiasi org
|
||||
// autenticata (crea in "da_approvare", poi approvata/rifiutata dal moderatore).
|
||||
// Materiale.categoria resta per ora un campo stringa libero, non collegato a questa
|
||||
// tabella: introdurla come FK è un passo successivo, fuori scope qui.
|
||||
model Categoria {
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
stato StatoCategoria @default(confermata)
|
||||
creatoDaOrgId String? @map("creato_da_org_id")
|
||||
creatoIl DateTime @default(now()) @map("creato_il")
|
||||
|
||||
@@map("categoria")
|
||||
}
|
||||
|
||||
model Materiale {
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
@@ -32,56 +94,67 @@ model Materiale {
|
||||
propostoDaOrgId String @map("proposto_da_org_id")
|
||||
creatoIl DateTime @default(now()) @map("creato_il")
|
||||
|
||||
listaModelloVoci ListaModelloVoce[]
|
||||
listaVoci ListaVoce[]
|
||||
magazzinoVoci MagazzinoVoce[]
|
||||
eventoCheck EventoCheck[]
|
||||
listaVoci ListaVoce[]
|
||||
magazzinoVoci MagazzinoVoce[]
|
||||
eventoCheck EventoCheck[]
|
||||
|
||||
@@map("materiale")
|
||||
}
|
||||
|
||||
model TipoEvento {
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
// Stessa semantica/enum di Categoria.stato: un tipo evento creato dal moderatore
|
||||
// nasce 'confermata', uno proposto da un'organizzazione nasce 'da_approvare'.
|
||||
stato StatoCategoria @default(confermata)
|
||||
creatoDaOrgId String? @map("creato_da_org_id")
|
||||
creatoIl DateTime @default(now()) @map("creato_il")
|
||||
|
||||
listeModello ListaModello[]
|
||||
liste Lista[]
|
||||
|
||||
@@map("tipo_evento")
|
||||
}
|
||||
|
||||
model ListaModello {
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
tipoEventoId String @map("tipo_evento_id")
|
||||
pubblica Boolean @default(true)
|
||||
|
||||
tipoEvento TipoEvento @relation(fields: [tipoEventoId], references: [id])
|
||||
voci ListaModelloVoce[]
|
||||
|
||||
@@map("lista_modello")
|
||||
}
|
||||
|
||||
model ListaModelloVoce {
|
||||
listaModelloId String @map("lista_modello_id")
|
||||
materialeId String @map("materiale_id")
|
||||
quantita Int
|
||||
|
||||
listaModello ListaModello @relation(fields: [listaModelloId], references: [id])
|
||||
materiale Materiale @relation(fields: [materialeId], references: [id])
|
||||
|
||||
@@id([listaModelloId, materialeId])
|
||||
@@map("lista_modello_voce")
|
||||
}
|
||||
|
||||
model Lista {
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
orgId String @map("org_id")
|
||||
creataIl DateTime @default(now()) @map("creata_il")
|
||||
id String @id @default(uuid())
|
||||
nome String
|
||||
// Valorizzato solo per le liste in stato 'gruppo' (condivise con l'organizzazione):
|
||||
// le liste 'bozza'/'privato'/'pubblico' sono personali e non hanno alcuna org, anche
|
||||
// per un utente che ha un'organizzazione attiva sul token al momento della creazione.
|
||||
orgId String? @map("org_id")
|
||||
// Nullable perché le liste create prima di questo campo non hanno un autore noto;
|
||||
// da qui in poi è sempre valorizzato da req.auth.userId alla creazione.
|
||||
creataDaUserId String? @map("creata_da_user_id")
|
||||
stato StatoLista @default(bozza)
|
||||
creataIl DateTime @default(now()) @map("creata_il")
|
||||
|
||||
// Moderazione, ortogonale a `stato`: nullo per bozza/privato/gruppo, valorizzato
|
||||
// solo quando stato = pubblico (proposto/approvato/rifiutato, vedi liste.service.ts).
|
||||
statoModerazione StatoModerazioneLista? @map("stato_moderazione")
|
||||
|
||||
// Ex campo obbligatorio di ListaModello, ora opzionale su tutte le liste: serve solo
|
||||
// a filtrare il catalogo pubblico per tipo evento.
|
||||
tipoEventoId String? @map("tipo_evento_id")
|
||||
tipoEvento TipoEvento? @relation(fields: [tipoEventoId], references: [id])
|
||||
|
||||
// Lineage self-referenziato: da quale lista pubblica approvata è stata forkata questa
|
||||
// (fork = "usa come base"). Best-effort/storico: cancellare l'origine non deve
|
||||
// bloccare né trascinare i figli, quindi SetNull.
|
||||
parentId String? @map("parent_id")
|
||||
parent Lista? @relation("ListaParent", fields: [parentId], references: [id], onDelete: SetNull)
|
||||
figlie Lista[] @relation("ListaParent")
|
||||
|
||||
voci ListaVoce[]
|
||||
eventi Evento[]
|
||||
|
||||
// Sotto-liste agganciate a questa lista personale: un solo livello di nesting
|
||||
// (una sotto-lista non può avere a sua volta sotto-liste), validato in liste.service.ts.
|
||||
sottoListe ListaSottoLista[] @relation("SottoListePadre")
|
||||
usataComeSottoListaIn ListaSottoLista[] @relation("SottoListaFiglia")
|
||||
|
||||
@@index([stato, statoModerazione])
|
||||
@@index([tipoEventoId])
|
||||
@@index([parentId])
|
||||
@@map("lista")
|
||||
}
|
||||
|
||||
@@ -97,6 +170,35 @@ model ListaVoce {
|
||||
@@map("lista_voce")
|
||||
}
|
||||
|
||||
model ListaSottoLista {
|
||||
listaId String @map("lista_id")
|
||||
sottoListaId String @map("sotto_lista_id")
|
||||
|
||||
lista Lista @relation("SottoListePadre", fields: [listaId], references: [id])
|
||||
sottoLista Lista @relation("SottoListaFiglia", fields: [sottoListaId], references: [id])
|
||||
|
||||
@@id([listaId, sottoListaId])
|
||||
@@map("lista_sotto_lista")
|
||||
}
|
||||
|
||||
model GruppoMagazzino {
|
||||
id String @id @default(uuid())
|
||||
orgId String @map("org_id")
|
||||
nome String
|
||||
// Un solo livello di nesting (uno scaffale contiene kit, un kit non contiene
|
||||
// a sua volta altri gruppi), validato in gruppiMagazzino.service.ts.
|
||||
parentId String? @map("parent_id")
|
||||
creatoIl DateTime @default(now()) @map("creato_il")
|
||||
|
||||
parent GruppoMagazzino? @relation("GruppoMagazzinoParent", fields: [parentId], references: [id], onDelete: SetNull)
|
||||
figli GruppoMagazzino[] @relation("GruppoMagazzinoParent")
|
||||
voci MagazzinoVoce[]
|
||||
|
||||
@@index([orgId])
|
||||
@@index([parentId])
|
||||
@@map("gruppo_magazzino")
|
||||
}
|
||||
|
||||
model MagazzinoVoce {
|
||||
id String @id @default(uuid())
|
||||
orgId String @map("org_id")
|
||||
@@ -105,9 +207,14 @@ model MagazzinoVoce {
|
||||
stato StatoMagazzinoVoce
|
||||
posizione String?
|
||||
note String?
|
||||
// Nullo finché la giacenza non viene organizzata in un gruppo (scaffale/kit):
|
||||
// eliminare il gruppo non elimina la voce, la riporta solo tra le "non organizzate".
|
||||
gruppoId String? @map("gruppo_id")
|
||||
|
||||
materiale Materiale @relation(fields: [materialeId], references: [id])
|
||||
materiale Materiale @relation(fields: [materialeId], references: [id])
|
||||
gruppo GruppoMagazzino? @relation(fields: [gruppoId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([gruppoId])
|
||||
@@map("magazzino_voce")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user