/ Guida Admin & Algoritmi
Overview Simulator
Guida Amministratore & Algoritmi WMS
Installazione, configurazione, algoritmi di prelievo (picking) e deposito (put-away), con roadmap per le regole AI basate su prompt in linguaggio naturale.
Ubuntu 22.04+ Docker 24+ Algoritmi aggiornati RAG Knowledge Base — LIVE AI Rules — Q3 2026
1

Prerequisiti

RisorsaMinimoConsigliato
CPU4 vCPU8 vCPU
RAM8 GB16 GB
Disco40 GB SSD100 GB SSD
OSUbuntu 22.04 LTS / Debian 12
Docker≥ 24.x + Compose v2
Conflitto porteLe porte 3050–3055 sono già occupate da altri servizi. WMS Agile usa 3080–3090. Verificare con ss -tlnp | grep 308.
2

Server & Docker

bash
# Installa Docker su Ubuntu
apt update && apt install -y ca-certificates curl gnupg git jq
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    gpg --dearmor -o /etc/apt/keyrings/docker.gpg
apt install -y docker-ce docker-ce-cli docker-compose-plugin

# Clone repository
git clone https://git.certisource.it/AdminGit2026/wms-agile.git /var/www/wms-agile

# CRITICO: imposta nome progetto (evita conflitti Docker)
echo "COMPOSE_PROJECT_NAME=wms-agile" > /var/www/wms-agile/infrastructure/.env

Per la guida completa di installazione server → docs/INSTALL.html

3

Configurazione file di ambiente

bash
# Copia template per ogni servizio
for svc in auth inventory warehouse inbound outbound report ai calendar wcs network; do
    cp services/${svc}-ms/.env services/${svc}-ms/.env.production
done

# JWT_SECRET uguale per tutti (CRITICO)
JWT=$(openssl rand -hex 32)
for svc in auth inventory warehouse inbound outbound report ai calendar wcs network; do
    sed -i "s/^JWT_SECRET=.*/JWT_SECRET=${JWT}/" services/${svc}-ms/.env.production
done
ANTHROPIC_API_KEY — ✅ Già configurata in produzioneLa chiave di sistema è attiva in services/ai-ms/.env.production. Health check conferma: "anthropic_key":"configured","model":"claude-sonnet-4-6". Ogni tenant può sovrascriverla con la propria chiave via Admin → AI / RAG.
RAG Knowledge Base — ✅ Attiva in produzione (Feb 2026)Voyage AI (voyage-3-lite 512 dim) + Qdrant vector DB. 15 moduli WMS pre-indicizzati · 36 chunk · collection wms_kb_{tenant_id}. Indicizzazione aggiuntiva: Admin → AI / RAG → "Indicizza Documentazione WMS" (90 secondi).
4

Avvio & verifica

bash
# Build e start (prima volta ~15 min)
cd /var/www/wms-agile/infrastructure
COMPOSE_PROJECT_NAME=wms-agile docker compose \
    -f docker-compose.yml -f docker-compose.production.yml up -d --build

# Verifica health check (attendi ~60s per MySQL)
for port in 3081 3082 3083 3084 3085 3086 3087; do
    echo "Porta $port: $(curl -sk -o /dev/null -w '%{http_code}' http://127.0.0.1:$port/health)"
done
SQL aggiuntiviApplicare manualmente i file sql/06-*.sqlsql/19-*.sql dopo il primo avvio. Sono idempotenti (IF NOT EXISTS).
5

Primo tenant (onboarding)

bash
./infrastructure/first-install.sh \
    https://wms.tuodominio.it \
    "Nome Azienda" admin@azienda.it "Password2026!"

# Output atteso: 12/12 ✅  (tenant + admin + warehouse + 6 zone + 3 prodotti)
6

Apache reverse proxy + SSL

apache
<VirtualHost *:443>
    ServerName wms.tuodominio.it
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/wms.tuodominio.it/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/wms.tuodominio.it/privkey.pem
    ProxyPreserveHost On
    ProxyPass        / http://127.0.0.1:3080/
    ProxyPassReverse / http://127.0.0.1:3080/
    # SSE streaming AI: no buffering
    ProxyPassMatch ^/api/ai/chat$ http://127.0.0.1:3080/api/ai/chat
    Header always set Cache-Control "no-cache"
