Source: https://eleccp.com/en/formato-archivio
Language: en

Data and transparency

# Archive format

How to read, keep and transfer your organization’s data, including outside EleCCP.

[Terms: export and switching](https://eleccp.com/en/termini#cessazione-pacchetto-dati-e-passaggio-ad-altro-servizio)

## Portability and the Data Act

This page documents the export format for data portability and switching to another provider or your own infrastructure under Chapter VI of  [Regulation (EU) 2023/2854 (Data Act)](https://eur-lex.europa.eu/eli/reg/2023/2854/oj/ita) , particularly Article 26. It describes structures, fields, relationships and limitations. Request procedures, deadlines and service conditions are set out in Article 15 of the Terms.

The  [excluded data section](https://eleccp.com/en/formato-archivio#dati-non-compresi-nell-archivio)  lists each exclusion and its reason. Exclusions relating to internal functioning under Article 25(2)(f) concern the risk of disclosing the provider’s trade secrets and must not obstruct or delay switching. Customer data and metadata needed to interpret and reuse it remain exportable.

SHA-256 checksums help verify file integrity; they are not digital signatures or certifications of authenticity.

The technical specification below is the original Italian text. An English translation is not yet available.

**Versione del formato: 6** — in vigore dal 28 settembre 2026. Identificativo: `safe-haccp-archivio-organizzazione`. Indirizzo di questa pagina:  [https://eleccp.com/it/formato-archivio](https://eleccp.com/it/formato-archivio) .

EleCCP consegna all'organizzazione, quando lo chiede o quando chiude, una copia completa dei suoi dati: i registri di autocontrollo, la tracciabilità, i richiami, lo storico delle correzioni e tutti i file originali (foto, documenti, note vocali). Questa pagina descrive com'è fatta quella copia, in modo che si possa leggere e conservare anche senza EleCCP.

## Com'è fatto l'archivio

L'archivio è diviso in **pacchetti ZIP**, ognuno apribile da solo. Un pacchetto non supera la dimensione indicata in `manifest.json` (`package_size_limit_bytes`); un file più grande di quel limite sta da solo nel suo pacchetto.

```
pacchetto 1                        i dati: si apre per primo
  LEGGIMI.txt                      come leggere l'archivio, in italiano
  manifest.json                    l'indice di tutto l'archivio
  organizzazione.json              chi è l'organizzazione: azienda, organizzazione, membri
  dati/<tipo>.jsonl                un file per tipo di dato, un record per riga
pacchetti 2, 3, …                  i file originali
  manifest-parte.json              i file di quel pacchetto, con l'impronta
  file/<media_id>-<nome>           i file originali
```

I pacchetti si chiamano `archivio-<organizzazione>-<export_id>-pacchetto-<NNN>.zip`, con il numero a tre cifre. Per verificare di averli tutti e integri si confronta l'impronta SHA-256 di ogni file ZIP con quella elencata in `manifest.json` (`packages[].sha256`); l'impronta del pacchetto 1, che non può stare dentro sé stesso, è riportata nell'email di consegna e in EleCCP.

## Regole generali

- **Codifica**: tutti i file di testo sono UTF-8.

- **`dati/<tipo>.jsonl`**: [JSON Lines](https://jsonlines.org/) — un oggetto JSON per riga, un record per oggetto. Un tipo senza record ha il file vuoto.

- **Date e ore** (tipo *data e ora*): ISO 8601 con il fuso, in UTC (es. `2026-09-28T08:15:00+00:00`). Per l'ora locale si usa il fuso della sede (`site.timezone`).

- **Date** (tipo *data*): `AAAA-MM-GG`, nel calendario della sede.

- **Numeri decimali** (es. le quantità) sono scritti come testo (`"1.500"`), per non perdere cifre.

- **Identificativi**: ogni record ha un identificativo pubblico (`id`, o `external_id`), un UUID. Un campo che cita un altro record ne porta l'identificativo: la colonna *Rimanda a* dice in quale tipo cercarlo. Le persone sono citate con il loro numero (`*_user_id`), che si ritrova in `organizzazione.json` → `members`.

- **null e vuoto**: `null` vuol dire che il dato non c'è (non registrato, o non applicabile); una stringa vuota vuol dire che il campo esiste ma non è stato compilato.

- **Correzioni**: il record nel file del suo tipo è la versione attuale; ogni versione precedente a una correzione è in `dati/record_version.jsonl`, con il motivo e l'autore.

- **Campi in più**: chi legge l'archivio deve ignorare i campi che non conosce. Un campo nuovo fa comunque salire la versione del formato (vedi in fondo).

## `LEGGIMI.txt`

Un testo in italiano che spiega che cos'è l'archivio, da quanti pacchetti è composto, com'è fatto, come si seguono le relazioni fra i record, quanti record ha ogni tipo, quanti file sono stati copiati e che cosa manca. Rimanda a questa pagina. Non contiene dati che non siano anche negli altri file.

## `manifest.json` (pacchetto 1)

L'indice di tutto l'archivio.

| Campo | Tipo | Significato |
| --- | --- | --- |
| `format` | testo | Sempre `safe-haccp-archivio-organizzazione`: dice che il file è un manifest di questo formato |
| `format_version` | intero | La versione del formato con cui l'archivio è stato scritto |
| `format_url` | testo | L'indirizzo di questa pagina |
| `export_id` | uuid | Identificativo dell'archivio: è lo stesso in tutti i pacchetti |
| `organization_id` | intero | Numero dell'organizzazione |
| `organization_name` | testo o null | Nome dell'organizzazione |
| `snapshot_at` | data e ora | Il momento in cui i dati sono stati letti |
| `extracted_at` | data e ora | Uguale a `snapshot_at` (mantenuto per compatibilità) |
| `recovery_until` | data e ora o null | Se l'organizzazione è in chiusura: fino a quando i dati restano recuperabili in EleCCP |
| `package_size_limit_bytes` | intero | La dimensione massima di un pacchetto, in byte |
| `package_count` | intero | Quanti pacchetti compongono l'archivio, questo compreso |
| `files_count` | intero | Quanti file originali sono stati copiati |
| `kinds` | lista | I tipi di dato, uno per file `dati/<tipo>.jsonl` (vedi sotto) |
| `packages` | lista | Tutti i pacchetti, dal primo (vedi sotto) |
| `missing` | lista | Ciò che manca: file non copiati e parti di `organizzazione.json` (vedi sotto) |

Ogni elemento di `kinds`:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `kind` | testo | Il tipo di dato |
| `count` | intero | Quanti record contiene |
| `path` | testo | Il file nel pacchetto 1 (`dati/<tipo>.jsonl`) |

Ogni elemento di `packages`:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `index` | intero | Numero del pacchetto: 1 per i dati, da 2 in poi per i file |
| `filename` | testo | Nome del file ZIP |
| `size_bytes` | intero o null | Dimensione in byte (null per il pacchetto 1: un file non può contenere la propria dimensione) |
| `sha256` | testo o null | Impronta SHA-256 del file ZIP (null per il pacchetto 1, per la stessa ragione: la sua impronta è nell'email e in EleCCP) |
| `contents` | testo | Solo per il pacchetto 1: che cosa contiene |
| `files_count` | intero | Quanti file originali contiene |
| `files` | lista | I file originali che contiene (vedi sotto) |

Ogni elemento di `files` (qui e in `manifest-parte.json`):

| Campo | Tipo | Significato |
| --- | --- | --- |
| `media_id` | uuid | Identificativo del file, lo stesso citato dai dati (`attachments`, tipo `file`) |
| `path` | testo | Dove si trova nel pacchetto: `file/<media_id>-<nome>` |
| `original_filename` | testo | Il nome con cui il file è stato caricato |
| `content_type` | testo | Il tipo del file (es. `image/jpeg`, `application/pdf`) |
| `size_bytes` | intero | Dimensione in byte |
| `sha256` | testo | Impronta SHA-256 calcolata sui byte copiati nell'archivio |
| `declared_sha256` | testo o null | Impronta dichiarata da chi ha caricato il file, se c'era (non verificata) |

Ogni elemento di `missing` è di uno di due tipi. Un **file non copiato** (ha `media_id`):

| Campo | Tipo | Significato |
| --- | --- | --- |
| `media_id` | uuid | Il file che non è stato copiato |
| `reason` | testo | Perché (vedi i motivi) |
| `attempts` | intero | Quanti tentativi sono stati fatti |
| `expired_at` | data e ora o null | Solo con il motivo `expired`: quando il file è stato cancellato (null se la data non è stata letta) |

| Motivo | Significato |
| --- | --- |
| `not_found` | il file non esiste più nell'archivio dei file |
| `other_organization` | il file appartiene a un'altra organizzazione e non entra in questo archivio |
| `not_ready` | il caricamento del file non era mai stato completato |
| `media_unavailable` | l'archivio dei file non ha risposto, anche dopo i tentativi |
| `no_download_url` | l'archivio dei file non ha dato un modo per scaricarlo |
| `download_failed` | lo scaricamento non è riuscito, anche dopo i tentativi |
| `expired` | il file è stato cancellato perché la sua conservazione era finita (i mesi del vostro abbonamento dalla chiusura del record a cui era allegato); il record resta nei dati |

Una **parte di `organizzazione.json` non disponibile** (ha `section`):

| Campo | Tipo | Significato |
| --- | --- | --- |
| `file` | testo | Sempre `organizzazione.json` |
| `section` | testo | La parte che manca: `company`, `organization` o `members` |
| `source` | testo | Il servizio che doveva darla: `company`, `auth` o `haccp` |
| `reason` | testo | Perché (vedi i motivi) |

| Motivo | Significato |
| --- | --- |
| `service_unavailable` | il servizio non ha risposto |
| `service_error` | il servizio ha risposto con un errore |
| `not_found` | il servizio non conosce l'organizzazione (es. i dati dell'azienda non sono mai stati compilati) |
| `malformed_response` | il servizio ha risposto in una forma non leggibile |
| `haccp_unavailable` | il servizio che raccoglie queste informazioni non ha risposto |
| `haccp_error` | il servizio che raccoglie queste informazioni ha risposto con un errore |
| `not_supported` | la versione del servizio non sapeva ancora fornire queste informazioni |

Un file che manca non rende l'archivio incompleto negli altri contenuti: tutto ciò che è stato possibile copiare c'è, e ciò che manca è dichiarato qui.

## `manifest-parte.json` (pacchetti 2, 3, …)

Ogni pacchetto di file ha il suo indice, così si può verificare anche da solo.

| Campo | Tipo | Significato |
| --- | --- | --- |
| `format` | testo | Sempre `safe-haccp-archivio-organizzazione` |
| `format_version` | intero | La versione del formato |
| `format_url` | testo | L'indirizzo di questa pagina |
| `export_id` | uuid | Identificativo dell'archivio, lo stesso del pacchetto 1 |
| `organization_id` | intero | Numero dell'organizzazione |
| `package_index` | intero | Il numero di questo pacchetto |
| `root_manifest` | testo | Dove si trova l'indice completo (`manifest.json` nel pacchetto 1) |
| `files` | lista | I file di questo pacchetto, con la stessa forma di `files` in `manifest.json` |

## `organizzazione.json` (pacchetto 1)

Chi è l'organizzazione: i dati dell'azienda, l'organizzazione in EleCCP e i suoi membri. Non contiene password, codici di accesso, dispositivi, chiavi né coordinate bancarie o dati di pagamento.

| Campo | Tipo | Significato |
| --- | --- | --- |
| `format` | testo | Sempre `safe-haccp-archivio-organizzazione` |
| `format_version` | intero | La versione del formato |
| `format_url` | testo | L'indirizzo di questa pagina |
| `organization_id` | intero | Numero dell'organizzazione |
| `extracted_at` | data e ora | Quando queste informazioni sono state lette |
| `company` | oggetto o null | I dati dell'azienda (vedi sotto); null se non disponibili |
| `organization` | oggetto o null | L'organizzazione in EleCCP (vedi sotto); null se non disponibile |
| `members` | lista o null | Tutti i membri, anche usciti (vedi sotto); null se non disponibili |
| `missing` | lista | Le parti non disponibili: `{section, source, reason}`, con i motivi elencati sopra |

`company` — i dati dell'azienda:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `organization_id` | intero | Numero dell'organizzazione |
| `legal_name` | testo | Ragione sociale |
| `trade_name` | testo | Insegna o nome commerciale |
| `vat_number` | testo | Partita IVA |
| `tax_code` | testo | Codice fiscale |
| `legal_address` | oggetto | Sede legale (indirizzo, vedi sotto) |
| `email` | testo | Email aziendale |
| `phone` | testo | Telefono |
| `website` | testo | Sito web |
| `is_active` | booleano | Falso se l'anagrafica è disattivata |
| `created_at` | data e ora | Quando l'anagrafica è stata creata |
| `deleted_at` | data e ora o null | Quando l'anagrafica è stata cancellata (null = no) |
| `billing_profile` | oggetto o null | Il profilo di fatturazione in uso (vedi sotto); null se non compilato |

`legal_address` e `billing_profile.address`:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `address_line1` | testo | Indirizzo |
| `address_line2` | testo | Seconda riga dell'indirizzo |
| `city` | testo | Città |
| `state_province` | testo | Provincia |
| `postal_code` | testo | CAP |
| `country_code` | testo | Paese (codice ISO 3166-1 di due lettere, es. `IT`) |

`billing_profile`:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `label` | testo | Nome del profilo |
| `legal_name` | testo | Intestatario delle fatture |
| `vat_number` | testo | Partita IVA |
| `tax_code` | testo | Codice fiscale |
| `address` | oggetto | Indirizzo di fatturazione (stessa forma della sede legale) |
| `billing_email` | testo | Email per le fatture |
| `pec_email` | testo | PEC |
| `sdi_code` | testo | Codice destinatario per la fatturazione elettronica |

`organization`:

| Campo | Tipo | Significato |
| --- | --- | --- |
| `id` | intero | Numero dell'organizzazione |
| `name` | testo | Nome |
| `slug` | testo | Nome breve univoco |
| `organization_type` | testo | `OSA` (operatore del settore alimentare) o `CONSULTANT` (studio di consulenza) |
| `is_active` | booleano | Falso se l'organizzazione è disattivata |
| `created_at` | data e ora | Quando è stata creata |
| `deleted_at` | data e ora o null | Quando è stata cancellata (null = no) |
| `plan_slug` | testo o null | Il piano di abbonamento (codice) |
| `plan_name` | testo o null | Il piano di abbonamento (nome) |

Ogni elemento di `members` (tutti i membri di sempre, anche usciti):

| Campo | Tipo | Significato |
| --- | --- | --- |
| `user_id` | intero | Numero del membro: è il valore dei campi `*_user_id` (e `published_by`, `verified_by`…) nei dati |
| `first_name` | testo | Nome (vuoto per un account cancellato) |
| `last_name` | testo | Cognome (vuoto per un account cancellato) |
| `email` | testo o null | Email; null per gli operatori (che accedono senza email) e per gli account cancellati |
| `role` | testo | Ruolo nell'organizzazione (es. `owner` titolare, `admin`, `member`) |
| `user_kind` | testo | `standard`, `operator` (operatore dell'app) o `staff` |
| `joined_at` | data e ora | Quando è entrato nell'organizzazione |
| `left_at` | data e ora o null | Quando ne è uscito (null = ancora dentro) |
| `status` | testo | Stato (vedi sotto) |

| Stato | Significato |
| --- | --- |
| `active` | membro attivo |
| `removed` | uscito dall'organizzazione |
| `disabled` | account disattivato |
| `deleted` | account cancellato: resta solo il numero, per leggere i registri |

## I dati: `dati/<tipo>.jsonl`

| Tipo | Natura | Contenuto |
| --- | --- | --- |
| [`site`](https://eleccp.com/en/formato-archivio#tipo-site) | registro | Le sedi dell'organizzazione (i locali in cui si lavora). |
| [`site_assignment`](https://eleccp.com/en/formato-archivio#tipo-site-assignment) | registro | Quali membri lavorano in quale sede. Nessuna riga per un membro = tutte le sedi. |
| [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) | registro | I fornitori. |
| [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) | registro | I luoghi di conservazione (frigoriferi, celle, dispense…). |
| [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) | registro | Le attrezzature (abbattitori, forni, sonde…). |
| [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) | registro | Il catalogo dei prodotti che l'attività prepara (ricette). |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | registro | I ricevimenti della merce e gli scontrini d'acquisto. |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | registro | I lotti ricevuti: una riga per prodotto ricevuto in un ricevimento. |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | registro | Le confezioni aperte (con la data limite dopo l'apertura). |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | registro | Le schede di produzione: che cosa si è preparato, quando e con che cosa. |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | registro | Gli ingredienti di ogni scheda di produzione, con la loro fonte. |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | registro | Le unità conservate: le porzioni di una preparazione messe da parte con la loro etichetta. |
| [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) | registro | I lotti di produzione: la partita a cui appartengono le preparazioni. |
| [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) | registro | La storia degli stati di lotti, unità conservate e confezioni aperte. |
| [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) | registro | I tipi di registrazione del piano di autocontrollo (temperature, pulizie…). |
| [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) | registro | Le versioni del piano di autocontrollo di ogni sede. |
| [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) | registro | I punti di controllo di ogni versione del piano. |
| [`plan_suspension`](https://eleccp.com/en/formato-archivio#tipo-plan-suspension) | registro | I periodi in cui il piano, o un suo punto, è stato sospeso. |
| [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) | registro | Le registrazioni che il piano si aspettava, finestra per finestra, con il loro esito. |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | registro | Le registrazioni dei controlli (misure, verifiche, pulizie…). |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | registro | Le non conformità e la loro gestione fino alla chiusura. |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | registro | Il registro delle etichette stampate. |
| [`duplicate_verification`](https://eleccp.com/en/formato-archivio#tipo-duplicate-verification) | registro | Le verifiche «sono la stessa merce?» fra due lotti ricevuti. |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | registro | I recuperi dell'invenduto esposto come ingrediente. |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | registro | I richiami e i fermi della merce, con gli esiti per elemento. |
| [`record_version`](https://eleccp.com/en/formato-archivio#tipo-record-version) | storico | Lo storico delle correzioni: ogni riga è un record com'era PRIMA di una correzione. |
| [`collision_resolution`](https://eleccp.com/en/formato-archivio#tipo-collision-resolution) | registro del server | Le decisioni prese su un lotto che arrivava doppio da due telefoni. |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | registro del server | Le ragioni per cui certi documenti vanno conservati (richiami, validazioni, vincoli di legge). |
| [`recall_item_outcome`](https://eleccp.com/en/formato-archivio#tipo-recall-item-outcome) | registro del server | Gli esiti di un richiamo per ogni elemento fermato (sono anche dentro `recall`). |
| [`site_access_code_rotation`](https://eleccp.com/en/formato-archivio#tipo-site-access-code-rotation) | registro del server | Quando è stato cambiato il codice di sede che sblocca le etichette. |
| [`site_reactivation`](https://eleccp.com/en/formato-archivio#tipo-site-reactivation) | registro del server | Le riattivazioni di sedi disattivate. |
| [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) | registro del server | I documenti di validazione in uso (es. la validazione di un processo) e la loro cessazione. |
| [`file`](https://eleccp.com/en/formato-archivio#tipo-file) | elenco dei file | L'elenco di ogni file citato dai dati, con dove compare e se è protetto. |

Per ogni campo: il **tipo** (*o null* se può mancare), il **significato**, i **valori ammessi** o l'**unità** dove esistono, e il tipo di dato a cui **rimanda** quando porta l'identificativo di un altro record.

### `site`

Le sedi dell'organizzazione (i locali in cui si lavora). File: `dati/site.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `name` | testo | Nome della sede |  |  |
| `address` | testo | Indirizzo |  |  |
| `timezone` | testo | Fuso orario della sede (IANA, es. «Europe/Rome»): le date locali si contano su questo |  |  |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |
| `is_default` | booleano | Vero per la sede proposta per prima |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `created_by_user_id` | intero o null | Chi l'ha creato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_by_display_name` | testo | Nome di chi l'ha creato, com'era in quel momento |  |  |
| `created_device_id` | testo | Dispositivo da cui è stato creato |  |  |
| `updated_by_user_id` | intero o null | Chi l'ha modificato per ultimo: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `updated_by_display_name` | testo | Nome di chi l'ha modificato per ultimo, com'era in quel momento |  |  |
| `updated_device_id` | testo | Dispositivo da cui è stato modificato per ultimo |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `qr_public_base_url` | testo | L'indirizzo di base dei codici QR stampati |  |  |

### `site_assignment`

Quali membri lavorano in quale sede. Nessuna riga per un membro = tutte le sedi. File: `dati/site_assignment.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `user_id` | intero | Chi è il membro: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `assigned_by` | intero | Chi ha assegnato la sede: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `deleted_at` | data e ora o null | Quando l'assegnazione è stata tolta (null = in vigore) |  |  |
| `revoked_by_user_id` | intero o null | Chi l'ha revocato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `revoked_by_display_name` | testo | Nome di chi l'ha revocato, com'era in quel momento |  |  |
| `revoked_device_id` | testo | Dispositivo da cui è stato revocato |  |  |
| `revoked_at` | data e ora o null | Quando è stato revocato |  |  |

### `supplier`

I fornitori. File: `dati/supplier.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `name` | testo | Nome o ragione sociale |  |  |
| `address` | testo | Indirizzo |  |  |
| `vat_number` | testo | Partita IVA |  |  |
| `tax_code` | testo | Codice fiscale |  |  |
| `contacts` | oggetto JSON | Recapiti (telefono, email, referente…) |  |  |
| `usual_supplies` | testo | Che cosa fornisce di solito |  |  |
| `compliance_docs` | testo | Documenti di conformità del fornitore (note) |  |  |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |
| `identification_incomplete` | booleano | Vero se manca l'indirizzo del fornitore |  |  |
| `identification_missing` | booleano | Vero se mancano indirizzo, partita IVA e codice fiscale insieme |  |  |

### `storage_location`

I luoghi di conservazione (frigoriferi, celle, dispense…). File: `dati/storage_location.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `name` | testo | Nome del luogo di conservazione |  |  |
| `kind` | testo | Tipo (frigorifero, congelatore, dispensa…) |  |  |
| `icon` | testo | Icona scelta nell'app |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |

### `equipment`

Le attrezzature (abbattitori, forni, sonde…). File: `dati/equipment.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `name` | testo | Nome dell'attrezzatura |  |  |
| `kind` | testo | Tipo di attrezzatura |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `storage_location_id` | uuid o null | Luogo di conservazione in cui si trova, se è uno |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |

### `catalog_product`

Il catalogo dei prodotti che l'attività prepara (ricette). File: `dati/catalog_product.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `name` | testo | Nome del prodotto |  |  |
| `expected_ingredients` | lista JSON | Ingredienti previsti dalla ricetta |  |  |
| `instructions` | testo | Istruzioni di preparazione |  |  |
| `suggested_shelf_life_days` | intero o null | Durata proposta per il prodotto finito | unità: giorni |  |
| `storage_conditions` | testo | Condizioni di conservazione dichiarate (es. «0-4 °C») |  |  |
| `photo_media_id` | uuid o null | Foto del prodotto |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `expiry_notice_days_override` | intero o null | Con quanti giorni d'anticipo avvisare della scadenza (null = il valore generale) | unità: giorni |  |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |

### `delivery`

I ricevimenti della merce e gli scontrini d'acquisto. File: `dati/delivery.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `supplier_id` | uuid | Fornitore |  | [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `delivered_at` | data e ora | Quando la merce è arrivata |  |  |
| `dispatch_date` | data o null | Data di spedizione come risulta dal documento (null = non trascritta; mai dedotta) |  |  |
| `document_ref` | testo | Estremi del documento di trasporto o della fattura |  |  |
| `judgement` | testo | Giudizio complessivo sul ricevimento | `conforme`, `non_conforme` |  |
| `checks` | oggetto JSON | Esiti dei controlli al ricevimento (controllo → esito) |  |  |
| `voice_transcript` | testo | Trascrizione della nota vocale, confermata dall'operatore |  |  |
| `is_purchase_evidence` | booleano | Vero se è uno scontrino d'acquisto invece di un ricevimento con lotti |  |  |
| `exhausted_at` | data e ora o null | Quando lo scontrino è stato dichiarato esaurito (null = ancora utilizzabile) |  |  |
| `exhausted_reopen_reason` | testo | Motivo con cui uno scontrino esaurito è stato rimesso in uso |  |  |
| `exhausted_by_recall_id` | uuid o null | Il richiamo che l'ha esaurito, se l'esaurimento è dovuto a un richiamo |  | [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) |
| `recalled_products` | lista JSON | Nomi dei prodotti di questo scontrino oggetto di un richiamo |  |  |
| `purchased_products` | lista JSON | Nomi dei prodotti acquistati, se dichiarati |  |  |

### `incoming_lot`

I lotti ricevuti: una riga per prodotto ricevuto in un ricevimento. File: `dati/incoming_lot.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `delivery_id` | uuid | Ricevimento (o scontrino) a cui si riferisce |  | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| `supplier_id` | uuid | Fornitore |  | [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `product_description` | testo | Prodotto ricevuto |  |  |
| `lot_code` | testo o null | Codice di lotto del produttore (vuoto = lotto senza codice, un'anomalia) |  |  |
| `has_anomaly` | booleano | Vero se il lotto presenta un'anomalia documentata |  |  |
| `anomaly_reason` | testo | Descrizione dell'anomalia |  |  |
| `quantity` | numero decimale (scritto come testo) o null | Quantità ricevuta |  |  |
| `unit` | testo | Unità della quantità (kg, g, l, ml, pz, confezioni…) |  |  |
| `package_content` | testo | Contenuto di una confezione, quando l'unità è un imballo (es. «2 kg») |  |  |
| `quantity_missing` | booleano | Vero se manca la quantità o la sua unità |  |  |
| `unit_kind` | testo | Se l'unità misura la merce o conta imballi (vuoto = unità fuori vocabolario o assente) | `misura`, `confezionamento`, vuoto |  |
| `durability_date` | data o null | Data di durabilità (scadenza o termine minimo di conservazione) |  |  |
| `durability_kind` | testo | Che cosa indica la data di durabilità: scadenza o termine minimo di conservazione | `scadenza`, `TMC` |  |
| `storage_location_id` | uuid o null | Dove è conservata la merce |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `arrival_temperature` | numero decimale (scritto come testo) o null | Temperatura misurata all'arrivo | unità: °C |  |
| `checks` | oggetto JSON | Esiti dei controlli sul lotto (controllo → esito) |  |  |
| `status` | testo | Stato del lotto | `accettato`, `aperto`, `bloccato`, `disponibile`, `esaurito`, `non_conforme`, `reso`, `ricevuto`, `scaduto`, `scartato` |  |
| `blocked_reason` | testo | Motivo del fermo, se bloccato |  |  |
| `consolidated_into_id` | uuid o null | Il lotto in cui questo è stato consolidato (era lo stesso lotto registrato due volte) |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `consolidation_reason` | testo | Motivo del consolidamento |  |  |
| `qr_url` | testo | L'indirizzo contenuto nel codice QR stampato sull'etichetta |  |  |

### `open_ingredient`

Le confezioni aperte (con la data limite dopo l'apertura). File: `dati/open_ingredient.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `source_kind` | testo | Da dove viene la confezione: da un lotto ricevuto o da uno scontrino | `incoming_lot`, `purchase_evidence` |  |
| `source_lot_id` | uuid o null | Lotto ricevuto da cui viene (se la fonte è un lotto) |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `source_delivery_id` | uuid o null | Scontrino da cui viene (se la fonte è uno scontrino) |  | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| `declared_product_description` | testo | Il prodotto come dichiarato dall'operatore, quando la fonte è uno scontrino |  |  |
| `container_code` | testo o null | Codice breve della confezione, quando la merce non ha un lotto |  |  |
| `container_code_duplicate` | booleano | Vero se un'altra confezione porta lo stesso codice (accettata e segnalata) |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `opened_at` | data e ora | Quando è stata aperta |  |  |
| `finished_at` | data e ora o null | Quando è stata finita (null = ancora in uso, o finita prima che il dato esistesse) |  |  |
| `status` | testo | Stato della confezione | `aperto`, `finito`, `richiamato`, `bloccato`, `scartato`, `reso` |  |
| `status_reason` | testo | Motivo dell'ultimo fermo o rientro |  |  |
| `original_durability_date` | data o null | Data di durabilità del lotto al momento dell'apertura |  |  |
| `source_revision` | intero o null | Revisione della fonte al momento dell'uso: dice su quale versione del record si è deciso |  |  |
| `after_opening_date` | data o null | Data limite di consumo dopo l'apertura (null = non confermata) |  |  |
| `proposed_from` | data o null | Data da cui l'app ha calcolato la data limite proposta |  |  |
| `storage_location_id` | uuid o null | Dove è conservata la merce |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `storage_conditions` | testo | Condizioni di conservazione dichiarate (es. «0-4 °C») |  |  |
| `qr_url` | testo | L'indirizzo contenuto nel codice QR stampato sull'etichetta |  |  |

### `production_sheet`

Le schede di produzione: che cosa si è preparato, quando e con che cosa. File: `dati/production_sheet.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `display_kind` | testo | Il nome del tipo di record come lo mostra l'app |  |  |
| `status` | testo | Stato della scheda: bozza o confermata (una scheda confermata non cambia più) | `bozza`, `confermata` |  |
| `catalog_product_id` | uuid o null | Prodotto del catalogo preparato, se scelto dal catalogo |  | [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) |
| `product_name` | testo | Nome del prodotto preparato |  |  |
| `produced_at` | data e ora | Quando è stato preparato |  |  |
| `finished_durability_date` | data o null | Data di durabilità del prodotto finito |  |  |
| `durability_kind` | testo | Che cosa indica la data di durabilità: scadenza o termine minimo di conservazione |  |  |
| `storage_conditions` | testo | Condizioni di conservazione dichiarate (es. «0-4 °C») |  |  |
| `process_notes` | testo | Note di lavorazione |  |  |
| `outcome` | testo o null | Esito complessivo della preparazione, se dichiarato | `venduto`, `somministrato`, `scartato`, `scaduto` |  |
| `outcome_at` | data e ora o null | Quando è avvenuto l'esito |  |  |
| `outcome_recipient` | testo | A chi è andato il prodotto (per venduto o somministrato) |  |  |
| `outcome_note` | testo | Nota sull'esito (obbligatoria per scartato e scaduto) |  |  |
| `outcome_by_user_id` | intero o null | Chi ha dichiarato l'esito: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `outcome_by_display_name` | testo | Nome di chi ha dichiarato l'esito, com'era in quel momento |  |  |
| `outcome_device_id` | testo | Dispositivo da cui è stato dichiarato l'esito |  |  |
| `outcome_recorded_at` | data e ora o null | Quando l'esito è stato registrato |  |  |
| `confirmed_by_user_id` | intero o null | Chi ha confermato la scheda: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `confirmed_by_display_name` | testo | Nome di chi ha confermato la scheda, com'era in quel momento |  |  |
| `confirmed_device_id` | testo | Dispositivo da cui è stata confermata la scheda |  |  |
| `confirmed_at` | data e ora o null | Quando la scheda è stata confermata |  |  |
| `duplicated_from_id` | uuid o null | Scheda da cui questa è stata duplicata |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `destination` | testo | Destinazione della preparazione (uso interno o vendita) | `interno`, `vendita` |  |
| `production_lot_id` | uuid o null | Lotto di produzione (la partita) a cui appartiene |  | [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) |
| `production_lot_code` | testo o null | Codice del lotto di produzione (es. «LI-T01-140926-001») |  |  |

### `production_ingredient`

Gli ingredienti di ogni scheda di produzione, con la loro fonte. File: `dati/production_ingredient.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `production_sheet_id` | uuid | Scheda di produzione a cui si riferisce |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `open_ingredient_id` | uuid o null | Confezione aperta usata come fonte |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `incoming_lot_id` | uuid o null | Lotto ricevuto usato come fonte |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `internal_lot_id` | uuid o null | Unità conservata usata come fonte (un semilavorato) |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `source_delivery_id` | uuid o null | Scontrino usato come fonte |  | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| `declared_product_description` | testo | Il prodotto come dichiarato dall'operatore, quando la fonte è uno scontrino |  |  |
| `marked_finished` | booleano | Vero se alla conferma la fonte è stata dichiarata finita |  |  |
| `added_via` | testo | Come è stata scelta la fonte (QR, riconoscimento testo, ricerca, scontrino) | `qr`, `ocr`, `search`, `purchase_evidence` |  |
| `exception_documented` | testo o null | Spiegazione quando l'ingrediente non ha una fonte tracciata |  |  |
| `source_revision` | intero o null | Revisione della fonte al momento dell'uso: dice su quale versione del record si è deciso |  |  |
| `usability_anomaly` | JSON o null | Perché la fonte non era più utilizzabile quando la conferma è arrivata: `{code, reason}`, null nel caso normale |  |  |
| `source_issue` | oggetto JSON o null | Com'è la fonte al momento dell'estrazione: `{code}` se c'è un problema, null altrimenti |  |  |

### `internal_lot`

Le unità conservate: le porzioni di una preparazione messe da parte con la loro etichetta. File: `dati/internal_lot.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `display_kind` | testo | Il nome del tipo di record come lo mostra l'app |  |  |
| `production_sheet_id` | uuid | Scheda di produzione da cui viene |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `production_lot_id` | uuid o null | Lotto di produzione (la partita) a cui appartiene |  | [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) |
| `lot_number` | testo | Numero di lotto stampato sull'etichetta |  |  |
| `unit_seq` | intero o null | Progressivo dell'unità dentro il suo lotto di produzione |  |  |
| `unit_code` | testo o null | Codice dell'unità stampato sull'etichetta (lotto + progressivo) |  |  |
| `unit_seq_duplicate` | booleano | Vero se un'altra unità dello stesso lotto porta lo stesso progressivo |  |  |
| `outcome_conflict` | booleano | Vero se l'unità è nata da una scheda che aveva già un esito complessivo |  |  |
| `preserved_at` | data e ora o null | Quando la porzione è stata messa da parte |  |  |
| `durability_date` | data o null | Data di durabilità (scadenza o termine minimo di conservazione) |  |  |
| `durability_kind` | testo | Che cosa indica la data di durabilità: scadenza o termine minimo di conservazione |  |  |
| `storage_conditions` | testo | Condizioni di conservazione dichiarate (es. «0-4 °C») |  |  |
| `storage_location_id` | uuid o null | Dove è conservata la merce |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `status` | testo | Stato dell'unità | `bloccato`, `disponibile`, `esaurito`, `recuperata`, `richiamato`, `scaduto`, `scartato`, `vendita_terminata` |  |
| `purpose` | testo | A che cosa serve: da usare in cucina o da servire/vendere | `cucina`, `servizio` |  |
| `source_unit_id` | uuid o null | L'unità esposta da cui questa è stata recuperata, se nasce da un recupero |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `is_usable` | booleano | Vero se al momento dell'estrazione si poteva usare come ingrediente |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `qr_url` | testo | L'indirizzo contenuto nel codice QR stampato sull'etichetta |  |  |
| `label` | oggetto JSON | I dati stampati sull'etichetta |  |  |

### `production_lot`

I lotti di produzione: la partita a cui appartengono le preparazioni. File: `dati/production_lot.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `display_kind` | testo | Il nome del tipo di record come lo mostra l'app |  |  |
| `kind` | testo | LI = lotto per uso interno, LE = lotto per la vendita | `LI`, `LE` |  |
| `code` | testo | Codice del lotto (es. «LI-T01-140926-001») |  |  |
| `device_code` | testo | Sigla del telefono che l'ha generato |  |  |
| `production_day` | data | Giorno di produzione, nel calendario della sede |  |  |
| `day_seq` | intero | Progressivo del lotto nel giorno |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `product_key` | testo | Il prodotto, come chiave (prodotto del catalogo o nome normalizzato) |  |  |
| `signature` | testo | Impronta dell'insieme esatto delle fonti usate |  |  |
| `code_duplicate` | booleano | Vero se un altro lotto porta lo stesso codice (accettato e segnalato) |  |  |
| `closed_at` | data e ora o null | Quando il lotto è stato chiuso |  |  |

### `lot_status_event`

La storia degli stati di lotti, unità conservate e confezioni aperte. File: `dati/lot_status_event.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `lot_id` | uuid o null | Lotto ricevuto di cui cambia lo stato |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `internal_lot_id` | uuid o null | Unità conservata di cui cambia lo stato |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `open_ingredient_id` | uuid o null | Confezione aperta di cui cambia lo stato |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `from_status` | testo o null | Stato di partenza (null = nascita) | `accettato`, `aperto`, `bloccato`, `disponibile`, `esaurito`, `finito`, `non_conforme`, `recuperata`, `reso`, `ricevuto`, `richiamato`, `scaduto`, `scartato`, `vendita_terminata` |  |
| `to_status` | testo | Stato di arrivo | `accettato`, `aperto`, `bloccato`, `disponibile`, `esaurito`, `finito`, `non_conforme`, `recuperata`, `reso`, `ricevuto`, `richiamato`, `scaduto`, `scartato`, `vendita_terminata` |  |
| `reason` | testo | Motivo dichiarato |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |

### `event_type`

I tipi di registrazione del piano di autocontrollo (temperature, pulizie…). File: `dati/event_type.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `code` | testo | Codice del tipo |  |  |
| `label` | testo | Nome del tipo |  |  |
| `form` | testo | Forma della registrazione | `misura`, `checklist`, `documento` |  |
| `payload_schema` | oggetto JSON | I campi che la registrazione chiede (schema) |  |  |
| `version` | intero | Versione del tipo |  |  |
| `previous_version_id` | uuid o null | Versione precedente dello stesso tipo |  | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |
| `is_global` | booleano | Vero per un tipo della libreria comune, falso per uno dell'organizzazione |  |  |
| `copied_from` | oggetto JSON o null | Il tipo della libreria da cui è stato copiato: `{id, code, version}`, null se nato qui |  | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `created_by_user_id` | intero o null | Chi l'ha creato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_by_display_name` | testo | Nome di chi l'ha creato, com'era in quel momento |  |  |
| `created_device_id` | testo | Dispositivo da cui è stato creato |  |  |
| `deactivated_by_user_id` | intero o null | Chi l'ha disattivato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `deactivated_by_display_name` | testo | Nome di chi l'ha disattivato, com'era in quel momento |  |  |
| `deactivated_device_id` | testo | Dispositivo da cui è stato disattivato |  |  |
| `deactivated_at` | data e ora o null | Quando è stato disattivato |  |  |

### `plan_version`

Le versioni del piano di autocontrollo di ogni sede. File: `dati/plan_version.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `version_number` | intero | Numero della versione (assegnato alla pubblicazione) |  |  |
| `status` | testo | Stato della versione | `bozza`, `pubblicata`, `sostituita`, `archiviata` |  |
| `effective_from` | data o null | Data da cui la versione è dichiarata in vigore |  |  |
| `published_by` | intero o null | Chi ha pubblicato la versione: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `published_at` | data e ora o null | Quando è stata pubblicata |  |  |
| `notes` | testo | Note |  |  |
| `origin` | testo | Chi l'ha redatta (es. «osa») |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `created_by_user_id` | intero o null | Chi l'ha creato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_by_display_name` | testo | Nome di chi l'ha creato, com'era in quel momento |  |  |
| `created_device_id` | testo | Dispositivo da cui è stato creato |  |  |
| `updated_by_user_id` | intero o null | Chi l'ha modificato per ultimo: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `updated_by_display_name` | testo | Nome di chi l'ha modificato per ultimo, com'era in quel momento |  |  |
| `updated_device_id` | testo | Dispositivo da cui è stato modificato per ultimo |  |  |

### `control_point`

I punti di controllo di ogni versione del piano. File: `dati/control_point.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `lineage_id` | uuid | Identità del controllo attraverso le versioni del piano (uguale da una versione all'altra) |  |  |
| `plan_version_id` | uuid | Versione del piano di autocontrollo a cui si riferisce |  | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| `event_type_id` | uuid | Tipo di registrazione |  | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| `event_type_version` | intero | Versione del tipo di registrazione in vigore in quel momento |  |  |
| `name` | testo | Nome del punto di controllo |  |  |
| `storage_location_id` | uuid o null | Luogo di conservazione controllato |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `equipment_id` | uuid o null | Attrezzatura controllata |  | [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) |
| `origin` | testo | Natura del punto: punto critico di controllo (CCP) o prerequisito/buona prassi | `CCP`, `PRP-GHP`, `verifica` |  |
| `is_ccp` | booleano | Vero se una deviazione su questo punto è grave |  |  |
| `corrective_action` | testo | Azione correttiva |  |  |
| `missing_monitoring_action` | testo | Che cosa fare quando il controllo non è stato registrato (dal piano di autocontrollo) |  |  |
| `recovery_allowed` | booleano | Vero se l'invenduto esposto qui può tornare a essere un ingrediente |  |  |
| `recovery_max_exposure_hours` | intero o null | Oltre quante ore di esposizione il recupero non è più ammesso | unità: ore |  |
| `block_lot_on_deviation` | booleano | Vero se una deviazione deve fermare la merce |  |  |
| `report_retention_months` | intero o null | Quanto conservare i referti di questo controllo (null = da definire) | unità: mesi |  |
| `report_retention_start` | testo | Da quando decorre la conservazione dei referti | `registrazione`, `fine_anno` |  |
| `is_active` | booleano | Falso se disattivato: resta a registro ma non si usa più |  |  |
| `limit` | oggetto JSON | Il limite da rispettare (forma e valori) |  |  |
| `frequency` | oggetto JSON | Ogni quanto va registrato il controllo |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |

### `plan_suspension`

I periodi in cui il piano, o un suo punto, è stato sospeso. File: `dati/plan_suspension.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `plan_version_id` | uuid | Versione del piano di autocontrollo a cui si riferisce |  | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| `control_point_id` | uuid o null | Punto sospeso (null = tutto il piano) |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `from_date` | data | Primo giorno di sospensione |  |  |
| `to_date` | data | Ultimo giorno di sospensione |  |  |
| `reason` | testo | Motivo dichiarato |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `created_by_user_id` | intero o null | Chi l'ha creato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_by_display_name` | testo | Nome di chi l'ha creato, com'era in quel momento |  |  |
| `created_device_id` | testo | Dispositivo da cui è stato creato |  |  |
| `status` | testo | Stato della sospensione | `attiva`, `annullata` |  |
| `cancelled_at` | data e ora o null | Quando è stato annullato (null = non annullato) |  |  |
| `cancelled_by_user_id` | intero o null | Chi l'ha annullato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `cancelled_by_display_name` | testo | Nome di chi l'ha annullato, com'era in quel momento |  |  |
| `cancelled_device_id` | testo | Dispositivo da cui è stato annullato |  |  |
| `cancellation_reason` | testo | Motivo dell'annullamento |  |  |

### `expected_registration`

Le registrazioni che il piano si aspettava, finestra per finestra, con il loro esito. File: `dati/expected_registration.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `control_point_id` | uuid | Punto di controllo del piano a cui si riferisce |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `window_start` | data e ora | Inizio della finestra in cui la registrazione era attesa |  |  |
| `window_end` | data e ora | Fine della finestra |  |  |
| `status` | testo | Esito: in attesa, soddisfatta o mancante | `attesa`, `soddisfatta`, `mancante` |  |
| `satisfied_by_event_id` | uuid o null | La registrazione che l'ha soddisfatta |  | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| `nc_id` | uuid o null | La non conformità aperta perché è mancata |  | [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |

### `event`

Le registrazioni dei controlli (misure, verifiche, pulizie…). File: `dati/event.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `event_type_id` | uuid | Tipo di registrazione |  | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| `event_type_version` | intero | Versione del tipo di registrazione in vigore in quel momento |  |  |
| `control_point_id` | uuid o null | Punto di controllo del piano a cui si riferisce |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `esito` | testo | Esito della registrazione (calcolato dal limite per le misure) | `conforme`, `non_conforme`, `na` |  |
| `payload` | oggetto JSON | I valori registrati (misure, risposte), nella forma del tipo di registrazione |  |  |
| `incoming_lot_id` | uuid o null | Lotto ricevuto a cui si riferisce |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `internal_lot_id` | uuid o null | Unità conservata a cui si riferisce |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `production_sheet_id` | uuid o null | Scheda di produzione a cui si riferisce |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `open_ingredient_id` | uuid o null | Confezione aperta a cui si riferisce |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `storage_location_id` | uuid o null | Luogo di conservazione controllato |  | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| `equipment_id` | uuid o null | Attrezzatura a cui si riferisce |  | [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) |
| `plan_version_id` | uuid o null | Versione del piano di autocontrollo a cui si riferisce |  | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| `point_snapshot` | oggetto JSON | Il punto di controllo com'era al momento della registrazione (limite compreso) |  |  |
| `expected_registration_id` | uuid o null | Registrazione attesa dal piano a cui si riferisce |  | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| `site_id` | uuid o null | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `off_plan` | booleano | Vero se è una registrazione fuori dal piano |  |  |

### `non_conformity`

Le non conformità e la loro gestione fino alla chiusura. File: `dati/non_conformity.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `origin` | testo | Area in cui è nata | `CCP`, `PRP-GHP`, `verifica`, `ricevimento`, `altra` |  |
| `severity` | testo | Gravità | `alta`, `media`, `bassa` |  |
| `description` | testo | Descrizione |  |  |
| `source` | testo | Come è nata: a mano, da una misura fuori limite, da una registrazione mancante… | `auto_fuori_limite`, `auto_registrazione_mancante`, `manuale`, `conferma_offline_fonte_non_utilizzabile`, `auto_recupero_invenduto`, `auto_durata_preparazione` |  |
| `control_point_id` | uuid o null | Punto di controllo del piano a cui si riferisce |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `event_id` | uuid o null | La registrazione che l'ha fatta nascere |  | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| `expected_registration_id` | uuid o null | La registrazione mancata che l'ha fatta nascere |  | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| `incoming_lot_id` | uuid o null | Lotto ricevuto a cui si riferisce |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `internal_lot_id` | uuid o null | Unità conservata a cui si riferisce |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `open_ingredient_id` | uuid o null | Confezione aperta a cui si riferisce |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `delivery_id` | uuid o null | Ricevimento (o scontrino) a cui si riferisce |  | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| `production_sheet_id` | uuid o null | Scheda di produzione a cui si riferisce |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `immediate_action` | testo | Azione immediata |  |  |
| `corrective_action` | testo | Azione correttiva |  |  |
| `missing_monitoring_action` | testo | Che cosa il piano prescrive quando il controllo manca (dal punto di controllo) |  |  |
| `assignee_user_id` | intero o null | Chi deve occuparsene: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `assignee_display_name` | testo | Nome di chi deve occuparsene, com'era in quel momento |  |  |
| `due_date` | data o null | Entro quando va gestita |  |  |
| `taken_over_by` | intero o null | Chi l'ha presa in carico: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `taken_over_by_display_name` | testo | Nome di chi l'ha presa in carico, com'era in quel momento |  |  |
| `taken_over_at` | data e ora o null | Quando è stata presa in carico |  |  |
| `missing_case` | testo | Che cosa è successo, per una registrazione mancante | `non_eseguito`, `eseguito_non_registrato`, `non_accertabile` |  |
| `product_outcome` | testo | Che cosa è stato deciso sul prodotto, per una registrazione mancante | `nessun_prodotto`, `rilasciato`, `rilavorato`, `reso`, `scartato`, `altra_destinazione` |  |
| `late_control_event_id` | uuid o null | Il controllo fatto in ritardo collegato come evidenza |  | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| `late_control_revision` | intero o null | Revisione di quel controllo su cui si è deciso |  |  |
| `affected_items` | lista JSON | La merce coinvolta: `[{kind, id, blocked_at}]` (kind è il tipo del record, id il suo identificativo) |  |  |
| `affected_declared_at` | data e ora o null | Quando è stata dichiarata la merce coinvolta (null = non ancora dichiarata) |  |  |
| `verification_note` | testo | Verifica dell'efficacia prima della chiusura |  |  |
| `verified_by` | intero o null | Chi ha verificato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `verified_by_display_name` | testo | Nome di chi ha verificato, com'era in quel momento |  |  |
| `verified_at` | data e ora o null | Quando è stata verificata |  |  |
| `status` | testo | Stato della non conformità | `aperta`, `in_lavorazione`, `in_verifica`, `chiusa`, `annullata` |  |
| `cancellation_reason` | testo | Motivo dell'annullamento |  |  |
| `site_id` | uuid o null | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |

### `label_print_log`

Il registro delle etichette stampate. File: `dati/label_print_log.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `record_kind` | testo | Che cosa è stato etichettato | `open_ingredient`, `internal_lot`, `incoming_lot` |  |
| `open_ingredient_id` | uuid o null | Confezione aperta a cui si riferisce |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `internal_lot_id` | uuid o null | Unità conservata a cui si riferisce |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `incoming_lot_id` | uuid o null | Lotto ricevuto a cui si riferisce |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `printer_ref` | testo | Stampante usata |  |  |
| `copies` | intero | Numero di copie |  |  |
| `outcome` | testo | Esito della stampa | `ok`, `fallita` |  |
| `is_reprint` | booleano | Vero se è una ristampa |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |

### `duplicate_verification`

Le verifiche «sono la stessa merce?» fra due lotti ricevuti. File: `dati/duplicate_verification.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `external_id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `status` | testo | Stato della verifica | `aperta`, `confermato_duplicato`, `non_duplicato` |  |
| `origin` | testo | Che cosa l'ha fatta nascere (es. «correzione») |  |  |
| `left_id` | uuid | Il lotto appena corretto |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `right_id` | uuid | Il lotto che c'era già con la stessa chiave |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `triggered_by_operation_id` | uuid o null | L'operazione dell'app che l'ha fatta nascere |  |  |
| `opened_by_user_id` | intero | Chi l'ha aperta: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `opened_by_display_name` | testo | Nome di chi l'ha aperta, com'era in quel momento |  |  |
| `opened_at` | data e ora | Quando è stata aperta |  |  |
| `resolved_by_user_id` | intero o null | Chi ha deciso: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `resolved_by_display_name` | testo | Nome di chi ha deciso, com'era in quel momento |  |  |
| `resolved_at` | data e ora o null | Quando è stata presa la decisione |  |  |
| `outcome_reason` | testo | Motivo della decisione |  |  |

### `unit_recovery`

I recuperi dell'invenduto esposto come ingrediente. File: `dati/unit_recovery.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `display_kind` | testo | Il nome del tipo di record come lo mostra l'app |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `exposed_unit_id` | uuid | L'unità esposta (invenduta) da cui si è recuperato |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `recovered_unit_id` | uuid | L'unità nuova, da usare in cucina |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `exposure_start` | data e ora | Inizio dell'esposizione |  |  |
| `exposure_end` | data e ora | Fine dell'esposizione |  |  |
| `control_point_id` | uuid o null | Il punto del piano che ammette il recupero, se c'è |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `control_point_lineage_id` | uuid o null | Identità del controllo attraverso le versioni del piano |  | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| `plan_version_id` | uuid o null | Versione del piano di autocontrollo a cui si riferisce |  | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| `event_ids` | lista JSON | Le registrazioni considerate nella valutazione |  | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| `missing_registration_ids` | lista JSON | Le registrazioni mancate nel periodo di esposizione |  | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| `measurement_event_id` | uuid o null | La misura presa al momento del recupero |  | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| `plan_compliant` | booleano | Vero se il recupero rispetta una regola del piano |  |  |
| `integrity_confirmed` | booleano | Vero se l'operatore ha confermato l'integrità del prodotto |  |  |
| `justification` | testo | Giustificazione dell'operatore |  |  |
| `deviations` | lista JSON | Le deviazioni trovate: `[{code, detail}]` |  |  |
| `nc_id` | uuid o null | La non conformità aperta per le deviazioni |  | [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) |

### `recall`

I richiami e i fermi della merce, con gli esiti per elemento. File: `dati/recall.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `attachments` | lista JSON | Allegati del record: `[{media_id, kind}]`, più chi e quando se aggiunti in un secondo momento. Il file è `file/<media_id>-<nome>` in uno dei pacchetti successivi |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `note` | testo o null | Nota libera |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `pending_attachments` | intero | Allegati annunciati ma non ancora arrivati al momento dell'estrazione |  |  |
| `evidence_complete` | booleano | Vero se tutti gli allegati annunciati sono arrivati |  |  |
| `revision` | intero | Numero di revisione: sale a ogni correzione. Le versioni superate sono nel tipo `record_version` |  |  |
| `corrected_at` | data e ora o null | Quando il record è stato corretto l'ultima volta (null = mai corretto) |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `mode` | testo | Simulazione o richiamo operativo | `simulazione`, `operativo` |  |
| `kind` | testo | Fermo interno, ritiro o richiamo al consumatore | `fermo_interno`, `ritiro`, `richiamo_consumatore` |  |
| `origin_kind` | testo | Di che tipo è la merce da cui parte il richiamo | `incoming_lot`, `internal_lot`, `production_sheet`, `purchase_evidence`, `open_ingredient` |  |
| `origin_incoming_lot_id` | uuid o null | Lotto ricevuto da cui parte |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `origin_internal_lot_id` | uuid o null | Unità conservata da cui parte |  | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| `origin_production_sheet_id` | uuid o null | Scheda di produzione da cui parte |  | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| `origin_delivery_id` | uuid o null | Scontrino da cui parte |  | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| `origin_open_ingredient_id` | uuid o null | Confezione aperta da cui parte |  | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| `origin_products` | lista JSON | Per uno scontrino: i prodotti dichiarati coinvolti |  |  |
| `impact_snapshot` | oggetto JSON | La merce fermata dal richiamo: `{stopped: {tipo: [id]}}` |  |  |
| `decision` | testo | Decisione presa |  |  |
| `actions` | testo | Azioni intraprese |  |  |
| `status` | testo | Stato del richiamo | `aperto`, `chiuso`, `annullato` |  |
| `cancel_reason` | testo | Motivo dell'annullamento |  |  |
| `cancelled_at` | data e ora o null | Quando è stato annullato (null = non annullato) |  |  |
| `cancel_report` | oggetto JSON | Che cosa l'annullamento ha rimesso in gioco e che cosa no |  |  |
| `closed_by_display_name` | testo o null | Nome di chi l'ha chiuso, com'era in quel momento |  |  |
| `closed_at` | data e ora o null | Quando è stato chiuso |  |  |
| `closed_by_user_id` | intero o null | Chi l'ha chiuso: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `outcomes` | lista JSON | Gli esiti per elemento fermato (la stessa forma del tipo `recall_item_outcome`) |  |  |

### `record_version`

Lo storico delle correzioni: ogni riga è un record com'era PRIMA di una correzione. File: `dati/record_version.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `entity_kind` | testo | Il tipo del record corretto (uno dei tipi di questo archivio) |  |  |
| `record_id` | uuid | L'identificativo del record corretto, nel file del suo tipo |  |  |
| `revision` | intero | Numero di revisione di questa versione (superata) |  |  |
| `snapshot` | JSON | Il record com'era prima della correzione, nella forma del suo tipo |  |  |
| `author_user_id` | intero | Chi ha registrato il fatto: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `author_display_name` | testo | Nome di chi ha registrato il fatto, com'era in quel momento |  |  |
| `occurred_at` | data e ora | Quando il fatto è avvenuto, come dichiarato da chi l'ha registrato |  |  |
| `server_accepted_at` | data e ora | Quando il server ha ricevuto la registrazione |  |  |
| `reason` | testo | Motivo della correzione |  |  |
| `source` | testo | Da dove è arrivata la correzione | `app`, `back-office`, `sistema` |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |

### `collision_resolution`

Le decisioni prese su un lotto che arrivava doppio da due telefoni. File: `dati/collision_resolution.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `organization_id` | intero | Numero dell'organizzazione (è lo stesso di `organizzazione.json`) |  |  |
| `operation_id` | uuid | L'operazione dell'app che portava il lotto doppio |  |  |
| `existing_lot_id` | uuid o null | Il lotto che c'era già |  | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| `choice` | testo | La decisione: collegare al lotto esistente o annullare | `link`, `cancel` |  |
| `reason` | testo | Motivo dichiarato |  |  |
| `resolved_by_user_id` | intero | Chi ha deciso: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `resolved_by_display_name` | testo | Nome di chi ha deciso, com'era in quel momento |  |  |
| `resolved_device_id` | testo | Dispositivo da cui è stata presa la decisione |  |  |
| `resolved_at` | data e ora | Quando è stata presa la decisione |  |  |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |

### `document_hold`

Le ragioni per cui certi documenti vanno conservati (richiami, validazioni, vincoli di legge). File: `dati/document_hold.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `external_id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `organization_id` | intero | Numero dell'organizzazione (è lo stesso di `organizzazione.json`) |  |  |
| `source_kind` | testo | Da dove nasce la ragione di conservazione | `recall`, `validation`, `manual`, `plan_control`, `non_conformity` |  |
| `source_ref` | uuid | L'identificativo di ciò da cui nasce (il richiamo, la validazione…) |  |  |
| `reason` | testo | Motivo dichiarato |  |  |
| `indefinite` | booleano | Vero se va conservato senza scadenza |  |  |
| `until` | data e ora o null | Fino a quando va conservato |  |  |
| `state` | testo | Stato della ragione di conservazione | `aperto`, `chiuso`, `annullato`, `attiva`, `cessata`, `revocata`, `da_definire` |  |
| `media_ids` | lista JSON | I file protetti |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `missing_media_ids` | lista JSON | I file che risultavano mancanti |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `created_by_user_id` | intero o null | Chi l'ha creato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `created_by_display_name` | testo | Nome di chi l'ha creato, com'era in quel momento |  |  |
| `created_device_id` | testo | Dispositivo da cui è stato creato |  |  |
| `revoked_by_user_id` | intero o null | Chi l'ha revocato: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `revoked_by_display_name` | testo | Nome di chi l'ha revocato, com'era in quel momento |  |  |
| `revoked_device_id` | testo | Dispositivo da cui è stato revocato |  |  |
| `revoked_at` | data e ora o null | Quando è stato revocato |  |  |
| `revoke_reason` | testo | Motivo della revoca |  |  |
| `legal_status` | testo | Valutazione di un vincolo di legge | `none`, `pending_review`, `legal`, `released` |  |
| `legal_basis` | testo | Fondamento giuridico del vincolo |  |  |
| `legal_decided_by_user_id` | intero o null | Chi ha deciso sul vincolo di legge: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `legal_decided_by_display_name` | testo | Nome di chi ha deciso sul vincolo di legge, com'era in quel momento |  |  |
| `legal_decided_at` | data e ora o null | Quando si è deciso sul vincolo di legge |  |  |
| `legal_review_at` | data e ora o null | Quando il vincolo va riesaminato |  |  |
| `legal_until` | data e ora o null | Fino a quando vale il vincolo |  |  |
| `legal_pending_since` | data e ora o null | Da quando il vincolo attende una valutazione |  |  |
| `legal_release_reason` | testo | Motivo del rilascio del vincolo |  |  |
| `legal_extract_media_ids` | lista JSON | Estratti prodotti per il vincolo di legge |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `revision` | intero | Numero di revisione della ragione di conservazione |  |  |
| `sync_pending` | booleano | Vero se l'allineamento con l'archivio dei file era ancora in corso |  |  |
| `sync_attempts` | intero | Tentativi di allineamento con l'archivio dei file |  |  |
| `last_sync_error` | testo | Ultimo errore di allineamento |  |  |
| `synced_at` | data e ora o null | Quando è stata allineata l'ultima volta |  |  |
| `next_sync_at` | data e ora o null | Quando era previsto il prossimo allineamento |  |  |

### `recall_item_outcome`

Gli esiti di un richiamo per ogni elemento fermato (sono anche dentro `recall`). File: `dati/recall_item_outcome.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `recall_id` | uuid | Il richiamo |  | [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) |
| `entity_kind` | testo | Il tipo dell'elemento deciso | `incoming_lot`, `internal_lot`, `open_ingredient`, `delivery` |  |
| `external_id` | uuid | L'identificativo dell'elemento deciso, nel file del suo tipo |  |  |
| `outcome` | testo | L'esito deciso per l'elemento | `scartato`, `reso`, `rilasciato`, `non_recuperabile`, `altra_causa`, `non_applicabile` |  |
| `reason` | testo | Motivo dichiarato |  |  |
| `status_event_id` | uuid o null | Il cambio di stato che l'esito ha prodotto |  | [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) |
| `decided_by_user_id` | intero | Chi ha deciso l'esito: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `decided_by_display_name` | testo | Nome di chi ha deciso l'esito, com'era in quel momento |  |  |
| `decided_device_id` | testo | Dispositivo da cui è stato deciso l'esito |  |  |
| `decided_at` | data e ora | Quando è stato deciso |  |  |
| `previous_outcome` | testo | L'esito precedente, se l'esito è stato cambiato |  |  |
| `previous_reason` | testo | Il motivo precedente |  |  |
| `previous_decided_by_user_id` | intero o null | Chi aveva deciso l'esito precedente: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `previous_decided_by_display_name` | testo | Nome di chi aveva deciso l'esito precedente, com'era in quel momento |  |  |
| `previous_decided_at` | data e ora o null | Quando era stato deciso l'esito precedente |  |  |
| `rectification_reason` | testo | Motivo dell'ultima correzione |  |  |
| `rectified_at` | data e ora o null | Quando l'esito è stato cambiato |  |  |

### `site_access_code_rotation`

Quando è stato cambiato il codice di sede che sblocca le etichette. File: `dati/site_access_code_rotation.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `rotated_by` | intero | Chi ha cambiato il codice: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `rotated_at` | data e ora | Quando è stato cambiato (il codice, vecchio o nuovo, non è mai registrato) |  |  |

### `site_reactivation`

Le riattivazioni di sedi disattivate. File: `dati/site_reactivation.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `site_id` | uuid | Sede a cui il record appartiene |  | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| `actor_user_id` | intero | Chi ha riattivato la sede: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `actor_display_name` | testo | Nome di chi ha riattivato la sede, com'era in quel momento |  |  |
| `reason` | testo | Motivo dichiarato |  |  |

### `validation_use`

I documenti di validazione in uso (es. la validazione di un processo) e la loro cessazione. File: `dati/validation_use.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `created_at` | data e ora | Quando la riga è stata creata sul server |  |  |
| `updated_at` | data e ora | Quando la riga è stata modificata l'ultima volta sul server |  |  |
| `external_id` | uuid | Identificativo pubblico del record: è il valore con cui gli altri record lo citano |  |  |
| `organization_id` | intero | Numero dell'organizzazione (è lo stesso di `organizzazione.json`) |  |  |
| `media_id` | uuid | Il documento di validazione |  | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| `record_kind` | testo | Il tipo del record a cui è allegato |  |  |
| `record_id` | uuid | L'identificativo del record a cui è allegato |  |  |
| `description` | testo | Che cosa valida |  |  |
| `status` | testo | Stato: in uso, cessata o sostituita | `in_uso`, `cessata`, `sostituita` |  |
| `replaced_by_id` | uuid o null | La validazione che l'ha sostituita |  | [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) |
| `followup_months` | intero o null | Per quanto conservarla dopo la cessazione | unità: mesi |  |
| `followup_start` | testo | Da quando decorre la conservazione | `cessazione` |  |
| `declared_by_user_id` | intero o null | Chi l'ha dichiarata in uso: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `declared_by_display_name` | testo | Nome di chi l'ha dichiarata in uso, com'era in quel momento |  |  |
| `declared_device_id` | testo | Dispositivo da cui è stata dichiarata |  |  |
| `declared_at` | data e ora | Quando è stata dichiarata in uso |  |  |
| `ceased_at` | data e ora o null | Quando è cessata |  |  |
| `ceased_by_user_id` | intero o null | Chi l'ha dichiarata cessata: identificativo del membro |  | `organizzazione.json` → `members` (`user_id`) |
| `ceased_by_display_name` | testo | Nome di chi l'ha dichiarata cessata, com'era in quel momento |  |  |
| `ceased_device_id` | testo | Dispositivo da cui è stata dichiarata cessata |  |  |
| `cessation_reason` | testo | Motivo della cessazione |  |  |

### `file`

L'elenco di ogni file citato dai dati, con dove compare e se è protetto. File: `dati/file.jsonl`.

| Campo | Tipo | Significato | Valori ammessi / unità | Rimanda a |
| --- | --- | --- | --- | --- |
| `media_id` | uuid | Identificativo del file: l'originale è `file/<media_id>-<nome>` nel pacchetto indicato da `manifest.json` |  |  |
| `attachment_kinds` | lista JSON | Che cosa rappresenta il file (scontrino, foto della merce…) |  |  |
| `records` | lista JSON | I record che lo citano: `[{entity_kind, id}]` (al più 20; il resto è segnalato da `records_truncated`) |  |  |
| `records_truncated` | booleano | Vero se i record che lo citano sono più di quelli elencati |  |  |
| `in_versions` | booleano | Vero se compare anche in una versione superata (`record_version`) |  |  |
| `holds` | lista JSON | Le ragioni di conservazione che lo proteggono (vedi `document_hold`), con `missing` se risultava assente |  | [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) |
| `protected` | booleano | Vero se al momento dell'estrazione una ragione di conservazione lo protegge |  |  |

## Dati non compresi nell'archivio

L'archivio porta tutti i dati dell'organizzazione. Non porta due categorie di dati del servizio, elencate qui con il motivo.

**Dati tecnici del servizio.** Registri e contatori che servono al funzionamento di EleCCP (sincronizzazione, numerazioni, consumi) e non aggiungono nulla ai registri: ciò che contano o trasportano è già per intero nei dati dell'archivio.

| Dato | Motivo |
| --- | --- |
| `allowance_bucket` | crediti AI del periodo: dato di consumo del servizio, non registro HACCP |
| `changelog_entry` | canale tecnico del sync: ogni record c'è per intero nel suo kind |
| `demo_run` | storia dello scenario dimostrativo, non dell'azienda |
| `device_code_counter` | contatore tecnico dei codici offline (i codici stanno sui record) |
| `device_code_sequence` | contatore tecnico delle sigle dei telefoni (le sigle compaiono nei codici dei lotti) |
| `device_sync_checkpoint` | telemetria del dispositivo |
| `file_retention_clock` | stato tecnico dell'allineamento con media delle decorrenze di conservazione dei file (issue #239): si ricalcola dai record, che l'archivio porta per intero |
| `lot_number_counter` | contatore tecnico dei numeri di lotto (i numeri stanno sui record) |
| `organization_closure_state` | stato della chiusura: sta nella testata dell'archivio |
| `pending_anonymization` | è per PERSONA, non per organizzazione |
| `purged_organization` | tombstone della cancellazione |
| `sync_operation` | registro tecnico di deduplica del push: non è un dato HACCP |
| `usage_allocation` | consumo dei crediti AI: dato del servizio, non registro HACCP |
| `usage_event` | consumo dei crediti AI: dato del servizio, non registro HACCP |

**Dati di funzionamento interno esclusi ai sensi dell'art. 25 par. 2 lett. f del Regolamento (UE) 2023/2854** (Data Act). Sono dati specifici al funzionamento interno del servizio, la cui esportazione esporrebbe il servizio al rischio di violazione di segreti commerciali; l'esclusione è dichiarata nel contratto. Mancano anche dalle versioni superate in `record_version`.

| Dato | Motivo |
| --- | --- |
| `device_code` | l'associazione fra ogni telefono e la sigla con cui il servizio compone i codici dei lotti offline: meccanismo di funzionamento interno (la sigla resta nel codice di ogni lotto di produzione) |
| `duplicate_verification.collision_key` | la chiave interna con cui il servizio riconosce i possibili doppioni: meccanismo interno (i due lotti confrontati restano in `left_id` e `right_id`) |
| `production_lot.signature_sources` | gli elementi da cui il servizio calcola l'impronta delle fonti per raggruppare le preparazioni in un lotto: meccanismo interno (le fonti restano negli ingredienti delle schede, l'impronta in `signature`) |

## Le relazioni fra i tipi

Ogni riga dice: il campo di un tipo porta l'identificativo di un record di un altro tipo.

| Da | Campo | A |
| --- | --- | --- |
| [`site`](https://eleccp.com/en/formato-archivio#tipo-site) | `created_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`site`](https://eleccp.com/en/formato-archivio#tipo-site) | `updated_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`site_assignment`](https://eleccp.com/en/formato-archivio#tipo-site-assignment) | `user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`site_assignment`](https://eleccp.com/en/formato-archivio#tipo-site-assignment) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`site_assignment`](https://eleccp.com/en/formato-archivio#tipo-site-assignment) | `assigned_by` | `organizzazione.json` → `members` (`user_id`) |
| [`site_assignment`](https://eleccp.com/en/formato-archivio#tipo-site-assignment) | `revoked_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) | `photo_media_id` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | `supplier_id` | [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) | `exhausted_by_recall_id` | [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `delivery_id` | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `supplier_id` | [`supplier`](https://eleccp.com/en/formato-archivio#tipo-supplier) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) | `consolidated_into_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `source_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `source_delivery_id` | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `catalog_product_id` | [`catalog_product`](https://eleccp.com/en/formato-archivio#tipo-catalog-product) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `outcome_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `confirmed_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `duplicated_from_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) | `production_lot_id` | [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `production_sheet_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `incoming_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`production_ingredient`](https://eleccp.com/en/formato-archivio#tipo-production-ingredient) | `source_delivery_id` | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `production_sheet_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `production_lot_id` | [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `source_unit_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`production_lot`](https://eleccp.com/en/formato-archivio#tipo-production-lot) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) | `lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) | `internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) | `open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) | `previous_version_id` | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) | `copied_from` | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) | `created_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) | `deactivated_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) | `published_by` | `organizzazione.json` → `members` (`user_id`) |
| [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) | `created_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) | `updated_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) | `plan_version_id` | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) | `event_type_id` | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) | `equipment_id` | [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) |
| [`plan_suspension`](https://eleccp.com/en/formato-archivio#tipo-plan-suspension) | `plan_version_id` | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| [`plan_suspension`](https://eleccp.com/en/formato-archivio#tipo-plan-suspension) | `control_point_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`plan_suspension`](https://eleccp.com/en/formato-archivio#tipo-plan-suspension) | `created_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`plan_suspension`](https://eleccp.com/en/formato-archivio#tipo-plan-suspension) | `cancelled_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) | `control_point_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) | `satisfied_by_event_id` | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) | `nc_id` | [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `event_type_id` | [`event_type`](https://eleccp.com/en/formato-archivio#tipo-event-type) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `control_point_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `incoming_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `production_sheet_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `storage_location_id` | [`storage_location`](https://eleccp.com/en/formato-archivio#tipo-storage-location) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `equipment_id` | [`equipment`](https://eleccp.com/en/formato-archivio#tipo-equipment) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `plan_version_id` | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `expected_registration_id` | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| [`event`](https://eleccp.com/en/formato-archivio#tipo-event) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `control_point_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `event_id` | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `expected_registration_id` | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `incoming_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `delivery_id` | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `production_sheet_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `assignee_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `taken_over_by` | `organizzazione.json` → `members` (`user_id`) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `late_control_event_id` | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `verified_by` | `organizzazione.json` → `members` (`user_id`) |
| [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `incoming_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`label_print_log`](https://eleccp.com/en/formato-archivio#tipo-label-print-log) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`duplicate_verification`](https://eleccp.com/en/formato-archivio#tipo-duplicate-verification) | `left_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`duplicate_verification`](https://eleccp.com/en/formato-archivio#tipo-duplicate-verification) | `right_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`duplicate_verification`](https://eleccp.com/en/formato-archivio#tipo-duplicate-verification) | `opened_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`duplicate_verification`](https://eleccp.com/en/formato-archivio#tipo-duplicate-verification) | `resolved_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `exposed_unit_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `recovered_unit_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `control_point_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `control_point_lineage_id` | [`control_point`](https://eleccp.com/en/formato-archivio#tipo-control-point) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `plan_version_id` | [`plan_version`](https://eleccp.com/en/formato-archivio#tipo-plan-version) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `event_ids` | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `missing_registration_ids` | [`expected_registration`](https://eleccp.com/en/formato-archivio#tipo-expected-registration) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `measurement_event_id` | [`event`](https://eleccp.com/en/formato-archivio#tipo-event) |
| [`unit_recovery`](https://eleccp.com/en/formato-archivio#tipo-unit-recovery) | `nc_id` | [`non_conformity`](https://eleccp.com/en/formato-archivio#tipo-non-conformity) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `attachments` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `origin_incoming_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `origin_internal_lot_id` | [`internal_lot`](https://eleccp.com/en/formato-archivio#tipo-internal-lot) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `origin_production_sheet_id` | [`production_sheet`](https://eleccp.com/en/formato-archivio#tipo-production-sheet) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `origin_delivery_id` | [`delivery`](https://eleccp.com/en/formato-archivio#tipo-delivery) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `origin_open_ingredient_id` | [`open_ingredient`](https://eleccp.com/en/formato-archivio#tipo-open-ingredient) |
| [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) | `closed_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`record_version`](https://eleccp.com/en/formato-archivio#tipo-record-version) | `author_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`collision_resolution`](https://eleccp.com/en/formato-archivio#tipo-collision-resolution) | `existing_lot_id` | [`incoming_lot`](https://eleccp.com/en/formato-archivio#tipo-incoming-lot) |
| [`collision_resolution`](https://eleccp.com/en/formato-archivio#tipo-collision-resolution) | `resolved_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `media_ids` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `missing_media_ids` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `created_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `revoked_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `legal_decided_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) | `legal_extract_media_ids` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`recall_item_outcome`](https://eleccp.com/en/formato-archivio#tipo-recall-item-outcome) | `recall_id` | [`recall`](https://eleccp.com/en/formato-archivio#tipo-recall) |
| [`recall_item_outcome`](https://eleccp.com/en/formato-archivio#tipo-recall-item-outcome) | `status_event_id` | [`lot_status_event`](https://eleccp.com/en/formato-archivio#tipo-lot-status-event) |
| [`recall_item_outcome`](https://eleccp.com/en/formato-archivio#tipo-recall-item-outcome) | `decided_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`recall_item_outcome`](https://eleccp.com/en/formato-archivio#tipo-recall-item-outcome) | `previous_decided_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`site_access_code_rotation`](https://eleccp.com/en/formato-archivio#tipo-site-access-code-rotation) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`site_access_code_rotation`](https://eleccp.com/en/formato-archivio#tipo-site-access-code-rotation) | `rotated_by` | `organizzazione.json` → `members` (`user_id`) |
| [`site_reactivation`](https://eleccp.com/en/formato-archivio#tipo-site-reactivation) | `site_id` | [`site`](https://eleccp.com/en/formato-archivio#tipo-site) |
| [`site_reactivation`](https://eleccp.com/en/formato-archivio#tipo-site-reactivation) | `actor_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) | `media_id` | [`file`](https://eleccp.com/en/formato-archivio#tipo-file) |
| [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) | `replaced_by_id` | [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) |
| [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) | `declared_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`validation_use`](https://eleccp.com/en/formato-archivio#tipo-validation-use) | `ceased_by_user_id` | `organizzazione.json` → `members` (`user_id`) |
| [`file`](https://eleccp.com/en/formato-archivio#tipo-file) | `holds` | [`document_hold`](https://eleccp.com/en/formato-archivio#tipo-document-hold) |

## Versioni del formato

Il numero di versione (`format_version` nei manifest e in `organizzazione.json`) **sale a ogni cambiamento di ciò che questa pagina descrive**: un file o un campo aggiunto, tolto, rinominato o che cambia significato, un valore ammesso nuovo, una struttura diversa dei pacchetti. Un archivio porta sempre la versione con cui è stato scritto; questa pagina descrive la versione corrente.

| Versione | Dal | Che cosa è cambiato |
| --- | --- | --- |
| 6 | 28 settembre 2026 | `missing[].reason` ammette `expired`: il file è stato cancellato perché la sua conservazione era finita, con la data in `missing[].expired_at` (issue #239). |
| 5 | 28 settembre 2026 | `document_hold.source_kind` ammette `non_conformity`: la scadenza dei file è sospesa mentre una non conformità è aperta (issue #238). |
| 4 | 28 settembre 2026 | Esclusi i dati di funzionamento interno del servizio (art. 25 par. 2 lett. f del Regolamento (UE) 2023/2854): il tipo `device_code` e i campi `production_lot.signature_sources` e `duplicate_verification.collision_key`, anche nelle versioni superate. |
| 3 | 28 settembre 2026 | `organizzazione.json` nel pacchetto 1 (azienda, organizzazione, membri); `format_url` nei manifest; le sezioni mancanti in `missing`. |
| 2 | 27 settembre 2026 | L'archivio in pacchetti ZIP con `manifest.json` radice e `manifest-parte.json`. |
| 1 | 27 settembre 2026 | Un solo ZIP con i dati e i file. |

On this page

- [Data Act](https://eleccp.com/en/formato-archivio#data-act)

- [Com'è fatto l'archivio](https://eleccp.com/en/formato-archivio#com-e-fatto-l-archivio)

- [Regole generali](https://eleccp.com/en/formato-archivio#regole-generali)

- [LEGGIMI.txt](https://eleccp.com/en/formato-archivio#leggimi-txt)

- [manifest.json (pacchetto 1)](https://eleccp.com/en/formato-archivio#manifest-json-pacchetto-1)

- [manifest-parte.json (pacchetti 2, 3, …)](https://eleccp.com/en/formato-archivio#manifest-parte-json-pacchetti-2-3)

- [organizzazione.json (pacchetto 1)](https://eleccp.com/en/formato-archivio#organizzazione-json-pacchetto-1)

- [I dati: dati/<tipo>.jsonl](https://eleccp.com/en/formato-archivio#i-dati-dati-tipo-jsonl)

- [Dati non compresi nell'archivio](https://eleccp.com/en/formato-archivio#dati-non-compresi-nell-archivio)

- [Le relazioni fra i tipi](https://eleccp.com/en/formato-archivio#le-relazioni-fra-i-tipi)

- [Versioni del formato](https://eleccp.com/en/formato-archivio#versioni-del-formato)
