Passa al contenuto principale
Versione: 0.3.0

Modello dei dati

Le tabelle qui sotto sono prese dalle migrazioni del server (server/internal/storage/sql/migrations/) e dallo schema speculare del client (app/src/lib/local/schema.ts). I nomi delle colonne sono identici da entrambe le parti e sono le chiavi usate nei payload di sincronizzazione. Le colonne enum memorizzano il numero proto; l'etichetta visualizzata è quella che mostra l'app (app/src/lib/i18n/locales/en.json).

Ogni tabella sincronizzata porta tre colonne di gestione non ripetute sotto: organization_id (tenant), field_hlc (orologio dei campi in JSON, vedi il protocollo di sincronizzazione) e deleted (flag di cancellazione logica). Gli id sono UUID, generati sul dispositivo oppure dal server per le righe create tramite l'API. I timestamp sono memorizzati come stringhe ISO 8601 sul client e come TIMESTAMP sul server.

Gerarchia​

apiary
└── hive ── queen (one active, older ones kept with replaced_at set)
├── inspection
├── task (task.hive_id and task.apiary_id are both optional)
├── harvest
├── treatment
├── placement (which apiary the hive lived in, and when)
└── event (append-only history with frozen apiary/hive/queen)

La condivisione e il partizionamento della sincronizzazione usano scope_id: l'id dell'apiario stesso per l'apiario e per tutto ciò che vi è contenuto. Solo event memorizza scope_id come colonna; per le altre tabelle viene trasportato nel messaggio Change.

apiary​

ColonnaTipoNote
idtext
nametextobbligatorio
addresstexttesto libero
lat, lngreal0 quando non impostati
notetext
created_at, updated_attimestamp

hive​

ColonnaTipoNote
idtextcodificato anche nell'etichetta QR
apiary_idtextapiario attuale
nametext
typeintHiveType, vedi sotto
statusintHiveStatus, vedi sotto; le nuove arnie partono da 1
boxesintnumero di corpi
colony_origintextes. "sciame 2024"
notetext
qr_codetextriservato; il codice stampato è derivato da id da shortCode() in app/src/lib/qr.ts
phototextdata URL o chiave blob
created_at, updated_attimestamp

HiveType: 0 Non specificato, 1 Zander, 2 Dadant, 3 Deutsch Normal, 4 Langstroth, 5 Warré, 6 Top-bar, 99 Altro.

HiveStatus: 0 Non specificato, 1 Attiva, 2 Nucleo, 3 Orfana, 4 Persa, 5 Sciolta.

queen​

ColonnaTipoNote
idtext
hive_idtext
yearintl'anno della regina; determina il colore di marcatura predefinito
markingintMarkingColor: 1 bianco (anni che finiscono in 1/6), 2 giallo (2/7), 3 rosso (3/8), 4 verde (4/9), 5 blu (5/0); predefinito da year
origintext
breeder_numbertext
introduced_attimestampinizio del regno
replaced_attimestampfine del regno, null finché regna
activebooltrue per la regina attuale
notetext
created_at, updated_attimestamp

Un cambio di regina imposta active = 0 e replaced_at sulla vecchia riga e ne inserisce una nuova; le vecchie regine non vengono mai eliminate.

inspection​

ColonnaTipoNote
id, hive_idtext
datetimestamp
weathertext
queen_seen, eggs_seenbool
temperamentint1 Molto docile, 2 Docile, 3 Normale, 4 Nervosa, 5 Aggressiva
calmnessint1 Fugge dal favo, 2 Irrequieta, 3 Calma, 4 Molto calma
framesinttelaini occupati
brood_framesint
storesint1 Buone, 2 Medie, 3 Scarse, 4 Assenti
queen_cellsintcelle reali di sciamatura contate
youngest_larvaintetà in giorni della larva più giovane vista
covered_larvaboolcovata opercolata vista
varroatext
honey_kg, fed_kg, weight_kgreal
frames_added, frames_removedint
drone_frame_cut, super_addedbool
temp_hive, temp_outsidereal°C, null quando non misurata nell'app; CreateInspection memorizza 0 per i campi omessi
humidity_hive, humidity_outsidereal%, stessa regola delle temperature
notetext
photo_keystextJSON OR-Set, l'unica colonna insieme
created_attimestamp