</VirtualHost>
bash
certbot --apache -d wms.tuodominio.it
a2ensite wms-agile wms-agile-ssl && systemctl reload apache2
7

Algoritmi di Prelievo (Picking) Aggiornato

Il picking è la fase critica dell'outbound: determinare quale unità fisica prelevare quando ci sono più lotti/ubicazioni disponibili dello stesso SKU. La scelta dell'algoritmo impatta direttamente su rotazione stock, scaduti, produttività operatori e costi di movimentazione.

Configurazione in WMS AgileLa strategia di picking si imposta a livello di tenant, categoria prodotto o singolo SKU tramite il parametro picking_strategy nella tabella wms_inventory_db.product_config. È possibile combinare più strategie con priorità.

Algoritmi disponibili

FIFO
First In, First Out
DEFAULT

Il primo prodotto entrato in magazzino è il primo ad essere prelevato. Basato sulla data di ricevimento del lotto.

Complessità
● Bassa
Rotazione stock
● Ottima
Pro
Previene invecchiamento
Prevedibile e semplice
Conforme a molte norme
Contro
Non considera scadenze
Non ottimizza percorsi
SQL sorting
ORDER BY sl.received_at ASC,
         sl.lot_number ASC
Quando usarlo: Prodotti standard senza data di scadenza, componentistica, articoli di largo consumo.
FEFO
First Expired, First Out
LOTTIPHARMAFOOD

Il lotto con la data di scadenza più vicina viene prelevato per primo, indipendentemente dall'ordine di ingresso. Richiede gestione lotti con expiry_date.

Complessità
● Media
Riduz. scaduti
● Massima
Pro
Elimina sprechi da scadenza
Obbligatorio GDP/GMP
Tracciabilità lotti
Contro
Richiede lotti con expiry
Più complesso da gestire
SQL sorting
ORDER BY l.expiry_date ASC,
         l.manufactured_date ASC
Quando usarlo: Farmaci, alimenti, cosmetici, reagenti chimici, qualsiasi prodotto con shelf-life.
LIFO
Last In, First Out
AVANZATO

L'ultimo prodotto entrato è il primo ad essere prelevato. Usato in casi specifici dove i prodotti più recenti sono fisicamente più accessibili.

Complessità
● Bassa
Rotazione stock
● Sconsigliata
Pro
Riduce movimentazione fisica
Utile per scaffali profondi
Contro
Rischio stock "invecchiato"
Non conforme a ISO/GDP
SQL sorting
ORDER BY sl.received_at DESC
Quando usarlo: Materiali non deperibili con scadenza lontana, scaffali drive-in dove il prelievo frontale è impossibile.
Zone Picking
Picking per zona assegnata
AVANZATO

Il magazzino è diviso in zone. Ogni operatore copre solo la propria zona. Gli ordini multi-zona vengono consolidati alla fine del processo.

Produttività
● Alta
Interferenze
● Ridotte
Pro
Operatori specializzati per zona
Meno conflitti corridoio
KPI per zona misurabili
Contro
Richiede merge degli ordini
Più latenza se una zona è lenta
config WMS
zone_id = operators.assigned_zone
picking_mode = 'zone_based'
merge_timeout_min = 15
Quando usarlo: Magazzini grandi con zone distinte (secco/fresco/farmacia), carichi di lavoro ad alta intensità.
Wave Picking
Picking a onde di rilascio
AVANZATOAGV

Gli ordini vengono raggruppati in "onde" (wave) e rilasciati in batch ottimizzati. Permette di pianificare risorse, AGV e dock di spedizione in anticipo.

Ottimiz. AGV
● Massima
Lead time
● Ridotto
Pro
Ottimizza routing AGV
Rispetta finestre spedizione
Pianificazione risorse
Contro
Non per ordini urgenti singoli
Richiede WavePlanningService
WMS Agile
POST /api/outbound/wave/create
{ wave_size: 50, ship_window: "14:00",
  strategy: "minimize_travel" }
