Roadmap step-by-step per costruire il progetto in modo ordinato (senza saltare fasi).
Check basati sui file presenti nel workspace al momento.
- Modulo Go inizializzato in
go.mod(module micro-vuln-scanner). - Struttura cartelle base creata:
internal/{config,domain,httpapi,logger,service,simulator,store}. - Cartelle
pkgetestcreate. - Presenza di entrypoint root con
package maininmain.go. - Entrypoint applicativo in
cmd/api/main.goda allineare apackage main+ funzionemain. - Primo avvio applicazione riuscito (
go run ./cmd/api). - Domain model
Vulnerabilityimplementato (con Severity, Status, validazioni, JSON tag). - Store concorrente in-memory implementato (RWMutex, Add, GetAll, GetBySeverity, retention).
- Endpoint
GET /api/vulnerabilitiesimplementato. - Service layer
Vulnerabilityimplementato (filtro severity spostato dal handler). - Risposte API in JSON uniformate anche sugli errori.
- Simulazione real-time con ticker implementata (generazione attiva con graceful shutdown).
Obiettivo: sistemare la base del progetto Go e partire pulito.
- Verifica versione Go locale (
go version). - Conferma modulo in
go.mod(ok:micro-vuln-scanner). - Crea una branch dedicata (consigliato) per lavorare in sicurezza.
- Correggi il file entrypoint: il file eseguibile deve avere package
main. - Decidi struttura definitiva:
- Opzione A: tenere
api/main.go. - Opzione B (piu standard): usare
cmd/api/main.go.
- Esegui un primo avvio minimale (
go run ./apioppurego run ./cmd/api).
Done quando: il comando di run parte senza errori di package.
Obiettivo: separare chiaramente responsabilita.
- Crea/usa queste cartelle:
internal/domaininternal/storeinternal/serviceinternal/simulatorinternal/httpapiinternal/configinternal/loggerpkg/response(utility riusabili)
- Definisci naming coerente dei file (uno scopo chiaro per file).
- Tieni
main.gosolo come bootstrap (niente logica business dentro).
Done quando: la struttura e pronta e ogni package ha un ruolo preciso.
Obiettivo: modellare bene i dati prima della logica.
- Definisci
Vulnerabilitycon:
IDImageNameSeverity(Critical, High, Medium, Low)Status(Fixed, Unfixed)CreatedAt
- Definisci severity/status come valori chiusi (enum-like), non stringhe libere sparse.
- Crea funzioni di parse/validazione severity e status.
- Standardizza data in UTC e serializzazione coerente JSON.
Done quando: input invalidi vengono rifiutati subito e in modo prevedibile.
Obiettivo: evitare race condition tra API e simulatore.
- Implementa store in memoria con lock (
sync.RWMutex). - Metodi minimi:
- add vulnerability
- list all vulnerabilities
- list by severity
- In lettura restituisci copie dei dati, non riferimenti mutabili interni.
- (Opzionale ma consigliato) retention: mantieni solo ultime N vulnerabilities.
Done quando: lo store e sicuro in concorrenza.
Obiettivo: centralizzare business logic.
- Crea un service che usa lo store.
- Sposta qui logica di filtro, ordinamento e regole applicative.
- Definisci errori noti (es. severity non valida) in modo chiaro.
- Mantieni handlers HTTP sottili: niente logica pesante negli endpoint.
Done quando: il service e il punto unico di logica applicativa.
Obiettivo: generare vulnerabilita automaticamente ogni 5 secondi.
- Crea una goroutine con ticker configurabile (default 5s).
- A ogni tick genera una vulnerability casuale ma realistica.
- Inseriscila nello store tramite service.
- Gestisci stop pulito con context cancellation e
ticker.Stop().
Done quando: i dati crescono nel tempo senza memory leak di goroutine.
Obiettivo: esporre endpoint pulito e filtrabile.
- Implementa
GET /api/vulnerabilities. - Supporta query param
severity(case-insensitive). - Se severity non valida: risposta
400con errore JSON coerente. - Se ok: risposta
200con lista (anche vuota). - Aggiungi header corretti (
Content-Type: application/json).
Done quando: endpoint stabile e contratto API chiaro.
Obiettivo: mostrare maturita architetturale.
- Nel layer HTTP crea un context con timeout per la richiesta.
- Passa il context al service/store.
- Gestisci timeout/cancel con risposta errore comprensibile.
- Rendi timeout configurabile via env.
Done quando: la request non resta bloccata indefinitamente.
Obiettivo: servizio configurabile e osservabile.
- Configura via env vars:
- porta
- intervallo ticker
- timeout API
- max elementi retention (se usata)
- Aggiungi logging strutturato per:
- startup/shutdown
- nuova vulnerability generata
- richieste API (path, filtro, status, latenza)
- errori
Done quando: puoi capire facilmente cosa succede in runtime.
Obiettivo: dimostrare qualita tecnica in colloquio.
- Unit test su parse/validazione severity-status.
- Unit test su filtri del service.
- Test store concorrente.
- Test endpoint:
- senza filtro
- filtro valido
- filtro invalido
- Esegui race detector:
go test -race ./....
Done quando: test verdi + nessuna race rilevata.
Obiettivo: dashboard professionale e aggiornata automaticamente.
- Crea layout:
- Sidebar filtri severity
- Main area tabella/card
- Crea custom hook
useVulnerabilitiesper:
- fetch dati
- stato loading/error
- filtro selezionato
- polling ogni 5-10s
- Aggiungi badge/colori severity (critical rosso, high arancio, medium giallo, low verde/azzurro).
- Gestisci stati UI: loading, empty, error.
Done quando: UI reattiva e leggibile, senza reload pagina.
Obiettivo: collegamento robusto tra servizi.
- Configura URL API via env frontend.
- Gestisci CORS lato backend (solo per sviluppo locale).
- Verifica mapping campi JSON e formati data.
- Testa filtro sidebar -> query
?severity=....
Done quando: filtro frontend riflette correttamente i dati backend.
Obiettivo: avvio rapido in stile aziendale.
- Crea Dockerfile backend.
- Crea Dockerfile frontend.
- Crea
docker-compose.ymlcon 2 servizi:
- backend
- frontend
- Esponi porte e variabili ambiente necessarie.
- Avvia e verifica l'intero stack da compose.
Done quando: tutto parte con un solo comando.
- Il backend genera una vulnerability ogni 5s.
- L'endpoint API filtra severity correttamente.
- La dashboard aggiorna dati con polling.
- Colori e stati UI sono chiari.
- Test principali passano, incluso race detector.
- Avvio completo con Docker Compose.
- Sai spiegare in 60 secondi:
- separazione layer
- concorrenza con mutex
- context timeout
- custom hook frontend
- Step 0-1 (setup + struttura)
- Step 2-6 (backend core)
- Step 7-9 (bonus + test)
- Step 10-11 (frontend + integrazione)
- Step 12-13 (docker + rifinitura colloquio)
Se segui questo ordine, arrivi a una demo solida in tempi brevi e con una narrazione tecnica convincente.