task​

ColonnaTipoNote
idtext
titletext
hive_id, apiary_idtextopzionali
due_attimestamp
donebool
priorityintTaskPriority: 1 Bassa, 2 Normale, 3 Alta; la colonna del server ha 2 come predefinito, l'app scrive 0
note, recurrence, assigned_totextpresenti nello schema; il modulo attività compila solo title e due_at
created_attimestamp

placement​

ColonnaTipoNote
id, hive_id, apiary_idtext
start_attimestamp
end_attimestampnull per la collocazione attuale

Creare un'arnia apre una collocazione; spostarla chiude la riga aperta al momento dello spostamento e ne apre una nuova.

Un'attività senza apiary_id si sincronizza sotto lo scope personale user:<user id> invece che sotto l'id di un apiario.

harvest​

ColonnaTipoNote
idtext
apiary_id, hive_id, queen_idtextfissati al momento del raccolto
datetimestamp
varietytext
amount_kgreal
water_contentreal%
batch_numbertext
best_beforetimestamp
notetext

treatment​

ColonnaTipoNote
idtext
apiary_id, hive_id, queen_idtextfissati al momento del trattamento
datetimestamp
product, active_ingredienttext
dose, methodtext
batch_numbertext
withdrawal_untiltimestamp
reasontextpredefinito varroa
notetext

event​

ColonnaTipoNote
idtext
scope_idtextid dell'apiario
typeintEventType, vedi sotto
datetimestamp
apiary_id, hive_id, queen_idtextfissati al momento dell'evento
ref_entity, ref_idtextla riga di dettaglio, es. harvest / il suo id
titletext
amount_kgrealcopiato dal raccolto così le query sulla resa non richiedono join
detailtextJSON
author_idtext

EventType: 1 Creata, 2 Regina introdotta, 3 Regina sostituita, 4 Spostata, 5 Ispezione, 6 Trattamento, 7 Raccolto, 8 Stato, 9 Sciolta. L'app scrive i tipi da 1 a 7 (app/src/lib/local/history.ts). Vedi Storia ed eventi.

Tabelle solo server​

organization, users, member, invite, user_passkey, api_key, apiary_share, change_log e seq_counter esistono solo sul server. member.role è owner o member; users.role è admin o user. apiary_share viene letta dal controllo degli scope di sincronizzazione ma nulla nell'app la scrive. Il client aggiunge outbox e sync_meta per il motore di sincronizzazione.

api_key​

Chiavi a lunga durata per script e integrazioni (migrazione 0014_api_keys.sql, server/internal/auth/apikey.go). Non sincronizzata.

ColonnaTipoNote
idtext
user_idvarchar(64)proprietario; indicizzata
organization_idvarchar(64)il tenant in cui la chiave agisce, fissato alla creazione
nametextetichetta mostrata nelle Impostazioni
key_prefixtexti primi 12 caratteri del testo in chiaro, per la visualizzazione
key_hashvarchar(64)SHA-256 in esadecimale del token obhk_... in chiaro, univoco; il testo in chiaro non viene mai memorizzato
scopetextwrite (predefinito) o read; una chiave read può chiamare solo Get*, List*, Pull e Subscribe
created_attimestamp
expires_attimestampnull per le chiavi che non scadono mai; una chiave oltre questo istante viene rifiutata
last_used_attimestampaggiornato a ogni utilizzo verificato, null fino ad allora

Una chiave viene verificata calcolando l'hash del bearer token e cercando key_hash; la riga viene eliminata alla rimozione, e una chiave il cui proprietario non è più member di organization_id, o il cui expires_at è passato, viene rifiutata senza essere eliminata.