Quando usarlo: Operazioni con finestre di spedizione fisse, AGV/robot autonomi, alto volume di ordini omogenei.
Cluster Picking
Prelievo multi-ordine
E-COMMAVANZATO

Un operatore preleva articoli per più ordini in un unico giro con un carrello multi-tote. Ciascun tote rappresenta un ordine. Maximizza la produttività per ordine.

Produttività
● Molto alta
Distanza percorsa
● Minimizzata
Pro
–60% distanza vs single
Ottimo per ordini piccoli
Contro
Richiede carrello dedicato
Errori smistamento se tanti tote
config WMS
cluster_size = 4   # tote per giro
sort_by = "zone_proximity"
Quando usarlo: E-commerce con ordini mono o pochi articoli, alta densità SKU per zona.
Batch Picking
Prelievo a lotti di ordini
E-COMM

Raggruppa ordini che condividono gli stessi SKU. L'operatore preleva la quantità totale per tutti gli ordini del batch, poi smista al sorter.

SKU ripetuti
● 1 solo prelievo
Sorter richiesto
● Sì
Pro
Minimizza visite per bin
Riduce tempi percorrenza
Contro
Richiede sorter/smistamento
Non per prodotti con lotti diversi
config WMS
batch_mode = 'same_sku'
batch_size_max = 20
sort_method = 'conveyor'
Quando usarlo: Alto volume e-commerce con SKU ripetuti, impianto dotato di nastri smistamento.
Proximity
Ottimizzazione percorso
AGVAVANZATO

Ordina i prelievi per minimizzare la distanza totale percorsa dall'operatore/AGV usando una sequenza ottimizzata per corsia → scaffale → ripiano.

Distanza
● Minima
Complessità
● Alta
Pro
Percorso ottimale (TSP)
Ideale per AGV autonomi
Contro
Può rompere FIFO/FEFO
Richiede mappa bin aggiornata
SQL sorting
ORDER BY zone_code ASC,
         aisle_code ASC,
         shelf_level ASC,
         bin_position ASC
Quando usarlo: AGV con mappa magazzino, picking tours a alta frequenza, ottimizzazione energetica robot.

Tabella comparativa — quale algoritmo scegliere?

AlgoritmoScadenzeProd.Comp.Ideale per
FIFONoAltaBassaStandard — tutti i settori
FEFOSì ✓AltaMediaPharma, Food, Cosmetica
LIFONoMediaBassaMateriali non deperibili
ZoneCombinabileMolto altaMediaMagazzini >5.000 mq
WaveCombinabileMolto altaAltaAGV, finestre spedizione fisse
ClusterCombinabileEccellenteMediaE-commerce ordini piccoli
BatchNoEccellenteAltaE-commerce con sorter
ProximityCombinabileOttimaAltaAGV, ottimiz. energetica
8

Algoritmi di Deposito (Put-Away) Aggiornato

Il put-away determina dove collocare la merce appena ricevuta. Un algoritmo corretto riduce il numero di movimenti durante il picking, ottimizza l'utilizzo dello spazio e garantisce la conformità (temperatura, normative, separazione merci).

Configurazione in WMS AgileLa strategia di deposito si imposta tramite il parametro putaway_strategy nella configurazione tenant/categoria. Il sistema può combinare più strategie con una catena di priorità (rule chain): prima verifica la regola 1, se non applicabile passa alla 2, ecc.

Algoritmi disponibili

Fixed Location
Ubicazione fissa per SKU
DEFAULT

Ad ogni SKU è assegnata una o più ubicazioni fisse. La merce va sempre e solo in quel bin. Semplice, prevedibile, facile da ricordare per gli operatori.

Complessità
● Bassa
Uso spazio
● Non ottimale
Pro
Operatori memorizzano posizioni
Zero calcolo a runtime
Contro
Spreco se SKU inattivo
Rigido per assortimento variabile
config WMS
putaway_strategy = 'fixed'
primary_bin = products.default_bin_code
Quando usarlo: Catalogo SKU stabile e limitato, operatori non esperti, magazzini piccoli.
ABC Slotting
Posizionamento per classe ABC
AVANZATO

I prodotti A (più movimentati) vanno in posizioni ergonomiche vicino alla spedizione. I prodotti C (lenta rotazione) vanno in zone remote o ad altezze difficili.

Produttività pick
● +30-40%
Ricalcolo
● Mensile
Pro
Prodotti A sempre accessibili
Riduce distanza operatori
Adattivo nel tempo
Contro
Richiede analisi periodica
Reslotting comporta fermata breve
SQL — zona target
CASE products.abc_class
  WHEN 'A' THEN 'ZONA-PICK-FRONT'
  WHEN 'B' THEN 'ZONA-PICK-MID'
  WHEN 'C' THEN 'ZONA-BULK-REAR'
END
Quando usarlo: Magazzini con assortimento ampio e distribuzione Pareto (20% SKU = 80% movimenti).
Zone-Based
Deposito per caratteristiche zona
PHARMAFOODGDP

Abbina il prodotto alla zona più adatta in base a: temperatura richiesta, peso, categoria merceologica, tenant, normative (GDP, HACCP, ADR).

Conformità
● Garantita
Flessibilità
● Alta
Pro
Separazione obbligatoria merci
Conformità automatica GDP
Supporta multi-tenant
Contro
Richiede classificazione prodotti
Zone possono saturarsi
regole zona
PharmaNet + requires_cold  → zona GDP (2-8°C)
categoria = 'pericoloso'   → zona ADR separata
tenant_id = RetailDistrib  → zona ecommerce
Quando usarlo: Magazzini multi-tenant, farmaceutico GDP, alimentare HACCP, merci pericolose ADR.
Random Putaway
Prima ubicazione libera

La merce viene collocata nella prima ubicazione libera disponibile nelle zone ammissibili. Massimizza l'utilizzo dello spazio ma richiede picking proximity-based.

Uso spazio
● Massimo
Distanza picking
● Alta
Pro
Nessun bin sprecato
Funziona con catalogo variabile
Contro
Picking più lungo senza proximity
Difficile senza WMS per operatori
SQL — bin selection
WHERE b.status = 'empty'
  AND b.zone_id IN (allowed_zones)
ORDER BY b.distance_from_dock ASC
LIMIT 1
Quando usarlo: Magazzini caotici con WMS avanzato, assortimento molto variabile, accoppiato con Proximity picking.
Bulk-to-Active
Riserva → Picking attivo
AGVAVANZATO

I pallet completi vanno in zona riserva (bulk). Quando il bin di picking attivo si svuota sotto soglia, viene generata automaticamente una missione di rifornimento.

Rifornimento
● Automatico
Ottimiz. spazio
● Elevata
Pro
Zero stockout zona picking
Missioni AGV prevedibili
Separazione bulk/attivo
Contro
Doppio handling pallet
Richiede soglie di riordino
trigger rule
IF bin.qty < replenishment_threshold:
  CREATE mission(type='replenishment',
    from=bulk_bin, to=active_bin)
Quando usarlo: SKU ad alta rotazione con acquisto in pallet, magazzini con zone bulk separate, integrazione AGV/WCS.
Cross-Docking
Bypass stoccaggio
AVANZATO

La merce in arrivo è già allocata ad ordini in uscita. Viene portata direttamente all'area staging/spedizione senza essere stoccata. Tempo di permanenza minimo.

Lead time
● Minimo
Costi handling
● –50%
Pro
Nessun costo stoccaggio
Tempi di consegna ridotti
Ideale per prodotti freschi
Contro
Richiede ordini pre-allocati
Sincronia ingresso/uscita
regola trigger
IF inbound_line.pre_allocated_order:
  putaway_zone = 'STAGING'
  skip_storage = TRUE
Quando usarlo: Prodotti freschi/deperibili, merce in transito GDO, distribuzione regionale veloci, retail promotions.

Tabella comparativa — quale algoritmo scegliere?

AlgoritmoSpazioVelocità dep.Comp.Ideale per
FixedNon ottimaleAltaBassaCatalogo stabile, magazzini piccoli
ABC SlottingMediaMediaMediaAmpio assortimento, Pareto tipico
Zone-BasedMediaAltaMediaPharma GDP, multi-tenant, ADR
RandomMassimoAltaBassaCatalogo variabile + WMS avanzato
Bulk-to-ActiveOttimaleMediaAltaSKU alta rotazione, AGV disponibili
Cross-DockingZeroMassimaAltaFreschi, transito, pre-allocazione
9

AI / RAG Knowledge Base Live da Feb 2026

Il sistema RAG (Retrieval-Augmented Generation) è attivo in produzione. La chat AI Claude non risponde solo con conoscenza generica — consulta la knowledge base aziendale del tenant prima di rispondere. SOP, procedure operative, guide dei moduli WMS: tutto indicizzato in vettori semantici e ricercato in tempo reale.

Stato produzione — Feb 2026
Voyage AI (voyage-3-lite, 512 dim, cosine similarity) → embedding semantici
Qdrant (Docker container wms-qdrant:6333) → vector DB isolato per tenant
15 moduli WMS pre-indicizzati · 36 chunk · collection wms_kb_1
• Soglia rilevanza: score cosine ≥ 0.35 · top-4 chunk per query

Come indicizzare i propri documenti

Dal pannello Admin → Impostazioni → AI / RAG sono disponibili due modalità:

bash
# 1. Auto-seed moduli WMS (15 guide operative, ~90 secondi)
POST /api/ai/knowledge/seed-wms
# → indicizza Dashboard, Inbound, Outbound, Missioni, 4PL, TMS, RAG, WCS, Rete Filiera...

# 2. Indicizza documento custom (SOP aziendale, manuale fornitore, policy)
POST /api/ai/knowledge/ingest
Content-Type: application/json
{
  "doc_id":   "sop-gdp-2026-003",
  "title":   "SOP GDP — Gestione Farmaci 2-8°C",
  "content": "Procedura operativa: i farmaci refrigerati vanno...",
  "source":  "wms://sop/gdp/003"
}

# 3. Verifica statistiche knowledge base
GET /api/ai/knowledge/stats
# → { "points_count": 36, "status": "green", "collection": "wms_kb_1" }
Tip — Voyage AI Free TierIl piano gratuito ha limiti di 3 RPM / 10K TPM. Il seed WMS usa batch da 8 testi con 22s di pausa → indicizzazione completa in ~90 secondi. Per uso intensivo (100+ documenti SOP) aggiungere una payment method sul dashboard Voyage AI per sbloccare i rate limit standard.

Regole AI tramite Prompt Opzione Futura — Q3 2026

Evoluzione pianificata: definire regole di picking e put-away in linguaggio naturale, interpretate da Claude AI e tradotte in configurazione strutturata. L'infrastruttura Claude + RAG è già attiva — manca solo il tool set_warehouse_rules.

Stato attualeIl modulo ai-ms con Claude Sonnet è già attivo e gestisce 20+ tool WMS. La funzionalità "regole AI" è pianificata come estensione del sistema esistente di tool-calling. Non richiede infrastruttura aggiuntiva — solo l'implementazione del tool set_warehouse_rules.

Mockup interfaccia

Nell'area di configurazione del supervisore, un campo prompt permette di descrivere le regole in italiano:

WMS AI Rule Engine
claude-sonnet-4-6 · tool: set_warehouse_rules
Descrivi le regole in linguaggio naturale:
Tutti i prodotti del tenant PharmaNet con categoria 'farmaco' devono essere collocati nella zona GDP (2-8°C). Durante i flash sale del tenant RetailDistrib usa LIFO per velocizzare il prelievo. I prodotti con classe ABC = A devono avere sempre almeno 2 bin attivi nelle corsie vicine alla spedizione.
Output generato da Claude AI:
warehouse_rules.json — generato automaticamente
"rules": [
  {
    "id": "pharmanet-gdp",
    "name": "PharmaNet → GDP",
    "priority": 1,
    "trigger": {
      "tenant": "PharmaNet",
      "category": "farmaco"
    },
    "action": {
      "putaway_zone": "GDP",
      "temp_range_c": [2, 8],
      "compliance": "EU-GDP-2013"
    }
  },
  {
    "id": "retail-flash-sale-lifo",
    "name": "RetailDistrib Flash Sale → LIFO",
    "priority": 2,
    "trigger": {
      "tenant": "RetailDistrib",
      "event": "flash_sale"
    },
    "action": {
      "picking_strategy": "LIFO",
      "reason": "velocità massima su event sale"
    }
  },
  {
    "id": "abc-a-min-bins",
    "name": "Classe A — 2 bin attivi minimi",
    "priority": 3,
    "trigger": { "abc_class": "A" },
    "action": {
      "min_active_bins": 2,
      "zone_proximity": "near_shipping",
      "trigger_replenishment_at": "30%"
    }
  }
]

Esempi di prompt supportati

Temperatura
"Prodotti che richiedono freddo tra 2-8°C devono andare solo in zona C o D"
Scadenze
"Non stoccare prodotti con scadenza entro 30 giorni vicino a prodotti con scadenza lunga"
Peso
"Prodotti sopra 30kg solo al piano terra, ergonomicamente al livello 1 o 2"
Multi-tenant
"FoodGroup e PharmaNet non devono mai condividere gli stessi scaffali"
Urgenza
"Ordini con priorità EXPRESS devono saltare la wave e andare direttamente in coda picking"
Conformità
"Tutti i materiali ADR classe 3 devono essere separati da qualsiasi prodotto alimentare"

Roadmap implementazione

Q2 2026
Tool set_warehouse_rules per Claude

Aggiunta del tool set_warehouse_rules(rules_json) all'ai-ms. Claude può già interpretare linguaggio naturale e convertirlo in JSON strutturato.

Q3 2026
UI nel pannello Supervisore

Interfaccia textarea nella sezione Configurazione → Regole WMS. Preview degli effetti prima dell'applicazione.

Q4 2026
Template library e versioning

Libreria di template pre-validati (GDP, HACCP, ADR), versioning delle regole con rollback, diff visuale.

Futuro
AI autonomo — auto-ottimizzazione

Claude analizza le metriche operative (distanza media picking, stockout rate, scaduti) e propone autonomamente modifiche alle regole. L'admin approva o rifiuta.

10

Aggiornamento

bash
# Standard: pull + rebuild + sql
cd /var/www/wms-agile && git pull origin main
cd infrastructure
COMPOSE_PROJECT_NAME=wms-agile docker compose \
    -f docker-compose.yml -f docker-compose.production.yml up -d --build
./deploy-hetzner.sh --verify

# Hot-fix PHP (immediato, non persiste al restart)
docker cp services/inbound-ms/src/Services/InboundService.php \
    wms-inbound-ms:/var/www/services/inbound-ms/src/Services/
docker exec wms-inbound-ms kill -USR2 1
Git + bind mount — inode problemDopo git pull fare sempre docker restart wms-gateway: git crea nuovi inode, il container vede ancora i vecchi file.
11

Troubleshooting

Container non parte

bash
docker logs wms-{svc}-ms --tail=50
docker inspect wms-mysql | grep -A5 '"Health"'

Login 401

bash
# Verifica JWT_SECRET allineato
for svc in auth inventory warehouse; do
    echo -n "$svc: "; grep JWT_SECRET services/${svc}-ms/.env.production
done
# Se disallineati: riavvia TUTTI
docker restart $(docker ps --filter name=wms --format "{{.Names}}")

AI chat non risponde

bash
docker exec wms-ai-ms env | grep ANTHROPIC_API_KEY
docker logs wms-ai-ms --tail=20

Picking estratto lotto sbagliato

Se il picking non rispetta FEFO, verificare che:

  1. I lotti abbiano expiry_date popolato in wms_inventory_db.lots
  2. La configurazione SKU abbia picking_strategy = 'FEFO'
  3. La query OutboundService usi il JOIN su lots.expiry_date nel ORDER BY
Sistema operativo — tutto prontoPer supporto e issues → git.certisource.it/AdminGit2026/wms-agile
12

Auto-Learn & Cron Job

Il sistema AI si arricchisce automaticamente dai dati operativi live. Ogni notte alle 03:00 UTC un cron job genera 5 snapshot dal database e li indicizza in Qdrant via Voyage AI.

Cron Configuration

bash
# File: /etc/cron.d/wms-ai-autolearn
0 3 * * * root curl -s -X POST http://127.0.0.1:3087/api/ai/knowledge/auto-learn \
    -H "X-API-Key: YOUR_API_KEY" >> /var/log/wms-ai-autolearn.log 2>&1

Documenti Generati

doc_idDatabaseContenuto
wms-live-stockinventoryTop 15 prodotti + scorte sotto punto di riordino
wms-live-alertswarehouseAlert attivi per severity + risolti ultime 48h
wms-live-warehousewarehouseZone, bin, operatori attivi, missioni in corso
wms-live-billingagileFatture per status con totali EUR
wms-live-ncrwarehouseNon conformità aperte

Esecuzione Manuale

bash
# Trigger manuale (es. dopo import dati massivo)
curl -s -X POST http://127.0.0.1:3087/api/ai/knowledge/auto-learn \
    -H "X-API-Key: YOUR_API_KEY" | python3 -m json.tool
# Risposta attesa: {"success":true,"data":{"indexed":5,"total":5}}
Nota tenant_id: Con API Key auth il tenant_id è null → la route usa default 1. Per multi-tenant, usare JWT Bearer di un admin del tenant specifico.
13

Inventario Ciclico

L'inventario ciclico verifica lo stock in modo continuativo senza fermare le operazioni. Il servizio CycleCountService in inventory-ms gestisce pianificazione, esecuzione e reporting.

Schema Database

sql
-- wms_inventory_db
CREATE TABLE cycle_counts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    tenant_id INT NOT NULL,
    code VARCHAR(30) UNIQUE,
    type ENUM('full','zone','spot') DEFAULT 'full',
    zone_id INT NULL,              -- NULL = full warehouse
    status ENUM('planned','in_progress','completed','cancelled'),
    scheduled_date DATE,
    completed_at TIMESTAMP NULL,
    operator_id INT NULL,
    notes TEXT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE cycle_count_lines (
    id INT AUTO_INCREMENT PRIMARY KEY,
    cycle_count_id INT NOT NULL,
    product_id INT NOT NULL,
    bin_code VARCHAR(30),
    expected_qty DECIMAL(12,2),    -- sistema
    counted_qty DECIMAL(12,2) NULL, -- operatore
    variance DECIMAL(12,2) NULL,
    counted_at TIMESTAMP NULL,
    FOREIGN KEY (cycle_count_id) REFERENCES cycle_counts(id)
);

API Endpoints

MetodoEndpointDescrizione
GET/api/cycle-countsLista conteggi con filtri (status, type, date)
POST/api/cycle-countsCrea conteggio pianificato (full/zone/spot)
POST/api/cycle-counts/quickConteggio rapido singolo bin
14

WCS / MQTT Bridge

Il microservizio wcs-ms (porta 3089) fa da bridge tra WMS e i sistemi automatici (AGV, sorter, nastri) via protocollo MQTT (Mosquitto, porta 1883).

Architettura

text
WMS App ──→ wcs-ms (REST API) ──→ Mosquitto (MQTT broker) ──→ AGV/PLC
   ↑                                        │
   └────── SSE events ◄─── subscribe ◄──────┘

MQTT Topics

TopicDirPayload
wms/agv/{id}/statusAGV→WMSbattery, position, state (idle/busy/charging)
wms/agv/{id}/missionWMS→AGVmission_id, source_bin, target_bin, priority
wms/agv/{id}/positionAGV→WMSx, y, zone_code (per mappa SVG)
wms/agv/{id}/completeAGV→WMSmission_id, status (completed/failed), timestamp

Container

bash
# Verifica MQTT broker
docker logs wms-mosquitto --tail=20
# Test publish
docker exec wms-mosquitto mosquitto_pub -t "wms/agv/AGV-01/status" \
    -m '{"battery":85,"state":"idle","zone":"PICK-A"}'
# WCS health
curl -s http://127.0.0.1:3089/health | python3 -m json.tool
15

Notifiche SSE (Server-Sent Events)

Le notifiche push usano SSE per delivery real-time al browser. L'endpoint /api/realtime (warehouse-ms) mantiene una connessione persistente HTTP con Content-Type: text/event-stream.

Configurazione Nginx per SSE

nginx
# CRITICO: proxy_http_version 1.1 SOLO nei location SSE
# A livello server block causa 405 per tutti i POST!
location ~ ^/api/realtime {
    proxy_pass http://warehouse_service;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Connection '';
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 130s;
    chunked_transfer_encoding on;
}

Severity & Canali

SeverityIn-AppEmailSMS/Webhook
infoBadge
warningBadge + ToastOpzionale
criticalToast autoSempreOpzionale
emergencyToast + SoundSempreSempre
16

PWA & Service Worker

L'app operatore (operator.html) e il palmare (mobile.html) sono PWA installabili con Service Worker per caching offline.

Service Worker (app/sw.js)

js
// Strategia: cache-first per shell, network-only per API
const CACHE_NAME = 'wms-op-v2';
const SHELL_ASSETS = [
    '/operator.html', '/mobile.html',
    '/css/mobile.css', '/js/mobile.js',
    '/js/api.js',
    'https://cdnjs.cloudflare.com/.../all.min.css'
];

Installazione su Device

PiattaformaProcedura
Android (Chrome)Menu ⋮ → "Aggiungi a schermata Home" → Installa
iOS (Safari)Condividi ↑ → "Aggiungi a Home" → Aggiungi
Zebra/HoneywellUsare mobile.html (118 righe, ultraleggero) per schermi piccoli e connessioni lente
Aggiornamento SW: Cambiare CACHE_NAME (es. wms-op-v3) per forzare l'aggiornamento della cache su tutti i device. Il vecchio SW viene invalidato automaticamente.
17

Backup & Disaster Recovery

Backup Database (7 DB)

bash
# Backup completo tutti i 7 DB WMS
for db in wms_auth_db wms_inventory_db wms_warehouse_db wms_inbound_db wms_outbound_db wms_report_db wms_agile_db; do
    docker exec wms-mysql mysqldump -u wms_user -pWmsAgile2026! $db | \
        gzip > /backup/wms/${db}_$(date +%Y%m%d_%H%M).sql.gz
done
# Retention: 30 giorni
find /backup/wms -name "*.sql.gz" -mtime +30 -delete

Backup Qdrant (RAG vectors)

bash
# Snapshot Qdrant
curl -X POST http://127.0.0.1:6333/snapshots
# Copia snapshot dal volume Docker
docker cp wms-qdrant:/qdrant/snapshots/ /backup/wms/qdrant/

Disaster Recovery

bash
# 1. Restore database
gunzip -c /backup/wms/wms_inventory_db_20260325.sql.gz | \
    docker exec -i wms-mysql mysql -u wms_user -pWmsAgile2026! wms_inventory_db
# 2. Restart tutti i container
cd /var/www/wms-agile/infrastructure
COMPOSE_PROJECT_NAME=wms-agile docker compose \
    -f docker-compose.yml -f docker-compose.production.yml up -d
# 3. Re-indicizza RAG (i dati DB sono aggiornati, i vector devono seguire)
curl -X POST http://127.0.0.1:3087/api/ai/knowledge/auto-learn \
    -H "X-API-Key: YOUR_API_KEY"
curl -X POST http://127.0.0.1:3087/api/ai/knowledge/seed-wms \
    -H "X-API-Key: YOUR_API_KEY"
RTO / RPO: Con backup giornaliero, RPO = 24h max. Docker image cache + git pull: RTO < 30 minuti per full rebuild. Per RPO < 1h, configurare MySQL binlog replication su un server secondario.