diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..cc7a8fbe
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,62 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# Sample workflow for building and deploying a Jekyll site to GitHub Pages
+name: Deploy Jekyll site to Pages
+
+on:
+ push:
+ branches: ["main"]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+ group: "pages"
+ cancel-in-progress: true
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "3.2"
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+ cache-version: 0 # Increment this number if you need to re-download cached gems
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v3
+ - name: Build with Jekyll
+ # Outputs to the './_site' directory by default
+ run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
+ env:
+ JEKYLL_ENV: production
+ - name: Upload artifact
+ # Automatically uploads an artifact from the './_site' directory by default
+ uses: actions/upload-pages-artifact@v2
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.github/workflows/formatting-validation.yml b/.github/workflows/formatting-validation.yml
index e7125723..f2fd0820 100644
--- a/.github/workflows/formatting-validation.yml
+++ b/.github/workflows/formatting-validation.yml
@@ -8,9 +8,9 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
with:
node-version: 18
- name: Prettier Check
- run: npm run format:check
\ No newline at end of file
+ run: npm run format:check
diff --git a/.gitignore b/.gitignore
index 65ff902c..63bbf0d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,6 @@ dist/
.env
.env.*
!.env.example
+
+# Site
+_site
diff --git a/.prettierrc b/.prettierrc
index 6e59ae61..a61d7fb5 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,4 +1,5 @@
{
"singleAttributePerLine": true,
- "trailingComma": "es5"
+ "trailingComma": "es5",
+ "endOfLine": "lf"
}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 593fc24b..1782aec5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,20 +1,59 @@
# Come contribuire al repository
-## Prima installazione
+## Benvenuto!
-Dopo aver clonato il progetto:
+Grazie per aver deciso di contribuire al progetto!
+In questa pagina troverai tutte le informazioni necessarie per poter contribuire al progetto in varie forme.
-```bash
-npm i
-```
+## In che modo posso contribuire?
+
+Per contribuire nella stesura del libro puoi fare una qualsiasi delle seguenti attività.
+
+### Proporre un nuovo capitolo
+
+Se hai un'idea per un capitolo, puoi proporla aprendo una nuova issue.
+Github ti proporrà un template per la creazione della issue, che ti suggeriamo di utilizzare.
+Inserisci quante più informazioni possibili e specifica se vorresti occuparti interamente della prima stesura o se invece vorresti produrre il contenuto in collaborazione con altri contributori.
+
+Una volta aperta la issue, verrà automaticamente assegnata una label `nuovo-capitolo`.
+A questo punto, un qualsiasi Ambassador potrebbe decidere di _assegnare_ a se stesso la issue. Ti consigliamo di pubblicizzare la tua idea in ogni modalità a te possibile e/o contattare eventuali Ambassador di tua conoscenza per chiedere loro di dare un'occhiata alla tua proposta e valutare la possibilità di _assegnare_ la issue a se stessi.
+
+Nel momento in cui un Ambassador deciderà di _assegnare_ la issue a se stesso, un branch verrà creato in maniera automatica e il lavoro di stesura potrà cominciare.
+
+Prosegui nella lettura di questa pagina alla voce [Modalità di stesura di un capitolo](#modalità-di-stesura-di-un-capitolo) per capire come procedere da qui.
+
+### Proporre una modifica ad un capitolo esistente
+
+Se hai un'idea per migliorare un capitolo esistente, puoi proporla aprendo una nuova issue.
+Github ti proporrà un template per la creazione della issue, che ti suggeriamo di utilizzare.
+In alternativa, potresti aprire direttamente una Pull Request, ma ti consigliamo di aprire una issue per discutere prima della modifica da apportare e capire se la tua idea è condivisa dalla community.
+
+### Modalità di stesura di un capitolo
+
+Bene, hai individuato un capitolo a cui contribuire / da modificare e vuoi cominciare a scrivere dei contenuti. Ma come?
+
+Le modalità di stesura del capitolo sono principalmente due:
-per installare le librerie
+- In accordo con la persona del team Ambassador assegnataria del capitolo di interesse, potrete decidere di mettervi in contatto per lavorare insieme alla stesura del capitolo. In questo caso, potrete decidere di utilizzare un qualsiasi strumento di scrittura collaborativa (Google Docs, Office 365, ecc.) e di caricare il contenuto nel branch una volta terminato. Per comodità, si suggerisce di lasciare alla figura di Ambassador il compito di caricare il contenuto nel repository rimuovendo la necessità di una ulteriore Pull Request.
-## Formattazione
+- In accordo con la persona del team Ambassador assegnataria del capitolo, potrai stendere in prima battuta il contenuto del capitolo e far sì che la persona assegnataria ti faccia da revisore e guida. In questo caso, sarà necessario fare un fork del branch relativo al capitolo e aprire una Pull Request che dovrà puntare a quello stesso branch come destinazione.
+ Una volta aperta la Pull Request, la persona assegnataria del capitolo potrà iniziare a revisionare il contenuto e a suggerire modifiche.
+ Una volta terminato il lavoro, la persona assegnataria del capitolo aprirà una Pull Request (o modificherà quella già presente da `draft` a `ready for review`) e chiederà una revisione al resto della community. Le regole di approvazione dei contenuti sono regolate dal Governance Group del progetto e sono disponibili [qui](https://github.com/Il-Libro-Open-Source/book/blob/main/GUIDELINES-CONTENUTI.md).
+
+## Scrivere i contenuti
+
+I contenuti del libro sono scritti in formato markdown e sono organizzati in cartelle e file.
+Sarà sufficiente avere una qualsiasi versione di Node.js installata sul proprio computer per poter formattare i file markdown in maniera automatica e un qualsiasi IDE per la stesura.
+
+### Prima installazione
+
+Dopo aver clonato il progetto ed essendosi spostati sul branch relativo al capitolo di interesse, eseguire il comando `npm i` per installare le librerie.
+
+### Formattazione
Tutti i file markdown devono essere formattati con [Prettier](https://prettier.io/) per una miglior leggibilità e per evitare inutili merge conflict se più persone lavorano allo stesso file.
-Per formattare da linea di comando tutti i file è necessario avere [Node](https://nodejs.org/it) installato sul proprio computer e lanciare il seguente comando nella cartella del repository:
+Per formattare da linea di comando tutti i file è sufficiente lanciare il seguente comando nella cartella del repository:
```bash
npm run format:write
@@ -22,13 +61,29 @@ npm run format:write
Fortunatamente i principali IDE supportano Prettier tramite delle estensioni, di seguito alcuni esempi:
-### Visual Studio Code
+#### Visual Studio Code
Per formattare i file markdown con Visual Studio Code è necessario installare l'estensione [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode).
Un buon consiglio è tenere attivo il flag `Format On Save` direttamente nelle impostazioni di vscode per evitare di dover formattare ogni volta a mano.
-## Conventional commits
+#### JetBrains IDE (WebStorm, IntelliJ, ecc.)
+
+Per formattare i file markdown con IDE JetBrains è necessario installare l'estensione [Prettier](https://plugins.jetbrains.com/plugin/10456-prettier), tranne per WebStorm che include già Prettier di default.
+
+Alcuni suggerimenti di configurazione si possono trovare [qui](https://prettier.io/docs/en/webstorm).
+
+#### Vim
+
+Per formattare i file markdown con Vim è necessario installare il plugin [vim-prettier](https://github.com/prettier/vim-prettier).
+
+Alcuni suggerimenti di configurazione si possono trovare [qui](https://prettier.io/docs/en/vim).
+
+#### Altri IDE
+
+Nella documentazione di Prettier sono presenti le istruzioni per configurare il tool nel proprio IDE preferito: [Editor Integration](https://prettier.io/docs/en/editors).
+
+### Conventional commits
Per mantenere uno storico e poter costruire dei changelog è richiesto a tutti i contributori del progetto di utilizzare i [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
In pratica è necessario utilizzare dei prefissi per i commit che indicano il tipo di commit e il contesto, ad esempio:
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000..9c084501
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem "just-the-docs"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000..f50ae961
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,84 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.8.6)
+ public_suffix (>= 2.0.2, < 6.0)
+ colorator (1.1.0)
+ concurrent-ruby (1.2.3)
+ em-websocket (0.5.3)
+ eventmachine (>= 0.12.9)
+ http_parser.rb (~> 0)
+ eventmachine (1.2.7)
+ ffi (1.16.3)
+ forwardable-extended (2.6.0)
+ google-protobuf (3.25.2-x86_64-darwin)
+ google-protobuf (3.25.2-x86_64-linux)
+ http_parser.rb (0.8.0)
+ i18n (1.14.1)
+ concurrent-ruby (~> 1.0)
+ jekyll (4.3.3)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ em-websocket (~> 0.5)
+ i18n (~> 1.0)
+ jekyll-sass-converter (>= 2.0, < 4.0)
+ jekyll-watch (~> 2.0)
+ kramdown (~> 2.3, >= 2.3.1)
+ kramdown-parser-gfm (~> 1.0)
+ liquid (~> 4.0)
+ mercenary (>= 0.3.6, < 0.5)
+ pathutil (~> 0.9)
+ rouge (>= 3.0, < 5.0)
+ safe_yaml (~> 1.0)
+ terminal-table (>= 1.8, < 4.0)
+ webrick (~> 1.7)
+ jekyll-include-cache (0.2.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-sass-converter (3.0.0)
+ sass-embedded (~> 1.54)
+ jekyll-seo-tag (2.8.0)
+ jekyll (>= 3.8, < 5.0)
+ jekyll-watch (2.2.1)
+ listen (~> 3.0)
+ just-the-docs (0.7.0)
+ jekyll (>= 3.8.5)
+ jekyll-include-cache
+ jekyll-seo-tag (>= 2.0)
+ rake (>= 12.3.1)
+ kramdown (2.4.0)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ liquid (4.0.4)
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ mercenary (0.4.0)
+ pathutil (0.16.2)
+ forwardable-extended (~> 2.6)
+ public_suffix (5.0.4)
+ rake (13.1.0)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ rexml (3.2.6)
+ rouge (4.2.0)
+ safe_yaml (1.0.5)
+ sass-embedded (1.70.0-x86_64-darwin)
+ google-protobuf (~> 3.25)
+ sass-embedded (1.70.0-x86_64-linux-gnu)
+ google-protobuf (~> 3.25)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ unicode-display_width (2.5.0)
+ webrick (1.8.1)
+
+PLATFORMS
+ x86_64-darwin-22
+ x86_64-linux
+
+DEPENDENCIES
+ just-the-docs
+
+BUNDLED WITH
+ 2.3.26
diff --git a/README.md b/README.md
index 88a2d1da..e500b209 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,30 @@
Questo progetto nasce da un post su LinkedIn che ha raccolto decine di persone attorno all'obiettivo di realizzare un libro completamente Open Source.
Dalla scelta del tema alla stesura del contenuto, il tutto verrà gestito e condiviso con la community e con chiunque voglia contribuire al progetto.
+## Vuoi leggerlo?
+
+Il libro è e sarà sempre disponibile online in maniera Open Source. Vuoi leggerlo? [Clicca qui!](https://il-libro-open-source.github.io/book/)
+
## Come contribuire
Puoi contribuire al progetto in moltissimi modi.
Il primo è certamente quello di mettere una stella e di condividere il progetto con chiunque tu conosca.
Il secondo è quello di contribuire attivamente al progetto, scrivendo, traducendo, revisionando, disegnando, ecc.
Durante la vita del progetto saranno aperte discussioni, sondaggi, pull requests e issue per permettere a chiunque di contribuire in maniera attiva al progetto.
-Inoltre, puoi diventare un Ambassador del progetto, che ti permetterà di avere un ruolo attivo nella gestione del progetto stesso. Vedi la sezione [Ambassadors](#ambassadors) per maggiori informazioni.
-Maggiori dettagli [qui](CONTRIBUTING.md).
+Trovi maggiori informazioni nella sezione [Come contribuire](CONTRIBUTING.md).
+
+### Contributor
+
+Puoi anche diventare un Contributor del progetto, che ti permetterà di avere un ruolo attivo nella gestione del progetto stesso.
+
+Visita la sezione [Membership](https://github.com/Il-Libro-Open-Source/governance/blob/main/MEMBERSHIP.md) per maggiori informazioni.
+
+### Ambassador
+
+Chi ricopre il ruolo di Ambassador?
+Coloro che hanno deciso di contribuire al progetto in maniera diretta, prendendosi la responsabilità di uno o più capitoli, oppure di altre aree come la grafica, la traduzione, la revisione, ecc.
+
+Visita la sezione [Membership](https://github.com/Il-Libro-Open-Source/governance/blob/main/MEMBERSHIP.md) per maggiori informazioni.
## Codice di condotta
@@ -22,15 +38,9 @@ Il tema del libro è: "Il Manuale Del Buon Dev", un compendio di buone pratiche
## Quali sono i capitoli del libro?
-I capitoli del libro sono ancora in fase di definizione e puoi dire la tua a riguardo [qui](https://github.com/Il-Libro-Open-Source/book/discussions/3).
+I capitoli del libro sono costantemente in fase di definizione.
+Trovi i capitoli già presi in considerazione o già in fase di stesura [qui](https://github.com/Il-Libro-Open-Source/book/labels/nuovo-capitolo), proporne uno nuovo aprendo una nuova isse o puoi trarre ispirazione nella [discussione apposita](https://github.com/Il-Libro-Open-Source/book/discussions/3).
## Dove posso scrivere le mie idee?
-Nella discussione [Idee sparse](https://github.com/Il-Libro-Open-Source/book/discussions/27) o nella discussione [Brainstorming](https://github.com/Il-Libro-Open-Source/book/discussions/1).
-
-## Ambassadors
-
-Chi sono gli Ambassador?
-Sono coloro che hanno deciso di contribuire al progetto in maniera diretta, prendendosi la responsabilità di uno o più capitoli, oppure di altre aree come la grafica, la traduzione, la revisione, ecc.
-Ad Agosto sono partite le prime votazioni per il ruolo di Ambassador.
-Per saperne di più, visita la pagina dedicata: [Ambassadors](AMBASSADORS.md).
+Nella discussione [Idee sparse](https://github.com/Il-Libro-Open-Source/book/discussions/27) o aprendo una issue senza template.
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 00000000..7f10857b
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,20 @@
+title: Il Libro Open Source
+
+theme: just-the-docs
+baseUrl: "/book"
+url: "https://il-libro-open-source.github.io"
+
+permalink: pretty
+
+search_enabled: true
+
+back_to_top: true
+back_to_top_text: "Torna all'inizio"
+
+footer_content: "Copyright © 2023-2024 Il Libro Open Source"
+
+gh_edit_link: true
+gh_edit_link_text: "Contribuisci a questo contenuto su GitHub."
+gh_edit_repository: "https://github.com/Il-Libro-Open-Source/book"
+gh_edit_branch: "main"
+gh_edit_view_mode: "tree"
\ No newline at end of file
diff --git a/_includes/head_custom.html b/_includes/head_custom.html
new file mode 100644
index 00000000..416bbdd6
--- /dev/null
+++ b/_includes/head_custom.html
@@ -0,0 +1,17 @@
+
diff --git a/assets/images/piramide.svg b/assets/images/piramide.svg
new file mode 100644
index 00000000..2658d4f4
--- /dev/null
+++ b/assets/images/piramide.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
index e71fb657..00000000
--- a/docs/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-title: Il Libro Open Source
diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
index ece22a27..00000000
--- a/docs/index.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## Indice del libro
-
-- [Introduzione](./it/introduzione.md)
-- [Cosa significa essere Dev](./it/cosa-significa-essere-dev.md)
-- [Testing](./it/testing.md)
diff --git a/docs/it/architetture-software.md b/docs/it/architetture-software.md
new file mode 100644
index 00000000..57f38bd5
--- /dev/null
+++ b/docs/it/architetture-software.md
@@ -0,0 +1,259 @@
+---
+layout: default
+title: Architettura software
+nav_order: 3
+---
+
+# Architetture Software
+
+Il termine "architettura software" viene spesso utilizzato in maniera molto generica e impropria. In questo documento cercheremo di dare una definizione e di descriverne le principali.
+
+Inoltre, cercheremo di dare un'idea di "chi si occupa di architetture software" e di descrivere il suo ruolo all'interno di un team di sviluppo.
+
+L'argomento è molto vasto e complesso, per cui proveremo a dare una visione generale, senza entrare troppo nel dettaglio, in quanto ogni singola sezione di questo capitolo potrebbe concretizzarsi in un libro a sé stante.
+
+## Cos'è l'architettura software?
+
+Wikipedia ci dà uno spunto di partenza:
+
+> L'architettura software è l'insieme delle strutture necessarie per ragionare su un sistema software e la disciplina per creare tali strutture e sistemi. Ogni struttura comprende elementi software, relazioni tra loro e proprietà di entrambi gli elementi e delle relazioni.
+
+In altre parole, l'architettura software è l'insieme di tutte le decisioni prese durante la progettazione di un sistema software.
+
+## I diversi aspetti dell'architettura software
+
+L'architettura software è un argomento molto vasto e complesso, ma possiamo identificare alcuni punti chiave che si applicano nella maggior parte dei casi:
+
+- **Componenti e moduli**: identificano i principali componenti o moduli del software e descrivono le loro responsabilità. Questi componenti possono essere funzioni, classi o persino interi microservizi in un sistema distribuito.
+- **Flusso e comunicazione dei dati**: descrive il modo in cui i dati attraversano le diverse parti del sistema, inclusi meccanismi di input e output, database e servizi esterni. Comprendere il flusso di dati è fondamentale per garantire una comunicazione e un'elaborazione efficiente dei dati.
+- **Comportamento del sistema**: definisce il comportamento previsto del software in varie condizioni, incluso il modo in cui vengono gestiti gli errori, ripristinati i guasti e organizzati gli adattamenti per far fronte all'aumento del carico.
+- **Attributi di qualità**: soddisfano i requisiti non funzionali, come prestazioni, sicurezza, scalabilità e manutenibilità. Le decisioni di progettazione per ottimizzare il software vengono prese in funzione di queste qualità.
+- **Vincoli e modelli**: l'architettura software spesso opera entro determinati vincoli, come budget, stack tecnologico o standard di conformità. Chi si occupa dell'architettura sfrutta i modelli di progettazione e le migliori pratiche per soddisfare questi vincoli, ottenendo al tempo stesso la funzionalità desiderata.
+
+In sostanza, l'architettura software fornisce un approccio strutturato alla costruzione di sistemi software complessi, garantendo che siano scalabili, manutenibili e in grado di soddisfare i requisiti e gli standard di qualità previsti. È una disciplina cruciale nell'ingegneria del software che aiuta chi sviluppa a prendere decisioni informate e a creare software che resistano alla prova del tempo.
+
+## Il contesto aziendale
+
+Chi si occupa di architetture software non può vivere in una bolla e non può esulare dal contesto aziendale nel quale si trova: ogni progetto va contestualizzato tenendo conto di queste caratteristiche durante la fase di progettazione per rendere l'implementazione più semplice.
+
+Essere quindi in grado di ascoltare e recepire le richieste e i cambiamenti del business e saper rispecchiare il tutto nel proprio lavoro quotidiano è fondamentale per prendere decisioni coerenti e creare architetture efficaci.
+
+L'architettura software gioca un ruolo fondamentale nel plasmare non solo gli aspetti tecnici di un sistema software ma anche l'organizzazione e la cultura più ampia all'interno della quale viene sviluppato e mantenuto. Un'architettura software ben progettata può favorire una cultura organizzativa positiva in diversi modi. In primo luogo, può promuovere la collaborazione e la comunicazione tra i team di sviluppo fornendo un modello chiaro della struttura e dei componenti del sistema. Quando i membri del team hanno una comprensione condivisa dell'architettura, diventa più facile per loro lavorare insieme in modo efficace, allineare i propri sforzi e prendere decisioni informate, promuovendo una cultura del lavoro di squadra e della cooperazione.
+
+Inoltre, l'architettura del software può seguire la strategia e gli obiettivi generali dell'organizzazione. Un'architettura ben ponderata può garantire che il sistema software sia allineato con gli obiettivi aziendali, rendendo più facile per l'organizzazione adattarsi alle mutevoli condizioni del mercato e alle esigenze dei clienti. Questo allineamento tra software e obiettivi aziendali può aiutare a promuovere una cultura agile e reattiva, in cui l'organizzazione è più propensa ad abbracciare il cambiamento e l'innovazione.
+
+In sintesi, l'architettura software non rappresenta solo un aspetto tecnico ma è un potente strumento in grado di plasmare la cultura dell'organizzazione. Quando si progetta tenendo conto della collaborazione, della comunicazione e in funzione degli obiettivi aziendali, si può promuovere una cultura del lavoro di squadra, dell'adattabilità e dell'innovazione all'interno dell'organizzazione, contribuendo in definitiva al successo dei progetti di sviluppo software e dell'azienda nel suo insieme.
+
+## Chi si occupa di architetture software?
+
+Chi si occupa di architettura del software è di solito una persona con una certa esperienza nel campo dell'ingegneria del software, ed è responsabile della progettazione e della supervisione della struttura di alto livello e della visione tecnica di un progetto o sistema software. Queste figure sono fondamentali per colmare il divario tra i requisiti concettuali di una soluzione software e la sua diretta implementazione. Il ruolo va oltre il codice: implica prendere decisioni strategiche sulla progettazione del sistema, garantire che sia in linea con gli obiettivi dell'organizzazione e ottimizzarlo in base ai vincoli prestabiliti.
+
+Di seguito le caratteristiche chiave che chi ricopre questo ruolo dovrebbe avere:
+
+- **Competenza tecnica**: questa figura dovrebbe avere una profonda conoscenza di vari linguaggi di programmazione, metodologie di sviluppo software e modelli architetturali. Deve rimanere aggiornata con le tecnologie emergenti e le tendenze nell'ingegneria del software. Seppure ci siano varie opinioni sulla necessità di conoscere più di un linguaggio di programmazione, è indubbio che conoscerne più di uno possa aiutare a trovare soluzioni più efficaci in modo particolare se aiuta la comprensione dei limiti che i vari contesti pongono.
+- **Attitudine al problem-solving**: sono essenziali forti capacità analitiche e di risoluzione dei problemi. Questa figura deve analizzare problemi complessi, identificare soluzioni e prendere decisioni che incidono sulla progettazione complessiva del sistema.
+- **Capacità di comunicazione**: una comunicazione efficace è fondamentale poiché le persone che ricoprono questo ruolo devono collaborare con team interfunzionali, parti interessate e con il team di sviluppo. Devono articolare la propria visione, le scelte progettuali e i concetti tecnici alle parti interessate non tecniche, facendo da ponte tra i due mondi.
+- **Leadership**: Queste figure spesso assumono ruoli di leadership, guidando i team di sviluppo, facendo da mentor a figure junior e garantendo che la visione architetturale venga seguita durante tutto il ciclo di vita del progetto.
+- **Design Thinking**: Le persone che ricoprono questo ruolo dovrebbero possedere una mentalità orientata al design, concentrandosi sulla creazione di soluzioni eleganti ed efficienti. Ciò include la progettazione per scalabilità, prestazioni, sicurezza ed esperienza utente.
+- **Business thinking**: comprendere il contesto di business aziendale e gli obiettivi che l'azienda si è posta di raggiungere. Queste figure devono allineare le loro decisioni tecniche con gli obiettivi strategici dell'organizzazione.
+- **Adattabilità**: il panorama del software è in continua evoluzione. La figura dovrebbe essere aperta e adattarsi a nuove tecnologie e metodologie e capace di rivalutare e riadattare l'architettura quando necessario, non solo per necessità tecniche, ma anche per rispondere ai cambiamenti del mercato e per soddisfare le esigenze dei clienti.
+
+Sebbene sia vero che il ruolo viene ricoperto da persone con una certa esperienza, non è detto che una figura junior non possa occuparsi di architetture software. Anzi, è molto importante che lo faccia, in quanto è un ottimo modo per imparare e crescere, ma il consiglio è di iniziare in un contesto controllato, più piccolo in modo da poter sperimentare meglio. L'affiancamento di una figura senior che possa guidare è sicuramente di aiuto per una persona junior.
+
+## Misurare la bontà di un'architettura
+
+Il termine _fitness function_ viene spesso adottato quando si parla di architetture evolutive, ovvero architetture software il cui scopo è quello di evolvere nel tempo, adattandosi ai cambiamenti del business e del mercato. Possono essere assimilabili a delle metriche che permettono di valutare quanto un'architettura software sia adatta a raggiungere gli obiettivi prefissati o ad eventuali obiettivi futuri del business.
+
+Apiumhub nel 2020 ha pubblicato un [post](https://apiumhub.com/tech-blog-barcelona/architectural-fitness-function) sul proprio blog in cui definisce questo concetto in maniera molto chiara:
+
+> La _fitness function_ è un tipo di funzione obiettivo utilizzata per riassumere quanto una determinata soluzione di architettura software sia vicina al raggiungimento degli obiettivi prefissati. Nel definire un'architettura evolutiva, l'architetto del software cerca un algoritmo "migliore"; la funzione fitness definisce cosa significa "migliore" in questo contesto.
+
+Esempi di fitness function possono essere: punteggio di scalabilità, percentuale di errori, tempo medio di risposta, quantità di messaggi persi dal broker, ecc.
+
+Poiché gli obiettivi prefissati di un'architettura variano da progetto a progetto, non esiste una _fitness function_ che è possibile usare ovunque. Di seguito diamo alcune idee di implementazione.
+
+### Triggered Fitness function
+
+Le _triggered fitness function_ (funzioni di fitness _attivate_ o _triggerate_) vengono eseguite in base a un evento particolare, ad esempio il team di sviluppo che esegue un test unitario, una pipeline di distribuzione che esegue una serie di operazioni o una persona del QA che esegue determinate attività stabilite.
+
+Questo tipo di funzioni ha da un lato il vantaggio di poter essere eseguito in maniera molto rapida, ma dall'altro lato ha il difetto di non essere rappresentativo di una situazione reale. Infatti, questo tipo di fitness function non tiene in considerazione il carico di lavoro che il sistema deve gestire durante il _day-by-day_, ma solo situazioni isolate e controllate.
+
+Queste funzioni di fitness vengono spesso lanciate durante una _pipeline_ di distribuzione, in modo da intercettare eventuali variazioni prima che il software venga rilasciato in produzione.
+
+Questo tipo di _fitness function_ richiede solitamente più manutenzione rispetto alle _continuous fitness function_, poiché deve essere adattato durante la vita del software, in base alle modifiche che vengono apportate.
+
+Alcuni esempi sono i test unitari, i test di integrazione, ecc.
+
+### Continuous Fitness function
+
+Le _continuous fitness function_ (funzioni di fitness _continue_) vengono eseguite in modo continuo sull'ambiente in analisi, tramite raccolta di metriche in tempo reale o comunque a cadenze rapide. Questo tipo di funzioni di fitness sono utili per monitorare il sistema e rilevare eventuali problemi prima che si verifichino, o analizzare dei trend.
+
+Questo tipo di funzioni ha da un lato il vantaggio di rappresentare la situazione reale, dall'altro lato ha il difetto di non essere replicabile, in quanto si basa su dati presi dall'ambiente che si sta analizzando (solitamente quello di produzione).
+
+Queste funzioni di fitness vengono spesso lanciate in un ambiente di produzione, in modo da avere contezza del reale contesto nel quale vengono eseguite.
+
+Alcuni esempi sono il monitoraggio dei tempi medi di risposta, il monitoraggio dei messaggi inviati e ricevuti in una coda, ecc.
+
+## Quali sono le principali architetture software?
+
+Esistono diverse architetture software, ognuna con i suoi pro e i suoi contro. In questa parte del libro, descriviamo le principali architetture software che, nel corso dei decenni, sono diventate uno standard de facto grazie alle loro molteplici implementazioni e casi di successo.
+
+Per scegliere quale architettura usare in diversi contesti, possiamo fare riferimenti alle seguenti caratteristiche:
+
+- **Start-up**: Il tempo necessario per definire l'architettura software e cominciare a sviluppare funzionalità. Tale tempo non è da sottovalutare poiché potrebbe richiede, in base al contesto aziendale, una serie di procedure che possono essere automatizzate da tools come le `platform engineering tools`.
+- **Costi**: Il costo che si affronta nell'arco della vita di un progetto o un prodotto che implementi questa architettura. Da considerare che nell'effettiva valutazione dei costi bisogna differenziare eventuali costi di avvio, da pagare una tantum, da costi ricorrenti, da pagare periodicamente per la manutenzione.
+- **Sviluppo e manutenzione**: La facilità con il quale è possibile effettuare modifiche e manutenzione al software. Per semplicità, anche l'aspetto del testing viene incluso in questo punto.
+- **Tracciabilità**: La facilità con la quale è possibile individuare problemi o bug all'interno del software.
+- **Scalabilità**: La facilità con la quale è possibile scalare il software, ovvero la capacità di gestire un carico di lavoro maggiore. Questo punto non fa riferimento alla scalabilità orizzontale o a quella verticale e non tiene conto dei costi, ma dell'impegno tecnico necessario per scalare il software.
+- **Performance**: La velocità con la quale il software è in grado di elaborare i dati per rispondere ad un'esigenza di business.
+
+Questi punti chiave sono da intendersi come una valutazione soggettiva, in quanto ogni architettura software può essere implementata in modi diversi, con conseguenze diverse, valutando criteri e parametri differenti in base alle proprie necessità e, pur essendo un elenco piuttosto esaustivo, mix di queste architetture hanno dimostrato di essere vincenti in molti casi, anche a discapito di quanto riportato qui sopra.
+
+I punti chiave sono espressi con dei voti che vanno da 1 a 5, dove 1 è il voto più basso e 5 il voto più alto. Per _alto_ si intende il valore migliore per il punto chiave in questione, mentre per _basso_ si intende il valore peggiore per il punto chiave in questione, ovvero il valore che si vorrebbe evitare. Nel caso di _costi_, ad esempio, un voto alto significa che i costi sono bassi, mentre un voto basso significa che i costi sono alti.
+
+Segue una tabella riepilogativa dei punti di forza e di debolezza di ogni architettura.
+
+| | **Monolite** | **Monolite modulare** | **Microkernel** | **Microservizi** | **Service-based** |
+| --------------------------- | --------------- | --------------------- | --------------- | ---------------- | ----------------- |
+| **Start-up** | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ |
+| **Costi** | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Sviluppo e manutenzione** | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ |
+| **Tracciabilità** | ⭐️⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Scalabilità** | ⭐️ | ⭐️ | ⭐️⭐️ | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+| **Performance** | ⭐️⭐️ | ⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️⭐️ |
+
+Nelle sezioni che seguono verranno indicati alcuni termini che possono non essere familiari a tutti. Per questo motivo, quanto segue è un glossario dei termini più utilizzati.
+
+Quando parliamo di _scalabilità verticale_ ci riferiamo all'incremento delle risorse hardware a disposizione del sistema (CPU, RAM, storage, ecc.) quando queste non sono più sufficienti per gestire il carico di lavoro.
+
+Quando parliamo di _scalabilità orizzontale_ ci riferiamo alla replicazione dei componenti del sistema, in modo da poter gestire un carico di lavoro maggiore. Le tecniche di scalabilità orizzontale sono varie e possono essere implementate in modi diversi, in base alle esigenze del sistema.
+
+Quando parliamo di _layer applicativi_ ci riferiamo a un livello di astrazione del software. Il database, le API, il front-end, ecc. sono tutti layer del software.
+
+### Monolite
+
+Il monolite è un'architettura software in cui tutte le funzionalità sono sviluppate e distribuite come un singolo pacchetto. È il tipo di architettura più semplice da implementare, in quanto non richiede particolari accorgimenti per la comunicazione tra i vari componenti, dal momento che questi ultimi risiedono all'interno dello stesso applicativo.
+
+Trattasi dell'architettura software più semplice da implementare e più diffusa, ma anche la più difficile da scalare, in quanto non è possibile replicare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_.
+
+Solitamente questa architettura viene identificata anche come _Layered Architecture_.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+È importante notare che storicamente questa architettura è spesso risultata la più sensibile al concetto di _stratificazione del codice_, ovvero il continuo sviluppo di funzionalità una sopra l'altra in sostituzione o sovrapposizione di precedenti, rendendo il codice sempre più complesso e difficile da mantenere. Questo fenomeno è stato spesso chiamato _Big Ball of Mud_.
+
+- **Start-up**: 5. Il monolite è l'architettura software più semplice da implementare, in quanto non richiede particolari accorgimenti per la comunicazione tra i vari componenti o una necessità di valutazioni iniziali elevate. Molti linguaggi di programmazione, inoltre, offrono dei framework che permettono di implementare un monolite in pochi minuti. Fra i principali framework troviamo Ruby on Rails, Django, Spring Boot, Laravel, ecc.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 4. Il monolite è tra le architetture software più semplici da sviluppare e mantenere, per gli stessi motivi espressi nella voce _start-up_. I framework sono ormai molto maturi e permettono di sviluppare e mantenere un monolite in maniera molto semplice.
+- **Tracciabilità**: 4. Poiché tutti i componenti fanno parte dello stesso processo o blocco, è facile individuare la porzione di codice che ha generato un problema o un bug.
+- **Scalabilità**: 1. Il monolite è tra le architetture software più difficili da scalare, in quanto non è possibile replicare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_. La valutazione è dovuta alla necessità, nella maggior parte delle implementazioni di questo tipo, di dover riavviare il sistema per scalare le risorse hardware.
+- **Performance**: 2. La performance del monolite è legata alla capacità di scalare le risorse hardware a disposizione del sistema. Di conseguenza, la curva di crescita dei tempi di risposta tende a crescere sempre di più. Solitamente le performance, seppur buone nelle prime fasi di vita del software, tendono a degradare nel tempo.
+
+### Monolite Modulare
+
+Il monolite modulare è un'architettura software in cui tutte le funzionalità sono sviluppate e distribuite come un singolo pacchetto, ma con la differenza che il codice è organizzato in moduli. Questi moduli possono essere sviluppati e distribuiti in maniera indipendente, ma sono comunque parte dello stesso _blocco_, inteso che l'applicativo online è unico, come nel caso del monolite _classico_.
+
+I moduli devono essere quanto possibile indipendenti tra di loro in modo da avere una suddivisione delle funzionalità segregata. La forza di questa architettura è comunque la possibilità, seppur da tenere sotto controllo, di far comunicare tra di loro i moduli tramite delle interfacce pubbliche.
+
+Da non confondersi con altre architetture, in questo caso i moduli sono parte dello stesso processo o applicativo, rendendo necessaria la _scalabilità verticale_.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+- **Start-up**: 4. Essendo una variante del monolite, lo start-up è molto semplice, ma la necessità di organizzare il codice in moduli può richiedere un po' di tempo.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 5. Rispetto a un monolite _classico_, il monolite modulare è più semplice da sviluppare e mantenere, in quanto i moduli hanno un compito ben definito e sono quanto più possibile indipendenti tra di loro.
+- **Tracciabilità**: 2. Compattando i moduli in un unico blocco, è più difficile individuare la porzione di codice che ha generato un problema o un bug in quanto solitamente il codice dei singoli moduli viene minificato o comunque ottimizzato per la produzione.
+- **Scalabilità**: 1. Il monolite, anche in forma modulare, è l'architettura software più difficile da scalare, in quanto non è possibile scalare i singoli componenti, ma è necessario scalare l'intero sistema. In questi casi, infatti, al monolite viene affiancato il concetto di _scalabilità verticale_. La valutazione è dovuta alla necessità, nella maggior parte delle implementazioni di questo tipo, di dover riavviare il sistema per scalare le risorse hardware.
+- **Performance**: 1. La performance del monolite modulare presenta le stesse problematiche del monolite _classico_, con l'aggiunta che per far funzionare questa architettura è necessario un ulteriore livello di astrazione, ovvero il modulo, che può portare ad un degrado delle performance.
+
+## Microkernel
+
+Chiamata anche _architettura a plugin_, si compone essenzialmente di un nucleo centrale che si occupa di gestire le comunicazioni tra i vari componenti, che sono sviluppati e distribuiti come plugin.
+Questi plugin possono essere sviluppati e distribuiti in maniera indipendente, ma funzionando attorno ad un nucleo centrale, faranno sempre parte dello stesso _blocco_, inteso che l'applicativo online è unico, come nel caso del monolite _classico_.
+
+Il concetto principale attorno a questa architettura è l'indipendenza totale tra i plugin. Per definizione, nessun plugin dovrebbe avere come dipendenza un altro plugin.
+
+In questa architettura i layer applicativi sono tutti parte dello stesso applicativo.
+
+- **Start-up**: 4. Essendo una variante del monolite, lo start-up è molto semplice, ma la necessità di organizzare il codice in un nucleo centrale e implementare un sistema di plugin può richiedere più tempo.
+- **Costi**: 3. Pur essendo un'architettura _a basso costo_ in termini di start-up, il costo cresce esponenzialmente per via della necessità di _scalare orizzontalmente_.
+- **Sviluppo e manutenzione**: 4. Trattasi di un'architettura semplice da mantenere e sulla quale aggiungere funzionalità, ma la necessità di non far comunicare i plugin tra di loro può aggiungere una lieve complessità.
+- **Tracciabilità**: 3. Testare e tracciare eventuali bug in questa architettura è mediamente complesso. L'isolamento dei plugin aiuta con il testing, ma la correlazione col nucleo centrale a volte può rallentare il processo di tracciamento.
+- **Scalabilità**: 2. Le difficoltà di scalabilità sono anche in questo caso dovute alla _singola unità di rilascio_ o _single deployment unit_, ovvero trattandosi di un unico applicativo, è necessario scalare l'intero sistema, dovendo quindi ricorrere alla _scalabilità verticale_.
+- **Performance**: 4. Processi di comunicazione semplici e isolabilità rendono questa architettura molto performante.
+
+## Microservizi
+
+La _buzzword_ per eccellenza degli ultimi anni.
+
+Questa architettura software si compone di un insieme di servizi indipendenti tra di loro, ognuno con un compito ben definito, che comunicano tra di loro attraverso un meccanismo di comunicazione _solitamente_ asincrono.
+
+A differenza delle architetture _a singolo blocco_ viste sopra, questa architettura permette di scalare i singoli componenti, in quanto ogni componente è un applicativo separato (servizio) e viene rilasciato in maniera indipendente.
+
+In questa architettura ogni microservizio solitamente ha il proprio database e il proprio back-end (basato su API), mentre il front-end è solitamente un'interfaccia grafica che comunica con i microservizi attraverso le API, a prescindere da dove risieda o da come sia implementato. I database sono solitamente piccoli e si occupano di gestire solo i dati necessari al microservizio in questione.
+
+A differenza delle altre architetture citate, la condivisione del database è da considerarsi un _anti-pattern_, ovvero una pratica da non adottare, in quanto può portare a problemi di _coupling_ tra i microservizi, esattamente l'opposto di quanto si vuole ottenere con questa architettura.
+
+Per definizione i microservizi non dovrebbero comporsi di più di una manciata di endpoint e relative funzioni, in quanto altrimenti si parla più di _service-based architecture_.
+
+Da notare che il _decoupling_ creato da questa architettura può portare ad un notevole aumento della complessità.
+
+- **Start-up**: 2. Lo start-up di un'architettura di questo tipo è complessa, in quanto è necessario stabilire sistemi di _orchestrazione_ o di _coreografia_ dei microservizi. Inoltre, il tipo di comunicazione (sincrono o asincrono) e il protocollo adottato (HTTP, AMQP, ecc.) devono essere valutati con attenzione.
+- **Costi**: 4. Potendo scalare indipendentemente i singoli microservizi, i costi sono contenuti, in quanto è possibile scalare solo i microservizi che ne hanno bisogno, e solo nei momenti in cui si ritiene necessario.
+- **Sviluppo e manutenzione**: 2. Il sistema di orchestrazione o coreografia dei microservizi può aggiungere una complessità non indifferente, soprattutto se non si ha esperienza in questo campo. Inoltre, la necessità di comunicare tra i microservizi può aggiungere un ulteriore livello di complessità.
+- **Tracciabilità**: 3. Testare e tracciare eventuali bug in questa architettura è complesso. L'isolamento dei microservizi aiuta in questo caso, ma la tracciabilità è piuttosto complessa e richiede integrazione di _distributed tracing_ o _open telemetry_.
+- **Scalabilità**: 5. La scalabilità è il punto di forza di questa architettura, in quanto ogni microservizio può essere replicato indipendentemente dagli altri.
+- **Performance**: 4. La performance di questa architettura è legata alla capacità di scalare i singoli microservizi. Con una buona configurazione di auto-scaling si possono raggiungere eccellenti risultati, anche se la necessità di mettere in comunicazione, via HTTP, socket o qualsiasi altra forma, una quantità elevata di sistemi può impattare sulle performance.
+
+## Service-based
+
+Il _service-based è un'architettura software in cui l'applicativo viene suddiviso in una manciata di servizi (Solitamente da 3 a 12) che comunicano tra di loro attraverso un meccanismo di comunicazione \_solitamente_ asincrono.
+
+Ci si aspetta che i servizi siano in costante comunicazione tra di loro e che rispettino dei contratti (interfacce) precedentemente stabiliti. Questo tipo di architettura è molto simile a quella dei microservizi, ma con la differenza che i servizi sono solitamente più grandi e con un compito ben definito.
+
+In questa architettura ogni servizio solitamente ha il proprio database, il proprio back-end e il proprio front-end, anche se ci sono casi in cui il database possa essere condiviso tra i servizi (in questo caso si suggerisce di utilizzare un utente dedicato per l'accesso alle singole tabelle o agli schemi di pertinenza), altri in cui il front-end vive in un applicativo separato o, ancora, altri in cui il front-end è unico per tutti i servizi.
+
+Questa architettura viene spesso indicata come "l'anello mancante" tra il monolite e i microservizi, anche se la dimensione dei servizi e il successivo _decoupling_ sono temi piuttosto complessi da gestire.
+
+- **Start-up**: 3. Lo start-up di un'architettura di questo tipo è complessa, ma non quanto quella a microservizi, anche se molte delle problematiche sono simili.
+- **Costi**: 4. Potendo scalare indipendentemente i singoli servizi, i costi sono contenuti, in quanto è possibile scalare solo i servizi che ne hanno bisogno, e solo nei momenti in cui lo si ritiene necessario.
+- **Sviluppo e manutenzione**: 3. Come per lo start-up, le sfide e le necessità sono simili a quelle dei microservizi, ma trattandosi di entità più grandi, la complessità diminuisce.
+- **Tracciabilità**: 4. Testare e tracciare eventuali bug in questa architettura è piuttosto semplice vista la normale dimensione dei servizi. L'isolamento aiuta, e anche qui si suggerisce l'integrazione di _distributed tracing_ o _open telemetry_.
+- **Scalabilità**: 4. La scalabilità è il punto di forza di questa architettura, in quanto ogni servizio può essere replicato indipendentemente dagli altri, ma la dimensione degli stessi può rendere più complicato del previsto il processo.
+- **Performance**: 4. La performance di questa architettura è legata alla capacità di scalare i singoli servizi. Con una buona configurazione di auto-scaling si possono raggiungere eccellenti risultati, anche se la necessità di mettere in comunicazione, via HTTP, socket o qualsiasi altra forma, una quantità elevata di sistemi può impattare sulle performance.
+
+## Altre architetture e pattern
+
+Architetture come la _space-based architecture_ o la _service-oriented architecture_ vengono utilizzate in contesti specifici e non sono solitamente utilizzate come architetture software di riferimento, di conseguenza vengono citate solo per completezza d'informazione.
+
+Una nota importante riguarda la _cell-based architecture_ che si pone come punto di incontro tra i microservizi e la _service-based architecture_. Partendo dal concetto di microservizi, potremmo identificare una _cell_ come un conglomerato di microservizi che rispondono a una necessità di business con una interfaccia unificata. Se si parte invece dal concetto di _service-based_, potremmo identificare una _cell_ come ulteriore scomposizione per facilitarne la manutenzione e la scalabilità.
+
+Altri termini, come la _event-driven architecture_ o la _event-sourcing architecture_ in realtà spesso si riferiscono ad un pattern di progettazione, ovvero un modo di progettare un sistema software, e non un'architettura software a tutti gli effetti. Il concetto di _event-driven_ viene infatti _affiancato_ più che _sostituito_ ad un'architettura software, come nel caso dei microservizi o del _service-based_.
+
+## Documentazione
+
+### Architecture Decision Records
+
+Gli _Architecture Decision Records_ (ADR) sono un modo per documentare le decisioni prese durante la progettazione di un sistema software. Questo tipo di documentazione è molto utile per capire il perché di determinate scelte e per capire come il sistema è stato progettato.
+
+A differenza di una classica documentazione tecnica o di un diagramma, gli ADR sono molto più semplici da scrivere e da leggere, in quanto sono composte da pochi elementi:
+
+- **Titolo**: il titolo della decisione presa.
+- **Stato**: lo stato della decisione presa. Solitamente può essere _Proposta_, _Accettata_, _Completata_, _Rifiutata_ o _Sostituita_.
+- **Contesto**: il contesto in cui è stata presa la decisione.
+- **Decisione**: la decisione presa.
+- **Conseguenze**: le conseguenze della decisione presa.
+
+Gli ADR vengono spesso utilizzate nelle aziende in cui si fa leva sul _BDD_ (Behavior Driven Development) per la stesura dei ticket nel proprio sistema di ticketing, puntando ad uno specifico ADR per dare informazioni aggiuntive e contesto a chi legge il ticket.
+
+## Conclusioni
+
+L'architettura software è un argomento molto vasto e complesso, materia che ognuno di noi dovrebbe conoscere e comprendere, in quanto influenza ogni aspetto dello sviluppo software.
+
+Un'architettura scelta in maniera frettolosa o senza una valutazione attenta può portare a conseguenze disastrose, come ad esempio un sistema che non riesce a gestire il carico di lavoro o che non riesce a soddisfare i requisiti di qualità e scalabilità richiesti.
+
+D'altro canto, si consiglia a chiunque legga questi contenuti di non basarsi sulle mere valutazioni fatte, che sono generaliste e non applicabili a tutti i contesti, ma di approfondire l'argomento e di valutare con attenzione ogni aspetto, in quanto ogni architettura software ha i suoi pro e i suoi contro, e ogni progetto ha le sue esigenze, e spesso la verità sta nel mezzo o, come piace dire a noi dev: _dipende_.
+
+## Riferimenti
+
+La lista di architetture software è ispirata e rivisitata a partire dal materiale prodotto e distribuito da [Mark Richards](https://www.developertoarchitect.com/), autore di molti libri sull'architettura software, video e webinar pubblicati su varie piattaforme, tra cui O'Reilly e YouTube.
diff --git a/docs/it/aziende-di-consulenza-vs-prodotto.md b/docs/it/aziende-di-consulenza-vs-prodotto.md
new file mode 100644
index 00000000..d2b7b932
--- /dev/null
+++ b/docs/it/aziende-di-consulenza-vs-prodotto.md
@@ -0,0 +1,105 @@
+---
+layout: default
+title: Aziende di consulenza vs prodotto
+nav_order: 7
+---
+
+# Aziende di consulenza vs prodotto
+
+## Obiettivo del capitolo
+
+In questo capitolo esploreremo i differenti modelli di business che un'azienda software può adottare. Non entreremo nel dettaglio di un intero modello di business, altrimenti diventerebbe un capitolo di economia e marketing, ma solo del modo in cui l'azienda riesce a mantenersi attiva sul mercato, creando e distribuendo valore ai clienti finali, attraverso i propri prodotti o servizi.
+
+In parole povere: come l'azienda riesce ad ottenere introiti e retribuire i dipendenti.
+
+Chi è agli inizi potrebbe pensare che le aziende informatiche siano essenzialmente tutte uguali.
+
+In realtà, il modello di business adottato dall'azienda influenza non solo il processo di sviluppo del software, ma potenzialmente anche la carriera stessa di chi lavora nello sviluppo, oltre che il suo modo di percepire e vivere l'azienda.
+
+Per questo motivo, conoscere le differenze tra le 2 principali strategie di business nelle aziende informatiche, ti permetterà di scegliere in modo consapevole il tuo prossimo lavoro.
+
+Capirai quale azienda può darti ciò che stai cercando, e non mi riferisco solamente alla RAL.
+
+> Nota bene: a volte queste differenze non sono così nette. Esistono aziende che adottano in maniera ibrida entrambe le modalità, ma avremo modo di entrare più nel dettaglio riguardo a questo nelle considerazioni finali.
+
+## Azienda di consulenza
+
+Questa tipologia di azienda adotta una tipologia di business B2B (_business to business_), ovvero i clienti dei servizi offerti, sono altre aziende.
+
+Più nello specifico, l'azienda guadagna tramite l'operato dei dipendenti, che lavorano come consulenti sotto contratto di appalto, per realizzare progetti delle aziende clienti.
+
+Questo significa che il dipendente presta momentaneamente la sua esperienza e le sue competenze, per portare a termine uno o più progetti per la durata del contratto stipulato tra la propria azienda in cui si è dipendenti e l'azienda cliente.
+
+Alcuni esempi di aziende di consulenza sono: Reply, Deloitte e Accenture.
+
+## Azienda di prodotto
+
+Le aziende di prodotto invece hanno solitamente un business B2C (business to customer), ovvero il cliente è l'utente finale, colui che utilizza il prodotto o i prodotti, sviluppati dalla compagnia stessa.
+
+In questo modello di business, le attività interne sono finalizzate a migliorare e innovare il prodotto, da cui dipendono i ricavi e la sopravvivenza dell'azienda.
+
+Il prodotto potrebbe essere un sito web, una piattaforma, un'applicazione, o un'intera suite di questi prodotti digitali.
+
+Se il prodotto è digitale, il guadagno potrebbe provenire ad esempio dalla sottoscrizione di abbonamenti, acquisti in app, pubblicità e altre modalità che in ogni caso dipendono dall'interazione dell'utente finale con il prodotto stesso.
+
+Alcuni esempi di aziende di prodotto sono: Google, Meta e Spotify.
+
+> N.B. Quando si parla di _utente finale_ ci si potrebbe benissimo riferire a dipendenti di aziende, o ad aziende nel loro insieme, e non necessariamente a cittadini e utilizzatori _comuni_. Ci sono tantissimi business che sviluppano prodotti in ottica B2B, vendendo soluzioni come, per esempio, applicativi di fatturazione piuttosto che strumenti di produttività.
+
+## Principali differenze
+
+Andremo a vedere adesso quali sono le principali differenze a livello di esperienza per chi sviluppa e sceglie di lavorare per una o per l'altra tipologia.
+
+### Cultura aziendale
+
+La cultura aziendale è il complesso dei valori che caratterizzano un'azienda.
+
+Tutti sono responsabili del clima e della cultura aziendale all'interno della propria azienda, ma essa è principalmente influenzata dalle persone che sono ai vertici e che sono responsabili delle principali decisioni aziendali.
+
+Chi è al management dell'azienda infatti definisce non solo gli obiettivi e la mission, ma cerca di trasmettere i valori da condividere per raggiungere tali obiettivi.
+
+Variando il modello di business di cui parlavamo prima, anche il focus e la cultura dell'azienda cambia.
+
+Generalmente chi lavora per aziende di prodotto ha un senso di appartenenza maggiore rispetto a chi lavora in aziende di consulenza poiché si lavora in team per un obiettivo comune, ovvero la realizzazione e il successo del prodotto. Questo aumenta la probabilità di sentirsi valorizzati e supportati.
+
+Questa sensazione invece spesso viene meno nelle aziende di consulenza poiché si lavora per il cliente o per i clienti. Escludendo il senso di responsabilità per il proprio operato, caratteristica del tutto personale e variabile, lavorando per e presso il cliente difficilmente si _sente_ il progetto su cui si sta lavorando come "proprio", soprattutto quando capitano frequenti spostamenti nei progetti e variazioni delle persone che ci lavorano. Tutto questo sul lungo periodo potrebbe causare demotivazione, disinteresse e quasi un senso di abbandono.
+In altri casi, questa sensazione di distacco è meno forte. In alcune aziende di consulenza infatti si lavora in modalità "_progetti chiavi in mano_". Con questa modalità, i progetti dei clienti vengono presi in carico dall'azienda di consulenza, curati e sviluppati interamente dai propri team. Questo permette a chi sviluppa di avere un team di riferimento più stabile rispetto a quando si lavora presso il cliente, aumentando il senso di appartenenza.
+
+### Possibilità di carriera
+
+Le aziende di consulenza puntano come obiettivo principale ad acquisire commesse dalle aziende clienti e puntare alla loro soddisfazione.
+
+Se questo obiettivo è perseguito in maniera sana, per un/a developer lavorare in azienda di consulenza significa potenzialmente lavorare con diverse tecnologie e avere la possibilità di formarsi in modo continuo e variegato.
+Questo si potrebbe tradurre in una rapida crescita e una più ampia possibilità di carriera. E spesso, le aziende di consulenza sono il punto di ingresso principale anche per le figure più Junior.
+
+Se questo obiettivo invece è perseguito dall'azienda con disorganizzazione, acquisendo progetti solo con lo scopo di fatturare senza tenere conto della reale disponibilità di un adeguato numero di personale preparato, questo potrebbe influire sul team di sviluppo in forma di mole di lavoro eccessiva, causando demotivazione e frustrazione, e in particolare sulle figure Junior che potrebbero essere abbandonate a loro stesse senza un'adeguata formazione.
+
+Nelle aziende di prodotto invece la responsabilità principale di ogni reparto dell'azienda sarà quello di mantenere il prodotto attivo e attrattivo sul mercato. Questo vale sia per il reparto di marketing e comunicazione, quanto per il reparto tecnico sia a livello di innovazione e sviluppo dello stesso.
+
+Se l'azienda di prodotto ha una direzione precisa e organizzata, per chi sviluppa e ci lavora sarà più naturale puntare alla propria crescita formativa, alla qualità del proprio operato e alla collaborazione e crescita in team.
+
+Per quanto la qualità del prodotto sviluppato è obiettivamente una priorità delle aziende di prodotto, tirando le somme, le possibilità di carriera e di crescita sono comunque fattibili in entrambe le tipologie di azienda, il tutto si riduce a quanto queste siano organizzate e attente alla formazione dei propri dipendenti.
+
+Per una persona Junior o senza una particolare esperienza significativa, è sicuramente più semplice entrare in un'azienda di consulenza poiché nelle aziende di prodotto in genere vengono ricercate persone autonome e con un background solido.
+
+### Progetti e tecnologie
+
+Le aziende di consulenza in genere hanno tipologie di clienti simili e offrono soluzioni per specifici ambiti (finance, automotive, e-commerce, medical, ecc...).
+
+La possibilità di variare linguaggi e tecnologie è sicuramente più alta rispetto un'azienda di prodotto, soprattutto se questa ha un singolo progetto. Lavorare nelle aziende di consulenza infatti permette generalmente di avere molte opportunità e fare molte esperienze diverse.
+
+Anche se questo dipende molto dalla tipologia di clienti con cui l'azienda collabora. Potrebbe capitare infatti di lavorare con progetti _legacy_ che il cliente non intende aggiornare per una questione di costi o di tempi.
+
+Nelle aziende di prodotto invece generalmente si ha un singolo o pochi progetti. Questo per alcuni potrebbe risultare noioso. Ma ancora una volta, dipende dalla natura del progetto stesso. Potrebbe infatti trattarsi di un software abbastanza grande e complesso da mantenere viva la curiosità e la necessità di formazione per svilupparlo, manutenerlo ed evolverlo.
+
+## Conclusioni
+
+Come abbiamo visto, la tipologia di azienda influenza significativamente la nostra esperienza e la nostra carriera come developer.
+
+Ma quello che incide più di tutto è il modo in cui il management e i vari reparti gestiscono i progetti, a prescindere dalla tipologia di azienda.
+
+Sicuramente le aziende di prodotto hanno come principale priorità quella di salvaguardare la **qualità** di ciò che viene sviluppato, per cui è molto più probabile che la loro attenzione sia rivolta verso la **formazione** e la **soddisfazione** dei propri dipendenti come strategia per trattenere le competenze acquisite e i talenti.
+
+Questo non significa che tutte le aziende di consulenza non siano attente ai propri dipendenti e prediligano la quantità alla qualità. Come spiegato precedentemente, alcune aziende di consulenza, approcciandosi con la metodologia "_chiavi in mano_" riescono a curare i progetti dei clienti nella loro interezza, aumentando anche la **sensazione di appartenenza** dei propri dipendenti.
+
+Sperando che adesso abbiate più chiare le principali differenze, potete fare la vostra scelta consapevole!
diff --git a/docs/it/come-affrontare-l-eta-nel-mondo-it.md b/docs/it/come-affrontare-l-eta-nel-mondo-it.md
new file mode 100644
index 00000000..1c4b7c71
--- /dev/null
+++ b/docs/it/come-affrontare-l-eta-nel-mondo-it.md
@@ -0,0 +1,80 @@
+---
+layout: default
+title: Come affrontare l'età nel mondo IT
+nav_order: 5
+---
+
+# Come affrontare l'età nel mondo IT
+
+In questo capitolo esploreremo la questione dell'età nel contesto dell'ambito IT. Spesso trascurato, questo aspetto riveste notevole rilevanza per coloro che operano in questo settore da qualche anno. Molte persone si trovano a confrontarsi con l'interrogativo sulla propria competitività nel mercato del lavoro in relazione all'età, chiedendosi se sono ancora in grado di mantenere un livello di competenza adeguato alle nuove tecnologie o se, viceversa, sono destinati a navigare tra mansioni manageriali, abbandonando il ruolo tecnico.
+
+È opportuno precisare che l'obiettivo di questo capitolo non è di certo dare delle certezze assolute o definire percorsi di carriera uguali per tutti, poiché ogni persona è unica e diversa in termini di passioni, ambizioni e attitudini. Quelle che seguono sono quindi delle considerazioni _personali_ che potrebbero aiutarti a comprendere come vuoi vivere la tua carriera dopo molti anni di esperienza e riflettere sulle implicazioni che potrebbero comportare alcune scelte.
+
+## Continuare ad essere dev, oppure diventare manager?
+
+Molto probabilmente questa è una domanda che hai già posto qualche volta, oppure ti sarà capitato di fare considerazioni simili con i tuoi colleghi durante la pause pranzo, o, addirittura anche con il/la tuo/a referente nei momenti dedicati alle valutazioni delle tue performance. Possiamo affermare che la maggior parte di chi sviluppa, con già qualche anno di esperienza alle spalle, risponderebbe che è possibile continuare a fare il dev anche dopo decine di anni di esperienza senza dover necessariamente abbandonare il codice. D'altronde se si è diventati developer per pura passione dello sviluppo, perché smettere?
+
+Forse, tu che leggi, penserai che con l'età che inizia ad avanzare possa risultare più arduo rimanere al passo con le tecnologie e che di conseguenza possa essere difficile rimanere competitivi rispetto ad una persona più giovane, spesso più aggiornata e stimolata. Pensiero assolutamente corretto e condivisibile, considerando che ragionamenti analoghi possono essere fatti anche su discipline diverse dal mondo IT. Ci sono decine di articoli che è possibile trovare in rete nei quali si evidenzia come sia più complicato trovare lavoro in età adulta, con consigli su come reinventarsi o su come rimanere competitivi in un mondo del lavoro che continua ad evolversi di anno in anno.
+
+Ma torniamo al pianeta IT: se hai già letto il capitolo _Cosa significa "essere dev"?_ avrai già realizzato che fare questo mestiere significa affrontare molte cose, non solo avere a che fare con linguaggi, librerie e frameworks. Chi si occupa di sviluppo deve realizzare che questi strumenti servono per uno scopo: risolvere problemi. Conoscere la nuova tecnologia non aiuta molto il core business di cui sei parte se non si applica bene al tuo dominio o alla necessità del momento. Molto spesso un/a dev giovane con tanta voglia di fare e sperimentare, cade in questo errore. Una persona che sviluppa da tanti anni potrà dare un contributo di valore nell'ambiente in cui si trova e aiutare anche dev più giovani a fare scelte più ponderate e corrette. Se tu che leggi, magari ancora non hai deciso come vuoi impostare la tua carriera, al di là della tua età e degli anni di esperienza, per lavorare al massimo in questo settore, poniti come obiettivo di non scrivere solo "bel codice", ma di portare _valore_ in ciò che fai per la tua azienda.
+
+## Pensare al "vero" obiettivo
+
+Ripetiamo: il lavoro del/la developer è (anche) risolvere problemi. Il nostro scopo non è, e non sarà sempre, trovare soluzioni accattivanti, magari con le tecnologie del momento, ed è questa la maturità che deve acquisire un/a developer negli anni e con l'esperienza.
+
+Vogliamo evidenziare questo aspetto con un aneddoto riportato nel libro Clean Architecure di Robert C. Martin. Senza entrare troppo nei dettagli, che puoi trovare nel libro, durante una sua esperienza lavorativa alla fine degli anni Ottanta ha dovuto, per pura esigenza di marketing, impiegare un database relazionale in un sistema di cui si occupava. Ma per motivi ingegneristici lui affermava che non era assolutamente necessario avere un database in quel sistema, che raggiungeva appieno il suo scopo così com'era, ma il mercato di quel periodo voleva i database nei sistemi, e l'azienda _accontentò_ il mercato. Dal canto suo, Martin era focalizzato sull'obiettivo ingegneristico reale, e crediamo che debba essere questa la competenza che chi fa questo lavoro dovrebbe sviluppare col tempo.
+
+Facciamo un esempio più recente: i microservizi. Chissà in quanti annunci di lavoro li avrai visti in questi ultimi anni.
+Oltre a valutare i vantaggi (e gli svantaggi) di questa architettura, sembra che non se ne possa più fare a meno. Peccato che nel marzo 2023 il team di Prime Video ha pubblicato un [post](https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90) sul proprio blog, indicando che con il passaggio da un'architettura distribuita a microservizi a un'architettura monolitica ha ridotto i costi infrastrutturali di oltre il 90%. Il team di Prime Video si è focalizzato su un obiettivo preciso: ottimizzare i costi, e ci sono riusciti con una soluzione tanto semplice quanto _classica_, il **monolite**.
+
+I due esempi sono diversi in termini di situazione e tempi, ma ci fanno comprendere una cosa: il nostro lavoro è cercare il modo migliore di raggiungere l'obiettivo ingegneristico che aiuti il business, a prescindere dalle mode del momento.
+
+Se sei un/a developer che riconosce del valore nelle scelte che compie, perché preoccuparsi dell'età che avanza?
+
+## Diventare manager
+
+Facciamo una breve considerazione sul diventare manager in modo da giungere alle dovute riflessioni che potrebbero esserti utili semmai un giorno dovessi fare questa scelta. Per manager intendiamo, per semplicità e senza andare troppo nel dettaglio, quei ruoli che non sono coinvolti nelle decisioni, e operativi per quanto concerne l'aspetto tecnico ma sostanzialmente incentrati nella gestione di alto livello dei progetti e dei team.
+Abbiamo constatato che è possibile rimanere dev anche con l'avanzare dell'età, ma molto spesso diventare manager sembra quasi l'unico modo per fare carriera. Ci sono realtà aziendali con una gerarchia tale per cui chi fa sviluppo è giunto solo ad un primo step della propria carriera, una base dalla quale poter avanzare, prima o poi, abbandonando la via del codice a favore di quella manageriale. Noi ci auguriamo che questo non sia il tuo caso, ma può capitare che il contesto lavorativo in cui ci si trova influenzi il modo di percepire la carriera e di conseguenza le nostre scelte, perché vediamo un'unica strada davanti a noi. Questo potrebbe indurci a pensare che non raggiungere un ruolo manageriale dopo molti anni di esperienza equivalga a un fallimento di carriera, portando noi stessi a sentirci in quel momento inadeguati rispetto alle richieste del mercato. Per evitare ciò, si sceglie di diventare manager per raggiungere una sorta di traguardo professionale e, perchè no, anche economico e di benefit che spesso sono legati a questo tipo di ruolo.
+
+A te che leggi, vogliamo dire che non è così: se in te c'è passione per lo sviluppo, non hai l'obbligo di intraprendere percorsi manageriali. La programmazione offre molte sfide e soddisfazioni che puoi trovare in contesti diversi da quello nel quale probabilmente ti trovi attualmente. Continua a studiare, ad approfondire e a confrontarti con altre persone con la tua stessa passione. E se dovessi realizzare di non trovarti bene nel contesto attuale, cerca realtà aziendali dove ci sono percorsi alternativi, che ti permetteranno di crescere tecnicamente e di continuare a perseguire i tuoi obiettivi.
+
+Concludiamo questa sezione dicendoti che non vogliamo convincerti a non diventare manager. Ci sono tante sfide in questo ruolo che sicuramente ti potrebbero dare molte soddisfazioni. Diventa manager, abbandonando pure la parte tecnica e il codice se ti rivedi in questa figura, se questo ruolo ti appassiona e sei convinto di questa decisione. Siamo certi che se intraprenderai questo percorso con decisione e passione potrai diventare un manager con il quale tutti avranno piacere di collaborare.
+
+## Non _solo_ developer
+
+Fermiamoci a riflettere brevemente su questa domanda apparentemente innocua ma allo stesso tempo interessante: se desideriamo continuare a scrivere codice, è necessario rimanere developer per sempre?
+
+Probabilmente nella tua mente starai già pensando al tuo contesto aziendale o alle tue precedenti esperienze, ricostruendo mentalmente le responsabilità di figure _ibride_ tra ruoli tecnici e manageriali, per citarne alcune: Team Leader, Tech Lead e Solution Architect a cui i/le developer fanno riferimento per ciò che riguarda decisioni più o meno delicate su aspetti tecnici. Come forse saprai, non è detto che queste figure, prese da altre responsabilità o coinvolte in altri processi più organizzativi, riescano ancora effettivamente a scrivere codice. Ogni realtà solitamente ridefinisce questi ruoli, proiettandoli nei propri contesti. Per esempio, un/a team leader in una startup che è poco strutturata è probabile che continui a sviluppare, rispetto a realtà più grandi e oliate dove il team leader è più simile a una figura manageriale. Ci sono, invece, realtà molto flessibili che danno la libertà ai propri team leader di gestirsi e decidere quanto addentrarsi negli aspetti tecnici.
+
+Questi ruoli sono molto interessanti e sfidanti qualora fare _solo coding_ iniziasse a non bastarti. Se vuoi gestire un team e avere responsabilità differenti, sicuramente prima o poi potrai intraprendere uno di questi percorsi senza rinunciare del tutto all'aspetto tecnico.
+
+Quale sia la tua scelta, ricorda che se vuoi essere un/a developer che aggiunga valore nonostante l'età, non è sufficiente che ti limiti alla programmazione, ma è necessario contribuire a ogni aspetto del progetto: sia che tu rivesta il ruolo di developer o di team leader, impegnati costantemente nel risolvere problemi e suggerire soluzioni, senza farti distrarre dai limiti imposti dai ruoli.
+Se sei ancora junior, proponi soluzioni anche se non hai la certezza in merito alla loro correttezza. Non solo l'impegno nello studio e nell'approfondimento, ma anche e soprattutto trarre insegnamento dai propri errori è un ottimo modo per crescere.
+Così, dopo anni di esperienza, potrai mettere in campo molte conoscenze che figure più giovani del team probabilmente non avranno.
+
+Un/a developer che sa comunicare e sa trasmettere le proprie conoscenze ad altri, sarà sempre di grande valore per un team e avrà un'autorevolezza al suo interno a prescindere dal ruolo e soprattutto dall'età.
+
+## Il bias del fare codice a vita
+
+La carriera di chi sviluppa è complessa sotto molti punti di vista e non priva di incognite: al primo posto possiamo assolutamente prendere coscienza del fatto che sia una categoria nuova e in continua evoluzione. Guardando alcuni schemi che illustrano l'evoluzione e le competenze necessarie per una particolare mansione, diventa evidente di fronte a noi un albero di opzioni impressionante. Da un punto di vista più generale non possiamo ignorare la crescita verso determinate mansioni più gestionali e meno operative, è un pensiero che prima o poi si tende a fare. Questo è legato non solo all’ambizione ma anche ad una considerazione sul proprio futuro, in generale sull’invecchiamento intellettuale e sulle conseguenze che inevitabilmente può avere sul nostro rendimento, sulla nostra freschezza e sulla capacità di stare dietro ad un mondo, quello informatico, in perenne vorticoso movimento; questo rendimento è legato a doppio filo con il nostro intelletto.
+
+Dal punto di vista della catalogazione, l’intelligenza, come capacità di risolvere un problema, viene descritta come Fluida o Cristallizzata (teorizzata dallo psicologo Cattell). La prima, quella fluida, è il pensiero logico, la nostra capacità di risolvere problemi nuovi. Quella cristallizzata, invece, è la nostra capacità di utilizzare le conoscenze pregresse; questa è quella che di solito cade sotto il nome di “seniority”. Nel lavoro di chi sviluppa sono importanti entrambe probabilmente in egual misura.
+
+Il passare del tempo va intuitivamente a beneficio dell'intelligenza cristallizzata perché ci dà un bacino più ampio da cui attingere. In passato questa catalogazione veniva legata al Q.I. da cui prende anche il nome, rappresentato dal rapporto tra età psicologica e anagrafica (da cui quoziente). L’intelligenza fluida, invece, ha una caratteristica inversa, segue un andamento decrescente con l'avanzare dell'età, facendoci perdere freschezza. Le nostre performance come velocità, capacità di visualizzazione ed elaborazione sono legate a questi due elementi che sommati formano il nostro intelletto.
+
+Gli studi più recenti (A Novembre 2023) a riguardo sono stati svolti dall’Università di Monaco, racchiusi in un articolo dal titolo ["Life cycle patterns of cognitive performance over the long run" di Anthony Strittmatter](https://www.pnas.org/doi/10.1073/pnas.2006653117) che ha studiato e cercato di dare una risposta quantitativa e non solo qualitativa alla domanda: _quanto è differente un cervello giovane da uno vecchio e quale è il periodo in cui rende di più?_.
+
+Il punto di partenza è stato quello di capire quale sia il metodo migliore per misurare questa performance senza farsi influenzare. Il campione in questo caso è fondamentale: cultura, classe sociale e posizione geografica possono influenzare il risultato ed è semplicemente intuibile; l’allenamento delle proprie capacità e la possibilità di stare vicino a chi detiene conoscenze avanzate danno sempre strumenti migliori per affrontare i problemi. Da questo lato la sfida è molto interessante perché sappiamo bene quanto un bias cognitivo possa influenzare non solo i risultati ma anche la loro interpretazione.
+
+Per questa analisi si è quindi deciso di usare gli scacchi come metro; le partite, infatti, sono catalogate dal 1890 e la vittoria è legata a processi cognitivi prettamente meritocratici dove tutti quei parametri in cui il dato può essere influenzato hanno meno peso. Il bacino si è presentato piuttosto ampio, sono a disposizione tutte le mosse in un arco di 125 anni, circa 24.000 partite. A questo punto sono stati elaborati collegando età e qualità delle mosse e la velocità con cui venivano eseguite, una ad una; per analizzare la validità delle mosse è stato usato un famoso motore di scacchi open source Stockfish.
+
+Il risultato è piuttosto disarmante, è stato notato innanzitutto che il picco di performance è tra i 35 e i 45 anni. Questo va un poco a sfatare il fatto che la giovane età sia legata a performance migliori in assoluto. Da questo punto di vista si nota come l’avanzare dell’età non faccia che migliorare la qualità delle nostre capacità per molti anni; questo chiaramente da un punto di vista prettamente statistico, picchi in tutte le direzioni sono possibili e sono quelli che spesso danno forza ai nostri bias. I dati hanno anche mostrato una cosa altrettanto interessante sugli estremi di questa curva: la quantità di performance guadagnata e poi persa con l’età. Ci troviamo di fronte ad una campana schiacciata, prima sale (dai 20) e poi scende (verso i 55). L’escursione in ambo i lati, ovvero nei 20 e poi nei 55, è solamente intorno al 10%.
+
+In buona sostanza, ciò che è evidente è che la nostra volontà di fare carriera non deve essere influenzata dalla preoccupazione di non farcela al sopravanzare di una certa età; per lo meno non deve esserlo dal punto di vista delle capacità intellettive. Statisticamente non c’è un vero e proprio declino cognitivo, ma ci si trova più che altro di fronte alla stanchezza o alla propria ambizione di cambiamento. Molti informatici famosi hanno sostenuto questa affermazione: _la carriera non deve essere intesa nella sola direzione manageriale_; se chi si trova a dover prendere questa scelta ha la voglia e la passione, può continuare a fare questo lavoro a vita, non c’è qualcosa che veramente ce lo neghi dal punto di vista fisiologico. Che carriera intraprenderemo quindi deve essere frutto di un desiderio, di una necessità che non sia legata alla paura di invecchiare; anche questo tema sarà sicuramente rivisto negli anni a venire anche dal punto di vista del mercato del lavoro.
+
+**Se vi piace programmare e avere le mani in pasta ed essere operativi, non fatevi spaventare dell’avanzare dell’età: è più un bias che un ostacolo tangibile!**
+
+## Conclusioni
+
+In questo capitolo abbiamo parlato di come affrontare l'età nel mondo IT. Questo è sempre un tema delicato, e non riguarda solo il mondo IT, senza considerare che ci sono tanti fattori collegati ad esso: famiglia, figli, tempo che non basta mai per aggiornarsi e studiare, stanchezza, ecc..
+L'obiettivo era di darti modo di fare le tue considerazioni, con l'auspicio che ciò possa portarti ad una maggiore chiarezza riguardo al tuo percorso professionale futuro, e che la passione, la volontà di dare sempre il tuo contributo e di condividere le tue esperienze con il team, possano continuare a farti a sviluppare con entusiasmo senza timore dell'età che avanza.
diff --git a/docs/it/cosa-significa-essere-dev.md b/docs/it/cosa-significa-essere-dev.md
index e245f64d..17ced53e 100644
--- a/docs/it/cosa-significa-essere-dev.md
+++ b/docs/it/cosa-significa-essere-dev.md
@@ -1,3 +1,9 @@
+---
+layout: default
+title: Cosa significa "essere dev"?
+nav_order: 2
+---
+
# _Cosa significa "essere dev"?_
La domanda, di per sé, è piuttosto semplice.
diff --git a/docs/it/sviluppo-mobile.md b/docs/it/sviluppo-mobile.md
new file mode 100644
index 00000000..5b2cffce
--- /dev/null
+++ b/docs/it/sviluppo-mobile.md
@@ -0,0 +1,166 @@
+---
+layout: default
+title: Sviluppo Mobile
+nav_order: 6
+---
+
+# Sviluppo Mobile
+
+## Che cos'è lo sviluppo mobile?
+
+Per "sviluppo mobile" si intende un insieme di processi e attività che coinvolgono l'analisi, la progettazione, la realizzazione e il rilascio di una o più applicazioni la cui esecuzione avverrà su dispositivi tascabili come smartphone e tablet.
+
+## Le fasi dello sviluppo mobile
+
+Le fasi di analisi e di progettazione nello sviluppo mobile condividono molte caratteristiche con lo sviluppo del software classico. Sebbene sia un settore di nicchia, in questo particolare momento dello sviluppo è necessario tenere in considerazione alcuni aspetti di fondamentale importanza. Ad esempio l'usabilità differente dettata dalle dimensioni compatte di uno smartphone, o dalla potenziale assenza di connettività, passando dall'architettura e dalle prestazioni del dispositivo o dalla durata della batteria.
+
+La fase di realizzazione, come per qualsiasi tipologia di software, consiste nel tradurre il prodotto delle analisi e della progettazione in istruzioni da fornire al nostro dispositivo. Con il passare degli anni si sono consolidate due tipologie di approcci allo sviluppo: lo sviluppo nativo e lo sviluppo ibrido. Lo sviluppo nativo si è evoluto tecnologicamente nel tempo ma ha mantenuto concettualmente lo stesso significato, discorso diverso per l'approccio ibrido: nato con una particolare filosofia che ha cambiato significato grazie alla diffusione dei moderni framework di sviluppo cross-platform come React Native e Flutter.
+
+Il rilascio di un'applicazione è probabilmente l'unica fase che differisce rispetto al classico processo che avviene per altre tipologie di software. In questa fase il mobile developer deve costruire degli artefatti che nella maggior parte dei casi possono essere distribuiti ai propri utenti passando attraverso delle piattaforme che prendono il nome di Store. È possibile distribuire queste applicazioni senza passare dagli store attraverso il sideloading, ma questo penalizzerà la diffusione del prodotto e renderà il processo di installazione e di aggiornamento più complesso del normale. Allo stato dell'arte attuale, per ragioni di sicurezza, in alcune piattaforme Apple è persino vietato il sideloading di applicazioni non distribuite attraverso lo store principale, sebbene la comunità europea stia cercando in qualche modo di forzare la mano per sfavorire il monopolio di Apple.
+
+## Cenni Storici
+
+La nascita dello sviluppo mobile e della professione del mobile developer va fatta coincidere con la diffusione di dispositivi tascabili come smartphone e tablet, in origine definiti palmari.
+
+Secondo [Wikipedia](https://it.wikipedia.org/wiki/Computer_palmare), "Un computer palmare (detto anche palmare), spesso indicato in lingua inglese con la sigla PDA (Personal Digital Assistant), o con l'ormai desueto termine palmtop, è un computer di dimensioni contenute, tali da essere portato sul palmo di una mano (da cui il nome), dotato anche di un touch screen."
+
+Questi computer sono nati principalmente con l'obiettivo di avere con sé agende, calendari, rubriche e calcolatrici dalle dimensioni contenute che potessero essere facilmente riposte in tasca o in un piccolo contenitore più facilmente trasportabile rispetto ad un laptop.
+
+Le aziende pioniere di questo settore sono state Palm, Texas Instruments e Microsoft: sebbene i primi palmari altro non erano che calcolatrici arricchite di funzionalità come rubrica e calendario, con il passare degli anni questi strumenti hanno iniziato ad evolvere e, di pari passo con il diffondersi a macchia d'olio di Internet e della microminiaturizzazione, a convergere verso un unico dispositivo ad oggi noto come smartphone.
+
+I primi palmari ad essere di fatto degli smartphone sono stati i Pocket PC di Microsoft. L'azienda di Redmond realizzò una piattaforma denominata Windows CE (Windows Embedded Compact) installabile su tutta una serie di dispositivi tascabili. Su questa piattaforma Microsoft ha continuato a realizzare versioni parallele dei suoi principali sistemi operativi Microsoft Windows compatibili con processori ARM, MIPS o SH3.
+
+L'abbandono del concetto di palmare e la convergenza verso gli smartphone si è avuta con la diffusione delle connessioni a Internet sui telefoni cellulari e con l'introduzione di sempre più strumenti accessori come il GPS, la radio FM, la fotocamera, e tutta la sensoristica di base di cui sono dotati gli ormai moderni smartphone.
+
+A dominare la prima generazione di smartphone è stata Nokia con SymbianOS. La multinazionale finlandese ha letteralmente conquistato le tasche della popolazione mondiale grazie al suo sistema operativo in grado di far girare le prime applicazioni realizzate in JavaME (Java MicroEdition). Sebbene inizialmente lo sviluppo di applicazioni per palmare e smartphone era un'attività riservata a chi era stato fisicamente assunto presso l'azienda madre, con la diffusione di Java, chiunque poteva studiare l'SDK della Sun per realizzare le proprie applicazioni.
+
+La generazione successiva di smartphone ha visto contendersi il mercato da aziende come Apple con l'introduzione dell'iPhone, uno dei primissimi smartphone privi di tastiera fisica e dotato esclusivamente di touchscreen; BlackBerry con il suo BlackBerry OS, Microsoft con Windows Phone, Nokia con SymbianOS e Google con Android. Di queste realtà, ad oggi fra i principali player si annoverano solo Apple con iOS/iPadOS e Google con Android: molte delle aziende precedentemente menzionate non sono state in grado di innovarsi e tenere il passo nella scena mobile.
+
+In questi anni, alcune realtà come Samsung prima e Huawei poi hanno tentato in qualche modo di eliminare il duopolio di Apple e Google, senza successo. Ad oggi, sviluppare su mobile significa sostanzialmente realizzare applicazioni per iPhone e iPad compatibili con il sistema operativo iOS sul fronte Apple, e per smartphone e tablet che montano il sistema operativo di Google sul fronte Android.
+
+## Le Piattaforme Target
+
+Sviluppare per mobile ad oggi si traduce fondamentalmente nel costruire artefatti software che possano funzionare su smartphone e tablet basati su sistemi operativi Android e iOS/iPadOS.
+
+Per programmare applicazioni mobile, sia che si scelga di realizzarle con approccio nativo, sia che si scelga l'approccio ibrido, richiede necessariamente l'installazione di un Software Development Kit (SDK) preciso, che prendono il nome rispettivamente di Android SDK e iOS SDK. Questi SDK contengono tutta una serie di prodotti come compilatori, emulatori, e strumenti aggiuntivi utili a chi sviluppa su mobile. Sebbene ultimamente la tecnologia stia virando verso alcune particolari architetture basate su ISA ARM, ad oggi la maggior parte dei computer desktop adotta ancora processori basati su architettura x86 a 64 bit: si rende quindi necessario installare strumenti come emulatori e simulatori per velocizzare lo sviluppo installando il proprio software in fase di sviluppo all'interno di macchine virtuali che rispecchiano quanto più il comportamento di un dispositivo fisico.
+
+Per quanto un emulatore (altresì noto come simulatore nel mondo Apple) sia di fatto una macchina virtuale molto simile ad un dispositivo fisico, lo stesso non ci consentirà di testare tutte le funzioni realmente esistenti su un vero dispositivo: questo spesso si traduce nel dover acquistare un parco dispositivi fisico sufficientemente capiente per poter testare la maggior parte delle funzioni non riproducibili all'interno di un emulatore, funzionalità spesso legate al comparto sensoristica come bluetooth, accelerometri, GPS, fotocamera, sensori d'impronta digitale e via discorrendo.
+
+Se dal punto di vista degli SDK è necessario passare obbligatoriamente dai prodotti ufficiali Google e Apple, non vale la stessa regola per gli IDE. Sul fronte Android, l'IDE più diffuso è Android Studio, nato a partire da un altro prodotto Jetbrains di nome IntelliJ IDEA, mentre su iOS possiamo utilizzare il software proprietario Apple XCode. Come menzionato precedentemente, nessuno ci vieta di utilizzare altri IDE come Visual Studio Code o persino un banale blocco note per scrivere il nostro codice poiché il compilatore risiede nell'SDK e non è strettamente legato all'IDE scelto. Certo, dovremo rinunciare a qualche funzionalità extra offerta da un IDE di riferimento, ma questo non ci impedirà di essere produttivi scrivendo il codice all'interno di un editor con cui abbiamo familiarità.
+
+Che dire invece dei linguaggi di programmazione? Qui è fondamentale fare un distinguo in quanto gli stessi variano in funzione dell'approccio scelto: se nativo o ibrido. In questa sezione tratteremo esclusivamente l'approccio nativo.
+
+Agli albori dello sviluppo mobile su Android ed iOS, i principali linguaggi di programmazione a farne da padroni sono stati rispettivamente Java per Android ed Objective-C per iOS. Google tuttavia ha sempre sofferto l'idea di non poter avere il controllo sul proprio linguaggio di programmazione mobile così come faceva invece Apple con Objective-C, e a partire dal 2014 ha iniziato a lavorare su un approccio di sviluppo proprietario che ha poi visto la luce qualche anno dopo. Lato Apple invece, con la nascita di Kotlin divenuto poi il principale linguaggio di programmazione per lo sviluppo mobile nativo, si è scelto di abbandonare Objective-C in favore di Swift, un linguaggio di programmazione moderno e molto meno complesso rispetto al suo predecessore.
+
+Questi due linguaggi di programmazione hanno dominato e tutt'ora dominano la scena dello sviluppo mobile, sebbene negli ultimi anni abbiamo vissuto un vero cambio di paradigma passando dalla programmazione imperativa alla programmazione dichiarativa: se prima il layout delle interfacce era fortemente disaccoppiato rispetto al codice sorgente della nostra app, con il passaggio al metodo Declarative UI le due cose si sono fuse, dando alla luce a Jetpack compose su Android e a SwiftUI su iOS.
+
+## Modalità di sviluppo: Nativo vs Ibrido
+
+Agli albori dello sviluppo mobile, l'unico modo possibile per realizzare applicazioni per smartphone e tablet consisteva nello studiare il linguaggio di programmazione di riferimento per poter interagire con l'SDK messo a disposizione da Apple o Google per programmare le app. Con il consolidarsi dei due principali sistemi operativi Android ed iOS, chi scriveva codice per realizzare app mobile poteva fondamentalmente scegliere se verticalizzare le proprie competenze su uno dei due per diventare un Android Mobile Developer o un iOS Mobile Developer, o se studiarli entrambi, diventando di fatto un Mobile Developer a tutto tondo.
+
+Realizzare la stessa applicazione per due sistemi operativi diversi significava avere due codici sorgenti completamente diversi, utilizzare due design system differenti, affrontare bug e problematiche diverse in funzione della piattaforma di riferimento, e soprattutto imparare due linguaggi di programmazione con un paradigma molto diverso fra loro: Java per Android ed Objective-C per iOS.
+
+Con il diffondersi degli smartphone e di internet, e con la progressiva transizione al contenuto mobile-first, molti web developer hanno deciso di convertirsi al mobile. L'unico limite a questo punto restava il linguaggio di programmazione: la maggior parte dei web developer era poco avvezzo all'utilizzo di Java ed Objective-C, e questo ha contribuito a far nascere i framework di sviluppo ibridi di prima generazione.
+
+Lo sviluppo ibrido nasce per far fronte al problema di dover necessariamente conoscere linguaggi di programmazione ed SDK di riferimento per ogni piattaforma mobile esistente: dato che la maggiorparte delle prime applicazioni non presenti sugli store girava sui browser degli smartphone, si è deciso di sfruttare javascript come linguaggio di programmazione per modellare dei framework che consentissero con un unico codice sorgente ed un unico design system, di realizzare applicazioni per entrambi i sistemi operativi di riferimento.
+
+Per farla breve, tutti i framework di sviluppo ibrido di prima generazione come Cordova, Phonegap e Ionic non facevano altro che renderizzare un sito web realizzato con il tris di tecnologie HTML, Javascript e CSS all'interno di una webview in un'app nativa. Sebbene questo consentisse di realizzare applicazioni più rapidamente e meno prone a bug o problematiche di vario genere, di contro ci si doveva scontrare con i limiti prestazionali dettati dalla tecnologia, dalle latenze di javascript, e soprattutto dall'assenza di fluidità d'esecuzione a causa dell'assenza di motori di rendering pensati per interagire nativamente con l'hardware del dispositivo.
+
+Questo ha spinto i progettisti a ripensare l'approccio allo sviluppo ibrido: invece di utilizzare delle webview per renderizzare dei siti web, si è deciso di utilizzare in linguaggio di programmazione di riferimento per comunicare con un motore di rendering che consentisse di disegnare le interfacce in modo completamente nativo sugli smartphone. I framework di seconda generazione come Xamarin, Flutter, MAUI e React Native fondamentalmente producono un artefatto la cui logica di business scritta con il linguaggio di programmazione target è stata tradotta in codice macchina.
+
+Qui la domanda potrebbe sorgere spontanea: ma quindi realizzare app con un framework di sviluppo ibrido di seconda generazione ci consente di fatto di sviluppare app native? La risposta in questo caso è sì. E verrebbe quindi naturale chiedersi che tipo di strategia adottare quando si ha la necessità di realizzare un'applicazione mobile, soprattutto se queste valutazioni devono tradursi in un percorso di carriera professionale.
+
+Sviluppare in nativo o sviluppare in ibrido, come tutte le cose, ha dei pro e dei contro, vediamo insieme vantaggi e svantaggi delle due soluzioni:
+
+| | **Sviluppo Nativo** | **Sviluppo Ibrido** |
+| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Vantaggi** | **Prestazioni massime**: è pressoché impossibile battere le performance del codice nativo dato che lo stesso non passa attraverso un motore di rendering, le istruzioni vengono tradotte in codice macchina
**Miglior interazione**: come per il punto precedente, comunicare con la sensoristica o con gli accessori dello smartphone è pressoché immediato
**User experience proprietaria**: ogni piattaforma target ha ormai un design system di riferimento, è possibile quindi utilizzare le componenti standard per modellare le interfacce grafiche
**Applicazioni più leggere**: l'assenza di un framework si traduce in zero overhead in memoria o sullo storage | **Singola codebase**: come menzionato più volte precedentemente, questo aspetto ha un impatto sui tempi e sui costi di sviluppo e di manutenzione dell'intera codebase e dell'intero team
**Design system unico**: quando si ha la necessità di realizzare applicazioni fortemente tematiche o con una brand identity ben strutturata, avere un unico design system consente di comunicare le idee del prodotto in modo più efficace
**Prestazioni ottime**: a meno di realizzare prodotti molto di nicchia (realtà aumentata o videogames), l'uso dei motori di rendering consente di disegnare sullo schermo componenti con una reattività prossima al nativo e con una latenza del tutto impercettibile |
+| **Svantaggi** | **Codice sorgente duplicato**: se l'obiettivo è raggiungere entrambe le piattaforme, è necessario scrivere l'applicazione sia per Android che per iOS
**Bug e problematiche duplicate**: questa è una diretta conseguenza di avere un doppio codice sorgente; un errore di business è ridondante, un bug proveniente da un'implementazione strettamente legata al target di riferimento esisterà solo su quella determinata piattaforma
**Costi**: anche in questo caso il doppio codice sorgente si traduce in tempistiche, costi di sviluppo e manutenzione pressoché doppi | **Overhead del framework**: questo problema si traduce fondamentalmente in applicazioni leggermente più pesanti in memoria e sullo storage
**Interazione limitata**: spesso interagire con sensori o strumenti del dispositivo si traduce nell'introdurre canali di comunicazione, definendo ulteriori layer di scambio dati fra framework e codice nativo |
+
+Quando scegliere se realizzare un'applicazione in nativo o con un approccio ibrido? Nessuno conosce questa risposta in quanto la stessa dipende fondamentalmente dal tipo di prodotto che si vuole realizzare, dalle prestazioni che si intende ricercare, e soprattutto dai costi da affrontare. Ad oggi i framework di sviluppo ibridi di seconda generazione ci consentono di realizzare la maggior parte delle applicazioni mobile presenti sul mercato senza scomodare lo sviluppo nativo.
+
+## Modalità di rilascio
+
+A differenza dello sviluppo web dove l'applicativo viene eseguito all'interno di un browser, nello sviluppo mobile il prodotto finale deve essere installato sul dispositivo fisico, assumendo un comportamento simile a quello desktop.
+
+Come precedentemente accennato, per poter installare ufficialmente un'applicazione su uno smartphone è necessario passare per i canali ufficiali: i più diffusi sono rispettivamente il Google Play Store per il rilascio di applicazioni pensate per funzionare su telefoni e tablet basati su sistema operativo Android, e l'App Store per i dispositivi Apple. È possibile sfruttare il sideloading per poter installare un'app senza passare dagli store, ma questo richiede dei passaggi aggiuntivi che disabilitano alcuni controlli di sicurezza sui dispositivi Android, mentre su Apple è necessario utilizzare alcuni canali dedicati paralleli all'App Store, tipicamente adoperati in ambito business, oppure, scegliendo strade meno sicure come l'hacking con jailbreak.
+
+Queste sono le due principali piattaforme target che chi sviluppa su mobile può decidere di supportare sebbene in passato, in seguito ad una diatriba politica fra Stati Uniti e Cina, l'azienda Cinese Huawei abbia deciso di smettere di usufruire del ramo commerciale di Google creandosi una piattaforma per il rilascio di app ad-hoc che prende il nome di App Gallery. Ovviamente esistono anche altre minoranze sul mercato, ma sarebbe troppo complesso indicizzarle tutte.
+
+Per rilasciare applicazioni sulle due principali piattaforme target, è necessario registrarsi al Google Play Store come Google Play Developer, e all'Apple Developer Program. L'iscrizione alle due piattaforme ha un costo una tantum per quanto concerne Google e un canone fisso annuo per Apple, che consentono alla piattaforma di inserire una barriera d'accesso che privilegia la qualità alla quantità.
+
+A valle della registrazione, le applicazioni possono essere caricate sui rispettivi store e un team di professionisti procederà ad analizzare le nostre applicazioni e a valutare se le stesse sono conformi ai termini e condizioni che abbiamo siglato in fase di registrazione. A differenza di altre piattaforme, storicamente rilasciare applicazioni mobile è più difficile, complesso e temporalmente più lento, in quanto le app devono precedentemente superare un controllo di qualità da parte degli addetti agli store non del tutto automatizzabile e automatizzato.
+
+Quando compiliamo un artefatto per Android, abbiamo la possibilità di scegliere due formati di destinazione: apk e aab. Storicamente il formato apk è stato il primo file in grado di consentire l'installazione di un'app su Android. Formalmente altro non è che un archivio compresso che contiene alcuni descrittori dell'app, noti come Manifest file, e un ulteriore archivio con la logica dell'applicazione con estensione di tipo dex, acronimo di Dalvik Executable Format, in onore della prima macchina virtuale Android progettata da Dan Bornstein in Google.
+
+Con il passare degli anni, il diffondersi di smartphone e tablet, e il passaggio attraverso diverse architetture di processori, Google ha deciso di battezzare un nuovo archivio file pensato appositamente per il rilascio delle app sul Google Play Store e che prende il nome di Bundle AAB (Android App Bundle). Questo formato di file consente di memorizzare solo le informazioni strettamente necessarie al funzionamento dell'app, privando l'artefatto degli ABI (Application Binary Interface) e rendendolo molto più compatto. Fondamentalmente in Google si sono accorti che gli apk, con il passare del tempo, stavano crescendo di dimensione poiché gli stessi includevano tutti gli ABI esistenti. Si è scelto quindi di rivoluzionare il comportamento del Google Play Store, che compila apk multipli in funzione degli ABI direttamente sul Google Play Store: in questo modo Google Play Store stessa può fornirci degli apk in funzione dell'ABI del nostro smartphone. L'ABI rappresenta una particolare specifica progettuale definita per consentire il funziomanento di un programma su macchine di marche diverse purchè accomunate da un tipo particolare di hardware o di sistema operativo.
+
+Lato iOS, il principale output file ottenibile a valle di una compilazione di un'app ha come estensione IPA che sta per iOS App Package (l'acronimo risponde anche alla definizione iPhone Application prima che Apple rivoluzionasse la lineup dei nomi dei propri sistemi operativi mobile). Come per l'APK, questo file contiene alcuni descrittori del prodotto, questa volta in formato .plist, un formato molto conosciuto nel mondo Apple, e la logica dell'applicazione in formato .app, oltre ad una serie di file aggiuntivi come le icone.
+
+## Il ruolo di chi sviluppa su mobile
+
+Chi sviluppa su mobile è fondamentalmente un full-stack developer le cui competenze sono modellate in modalità Pi-shaped. Sebbene lo sviluppo mobile si possa concretizzare di fatto in una branca del frontend, la necessità di interagire con strumenti molto più a basso livello come i sensori o il dover scrivere logica di business che spesso elabora dati e li memorizza su basi di dati o su storage ospitati localmente al dispositivo, rende questa figura professionale uno specialista del backend. Quale miglior figura condivide sia le competenze backend che quelle frontend se non un full-stack developer? La specializzazione orizzontale del Pi-Shaped invece si concretizzano nel possedere conoscenze minime di UI e UX quando si tratta di disegnare e progettare interfacce grafiche, e di CI/CD quando è necessario compilare e rilasciare gli artefatti sui principali store.
+
+Il percorso di formazione e specializzazione di chi sviluppa su mobile è molto complesso e richiede più competenze trasversali:
+
+- Padronanza dei linguaggi di programmazione: fondamentalmente chi sviluppa mobile deve conoscere più linguaggi di programmazione sebbene lo stesso decida di seguire la strada della programmazione ibrida. Conoscere Kotlin o Swift quando programmiamo con React Native o Flutter ci consente di scrivere moduli nativi quando abbiamo la necessità di interfacciarci con l'hardware di smartphone e tablet
+- Conoscenza del sistema target: per costruire applicazioni accattivanti e funzionali, è necessario conoscere i behavior pattern del sistema operativo di riferimento. Disporre le componenti grafiche in un certo modo all'interno dell'applicazione o sfruttare determinati flussi dettati dalle tecnologie proprietarie del dispositivo consente agli utenti delle nostre app di sentirsi a casa propria quando usano i nostri prodotti.
+- Competenze di ingegneria del software: utilizzare i giusti pattern architetturali, scegliere i design pattern corretti, e scrivere gli algoritmi per la logica di business nel modo giusto consente di realizzare applicazioni robuste, performanti e facilmente estendibili.
+- Conoscenze di basi di dati e storage: spesso e volentieri si renderà necessario memorizzare i dati all'interno di una base di dati o sul file system del dispositivo. Sapere come progettare un database, ottimizare l'indicizzazione dei dati ed eseguire query ottimizzate può avere un forte impatto sulle performance e sull'estendibilità della nostra applicazione
+- Competenze di rete: chi sviluppa su mobile deve essere in grado di costruire client in grado di scambiare i dati con un server remoto in sicurezza e soprattutto deve poter modulare le modalità di presentazione dei dati in funzione della presenza/assenza di connessione
+- Competenze da DevOps: integrare strumenti di test all'interno di un processo di continuous integration finalizzato al rilascio dell'applicazione sui principali store è fondamentale per chi sviluppa su mobile
+- Padronanza di UI/UX: saper riconoscere interfacce ben progettate e ben bilanciate sono ottime skill di contorno che qualunque mobile developer dovrebbe possedere
+
+Sebbene non sia necessario verticalizzarsi su ognuna di queste competenze, è importante avere almeno un'infarinatura di base delle skill che possono poi essere interpretate da altri stakeholders all'interno del proprio team di sviluppo. Una formazione impostata su conoscenze Pi-Shaped in ambito mobile non può che portar giovamento nell'interazione con gli altri attori quali backend engineers, UI/UX designers, DevOps, eccetera.
+
+## Ingegneria del software per lo sviluppo mobile
+
+Secondo [Wikipedia](https://it.wikipedia.org/wiki/Ingegneria_del_software), l' ingegneria del software è quella disciplina informatica che si occupa dei processi produttivi e delle metodologie di sviluppo finalizzate alla realizzazione di sistemi software. Si propone una serie di obiettivi legati all'evoluzione dello sviluppo del software (inteso come attività industriale) sia da un punto di vista tecnologico (per es. attraverso la definizione di nuovi linguaggi di programmazione) che metodologico (per esempio il perfezionamento dei modelli di ciclo di vita del software).
+
+Lo sviluppo mobile prevede di fatto la realizzazione di prodotti software, ed è per questo motivo che sarebbe buona prassi applicare i principi dell'ingegneria del software anche in questo ambito. Ogni linguaggio di programmazione, e quindi ogni SDK, predilige un subset di design pattern e pattern architetturali da utilizzare durante la realizzazione di applicazioni mobile. Elencarli tutti, soprattutto spiegando dettagliatamente il funzionamento e il comportamento di ogni singolo componente, non rientra fra gli obiettivi di questo capitolo. Ci limiteremo a fornire un'infarinatura generale sui principali componenti da utilizzare quando si sceglie di realizzare applicazioni per mobile.
+
+I pattern architetturali più utilizzati sono:
+
+- [Model-View-Controller](https://it.wikipedia.org/wiki/Model-view-controller): Il componente centrale del MVC, il modello, cattura il comportamento dell'applicazione in termini di dominio del problema, indipendentemente dall'interfaccia utente (view). Il modello gestisce direttamente i dati, la logica e le regole dell'applicazione. Una vista può essere una qualsiasi rappresentazione in output di informazioni, come un grafico o un diagramma. Sono possibili viste multiple delle stesse informazioni, come ad esempio un grafico a barre per la gestione e la vista tabellare per l'amministrazione. La terza parte, il controller, accetta l'input e lo converte in comandi per il modello e/o la vista.
+- [Model-View-Viewmodel](https://it.wikipedia.org/wiki/Model-view-viewmodel): Questo pattern propone un ruolo più attivo della View rispetto a MVC: la View è in grado di reagire agli eventi, eseguire operazioni ed effettuare il binding con i dati. In questo contesto, alcune delle funzionalità del Controller vengono integrate nella View, che si basa su un'estensione del Model: il ViewModel. Il ViewModel è un Model esteso con funzionalità per la manipolazione dei dati e per l'interazione con la View
+- Model-View-Presenter: Questo modello rappresenta un’evoluzione dell’MVC e si concentra sulla separazione tra la presentazione dei dati e la logica di business. La differenza principale tra MVC e MVP è la posizione della logica di presentazione. Nell’MVC, il Controller è responsabile della logica di presentazione, mentre nell’MVP è il Presenter ad essere dedicato a questo compito.
+- Model-View-Intent (Android): L'architettura MVI è un pattern architetturale particolarmente utilizzato per la progettazione di interfacce utente in applicazioni basate su framework reattivi. Il modello rappresenta lo stato immutabile dell'applicazione, la view si occupa di visualizzare lo stato dell'applicazione e reagire agli input, e l'intent rappresenta le azioni o gli eventi che possono influenzare lo stato dell'applicazione. Il flusso di dati in MVI è unidirezionale: gli Intent vengono emessi dalla vista, elaborati dal modello per aggiornare lo stato e la vista viene quindi aggiornata per riflettere il nuovo stato.
+- View-Interactor-Presenter (iOS): Introdotto come un'alternativa al popolare pattern MVC per migliorare la separazione delle responsabilità e rendere il codice più testabile e manutenibile. La View è passiva e si occupa solo di visualizzare i dati e trasmettere gli input dell'utente al Presenter, l'Interactor contiene la logica di business dell'applicazione. Gestisce il recupero e la manipolazione dei dati, rispondendo alle richieste provenienti dal Presenter. L'Interactor può comunicare con il Modello (se presente) per ottenere o aggiornare i dati. Il Presenter Si occupa di presentare i dati dalla logica di business (Interactor) alla Vista. Il Presenter riceve gli input dall'utente attraverso la View, comunica con l'Interactor per ottenere i dati necessari, e infine aggiorna la View con le informazioni pertinenti. Il pattern VIP può includere un quarto componente, il model, più semplice e privo di logica di business. Il flusso di dati nel VIP pattern è principalmente unidirezionale.
+- View-Interactor-Presenter-Entity-Router (iOS): È un'evoluzione del pattern VIP, ed introduce due nuovi elementi, l'Entity e il Router. L'Entity rappresenta gli oggetti di dominio dell'applicazione e può contenere la logica di business e sono trasferite tra l'Interactor e il Repository/DataManager. Il Router gestisce la navigazione tra le schermate dell'applicazione e può essere utilizzato per avviare nuovi moduli VIPER e per gestire la navigazione tra essi. Il pattern VIPER cerca di risolvere alcuni dei problemi di separazione di responsabilità che potrebbero sorgere in altre architetture. La chiara separazione delle componenti facilita la comprensione del codice, rende più semplice l'aggiunta di nuove funzionalità e favorisce la testabilità delle singole unità.
+
+I design pattern più utilizzati sono:
+
+- Repository: Incapsula la logica di accesso ai dati, fornendo un'interfaccia comune per recuperare o salvare dati da diverse fonti.
+- Builder: Separa la creazione di un oggetto complesso dalla sua rappresentazione, consentendo la creazione di diverse rappresentazioni dell'oggetto con lo stesso processo di realizzazione.
+- Observer: Definisce una dipendenza uno a molti tra oggetti in modo che quando uno degli oggetti cambia stato, tutti i componenti sottoscritti vengano notificati e aggiornati automaticamente.
+- Dependency Injection: Fornisce un modo per fornire le dipendenze di un oggetto da parte di un'altra parte esterna, spesso attraverso l'iniezione di dipendenze tramite costruttore o metodi.
+- Factory: Definisce un'interfaccia per la creazione di un oggetto, ma lascia la scelta della sua classe di implementazione alle sottoclassi, ritardandone l'inizializzazione a runtime.
+- Adapter: Converte l'interfaccia di una classe in un'altra interfaccia che un client si aspetta di utilizzare, consentendo a classi incompatibili di lavorare insieme.
+- Singleton: Assicura che una classe abbia una sola istanza e fornisce un punto di accesso globale a questa istanza.
+- Facade: Fornisce un'interfaccia unificata a un insieme di interfacce in un sottosistema, semplificando così l'uso e la comprensione di quel sottosistema.
+- Decorator: Aggiunge dinamicamente nuove responsabilità a un oggetto fornendo una serie di oggetti che racchiudono l'oggetto originale.
+- Composite: Consente di trattare oggetti individuali e composizioni di oggetti in modo uniforme, permettendo la creazione di strutture gerarchiche.
+- Command: Incapsula una richiesta come un oggetto, consentendo di parametrizzare le richieste e rendendo le operazioni annullabili.
+- Strategy: Definisce una famiglia di algoritmi, incapsula ciascuno di essi e li rende intercambiabili. Consente all'algoritmo di variare indipendentemente dai clienti che lo utilizzano.
+- State: Permette a un oggetto di modificare il suo comportamento quando il suo stato interno cambia. L'oggetto sembra mutare la sua classe.
+- Delegate: Permette di delegare alcune funzionalità ad un altro oggetto. Questo pattern è particolarmente utile e necessario quando l'oggetto che invoca un’azione è disaccoppiato dall’oggetto che ne implementa il funzionamento.
+
+Anche i framework di sviluppo ibrido hanno la possibilità di interfacciarsi con pattern architetturali e design pattern di vario genere. La maggior parte dei framework ibridi di seconda generazione si basano su pattern che ruotano attorno alla definizione di stato. Ad esempio, su React Native i pattern di state management più utilizzati sono rispettivamente Redux, Hooks e MobX, mentre su Flutter troviamo BLoC, ChangeNotifier e Riverpod.
+
+## Design system per mobile
+
+Un design system è una raccolta di componenti riutilizzabili e standard ben definiti che possono essere utilizzati per costruire graficamente applicazioni. Questi sistemi sono utilizzati nel design e nello sviluppo di prodotti digitali come applicazioni mobile o siti web e possono comprendere librerie di pattern/componenti, linguaggi di design, guide dello stile (carattere, colore, spaziatura, posizionamento), componenti codificati, componenti di brand identity e documentazione.
+
+Essi fungono da punto di riferimento insieme a un linguaggio di design che assicura che i vari team coinvolti nella progettazione e realizzazione di un prodotto creino applicazioni coerenti nell'aspetto e nel comportamento. Fra i principali vantaggi nello scegliere di utilizzare un design system abbiamo un flusso di lavoro più efficiente dalla progettazione alla produzione, la creazione di un linguaggio unificato tra i team interfunzionali, progettazioni più veloci grazie a componenti riutilizzabili, user experience coerente e un linguaggio di design fisso e ben definito. Inoltre, favoriscono una manutenzione ed estendibilità migliore, riducendo il debito di progettazione e tecnico, e offrono un focus più forte per i team di prodotto, consentendo ai team di concentrarsi sulla risoluzione dei bisogni degli utenti.
+
+Un design system è composto da vari elementi, modelli, stili e linee guida che contribuiscono a semplificare ed ottimizzare la fase di progettazione. I fattori critici da considerare nella creazione di un design system hanno a che fare con l'ambito e la capacità di riprodurre i progetti, nonché la disponibilità di risorse e tempo. Se i design system non vengono implementati e mantenuti correttamente, possono diventare disorganizzati, compromettendo l'efficienza del processo di progettazione. Tuttavia, se implementati correttamente, possono semplificare il lavoro, rendere i prodotti finali più coesi e sostenere i progettisti durante le sfide complesse legate all'esperienza utente.
+
+È importante sempre tenere a mente che ci sono differenze sostanziali fra design system, linguaggi di pattern e UI kit. Un linguaggio di pattern consente ai suoi modelli di esistere in molte forme e configurazioni diverse; ad esempio, un modulo di accesso con campi per nome utente e password, e pulsanti per accedere, registrarsi e recuperare la password persa è un modello, indipendentemente dal fatto che i pulsanti siano verdi o viola. I modelli sono chiamati tali proprio perché la loro natura esatta può variare, ma le somiglianze consentono al rapporto tra di essi di rimanere invariato. D'altra parte, un design system ha sempre un insieme di linee guida visive che definiscono colori e tipografia ben precisi. La maggior parte dei design system consente agli elementi di un linguaggio di design di essere configurati in base alle esigenze. Uno UI kit è semplicemente un insieme di componenti dell'interfaccia utente, senza regole esplicite fornite per il suo utilizzo.
+
+I principali linguaggi di design proprietari che possiamo utilizzare su mobile sono rispettivamente Material Design e Human Interface Guidelines, sebbene per quest'ultimo sarebbe più corretto identificarlo come UI kit che come linguaggio di design.
+
+Material Design è un linguaggio di design sviluppato da Google nel 2014. Esso utilizza layout basati su griglie, animazioni e transizioni responsive, padding, ed effetti grafici come luci e ombre. Il principale obiettivo di Material Design è la definizione di un nuovo linguaggio visivo che combina principi di buon design con novità tecniche e scientifiche. La filosofia dietro al Material Design ha a che fare con componenti semplici disegnate con penna su carta e trasformati poi in elementi digitali. Con il passare degli anni, il Material Design si è evoluto dando alla luce prima il Material Design 2, e successivamente il Material Design 3 altresì noto come Material You.
+
+Spostandoci sullo sviluppo mobile per iOS, non abbiamo un vero e proprio design system nonostante Apple abbia ben documentato il proprio processo di definizione delle interfacce grafiche, bensì uno UI kit composto da un insieme di componenti di sistema che ci consentono di disegnare interfacce grafiche interattive e vicine alla filosofia delle applicazioni di sistema di iOS/iPadOS. Fra queste componenti possiamo trovare label, input testuali, bottoni, checkbox e radio button, switch, selettori, liste, card, etc.
+
+Quando si sceglie un design system per realizzare un prodotto mobile non è necessario sceglierne uno proprietario fra quelli menzionati precedentemente. È possibile lasciarsi ispirare da un design system ben definito e rimodellarne lo UI kit, così come è possibile costruirne uno completamente da zero o utilizzare altri modelli più diffusi come il Flat Design. In questo caso l'unico limite è la fantasia.
diff --git a/docs/it/testing.md b/docs/it/testing.md
index 1642c501..e58679bd 100644
--- a/docs/it/testing.md
+++ b/docs/it/testing.md
@@ -1,3 +1,9 @@
+---
+layout: default
+title: Testing
+nav_order: 4
+---
+
# Testing
Il testing è una parte fondamentale di ogni progetto software. In questo capitolo vedremo come testare il nostro codice in modo efficace.
@@ -7,7 +13,7 @@ Il testing è una parte fondamentale di ogni progetto software. In questo capito
Esistono diversi tipi di test, ognuno con un suo scopo ben preciso.
Si fa spesso riferimento alla piramide del testing, che rappresenta la proporzione tra di essi:
-
+![Piramide del testing](/book/assets/images/piramide.svg)
Nel resto del capitolo li vedremo nel dettaglio.
@@ -86,9 +92,9 @@ Esistono molte altre tipologie di test, come _compatibility testing_, _acceptanc
Esistono tre tecniche di test, ognuna con un suo scopo ben preciso. Vediamole brevemente:
-- **Black-box testing**: Il test _black-box_ è una tecnica di test in cui il tester non ha conoscenza dell'implementazione del sistema.
-- **White-box testing**: Il test _white-box_ è una tecnica di test in cui il tester ha conoscenza dell'implementazione del sistema.
-- **Grey-box testing**: Il test _grey-box_ è una tecnica di test in cui il tester ha conoscenza parziale dell'implementazione del sistema.
+- **Black-box testing**: Il test _black-box_ è una tecnica di test in cui il tester non ha conoscenza dell'implementazione del sistema. Il focus è sull'esaminazione del funzionamento dell'applicazione (quindi senza conoscere il codice sorgente) rispetto ai requisiti specificati. Il tester verifica se l'applicazione si comporta come previsto. Questo metodo è applicabile a quasi tutti i tipi di software e sistemi, indipendentemente dai linguaggi o dalla tecnologia utilizzata.
+- **White-box testing**: Il test _white-box_ è una tecnica di test in cui il tester ha conoscenza dell'implementazione del sistema, quindi dell'intero codice sorgente. Questo approccio si concentra sull'esaminare il comportamento interno del software e sul garantire che tutte le vie logiche ed i segmenti di codice siano testati. Il test ha un focus sulla validazione dei percorsi di esecuzione all'interno del codice, assicurando che tutte le condizioni, i cicli ed i percorsi di codice siano testati. Questo metodo è efficace nell'individuare bug specifici nel codice, come errori di logica, infinity loop e istruzioni non raggiunte.
+- **Grey-box testing**: Il test _grey-box_ è una tecnica di test in cui il tester ha conoscenza parziale dell'implementazione del sistema. Questo tipo di testing è particolarmente utile quando si desidera testare il software da una prospettiva esterna, ma con una comprensione sufficiente della sua architettura interna per creare test più mirati ed efficaci. I tester hanno accesso limitato al codice sorgente e alla struttura interna, permettendo loro di comprendere alcuni aspetti dell'architettura del software senza una conoscenza dettagliata. Il _grey-box_ testing si concentra sulle interfaccie e le API del sistema, testando la comunicazione e l'interazione tra diverse unità o moduli. Il vantaggio principale riguarda la maggiore efficienza, data la combinazione di conoscenze interne ed esterne, permettendo di creare test più mirati, aumentando l'efficienza del processo di testing.
Di solito queste tre tecniche vengono utilizzate per individuare eventuali falle nel sistema. Solitamente il _Black-box testing_ è la tecnica più utilizzata, in quanto permette di individuare falle che non sono state individuate durante lo sviluppo e non richiede una conoscenza pregressa del sistema.
@@ -170,3 +176,29 @@ La test coverage è una metrica che indica la percentuale di codice sorgente che
### Over-testing
Altra nota importante è relativa alla _coverage 100%_: solitamente si sconsiglia l'adozione di una coverage così alta in quanto si rischia di incorrere in un fenomeno chiamato _over-testing_, nel quale si testano tutte le possibili casistiche, anche quelle che non hanno senso e che impiegano molto tempo ad essere scritte. Questo fenomeno è molto pericoloso, in quanto si rischia di scrivere codice per il mero raggiungimento di un numero, la coverage appunto, che non aggiunge valore al prodotto e che non soddisfa alcun requisito funzionale o non funzionale.
+
+## Tools e Frameworks per il Testing
+
+Ora che abbiamo esplorato i vari tipi di test e le loro applicazioni, è di fondamentale importanza conoscere gli strumenti e i framework che possono rendere questi processi più efficienti ed efficaci. Ogni tipologia di test può essere supportata e migliorata dall'uso di tool specifici, che aiutano l'automazione dei test stessi, rendendo più semplice la scrittura del codice di test e fornendo feedback più dettagliati sui risultati.
+
+Quelle che seguono sono delle liste non esaustive di strumenti che solitamente vengono presi ad esempio quando si parla di una specifica modalità di testing. Ogni linguaggio ha, nella maggior parte dei casi, più di uno strumento per ogni modalità e il suggerimento, come per tutto ciò che riguarda il mondo dello sviluppo, è quello di sperimentare con ognuno di essi e di prendere delle decisioni informate riguardo a quali utilizzare.
+
+### Strumenti per Unit-Test
+
+- **JUnit**: è un framework di test unitari utilizzato in ambito Java. Ampiamente utilizzato per testare singole classi e metodi con annotazioni intuitive.
+
+- **pytest**: Come deducibile dal nome, pytest è un framework utilizzato in ambiente Python, molto versatile che rende semplice scriver test unitari complessi. Offre funzionalità come la parametrizzazione dei test e i fixtures per configurare il contesto di test.
+
+### Strumenti per Integration Test
+
+- **Postman**: Utilizzato principalmente per testare API. Permette di creare richieste HTTP, impostare vari ambienti di test e verificare le risposte delle API. Molto utile anche in un contesto di embedding.
+
+- **TestNG(Java)**: Fornisce funzionalità avanzate per i test d'integrazione. Inclusa l'esecuzione parallela dei test e la gestione delle dipendenze.
+
+### Strumenti per End-to-End Test
+
+- **Selenium**: È un framework utilizzato per automatizzare i browser web. E' ideale per testare interazioni utente complesse in web app.
+
+- **Cypress**: Una soluzione più moderna per il testing E2E, apprezzata per la sua NON complessità d'uso e l'integrazione con ambienti di sviluppo Javascript.
+
+- **Playwright**: Un altro framework moderno che consente di automatizzare il browser e di eseguire test E2E. Punta molto sulle performance e sull'affidabilità di esecuzione delle azioni sugli elementi in pagina.
diff --git a/docs/it/testing/piramide.png b/docs/it/testing/piramide.png
deleted file mode 100644
index 21b39199..00000000
Binary files a/docs/it/testing/piramide.png and /dev/null differ
diff --git a/docs/it/introduzione.md b/index.md
similarity index 98%
rename from docs/it/introduzione.md
rename to index.md
index 9b6dbfb7..51ac50e1 100644
--- a/docs/it/introduzione.md
+++ b/index.md
@@ -1,3 +1,12 @@
+---
+layout: default
+title: Introduzione
+nav_order: 1
+permalink: /
+---
+
+# Il Libro Open Source
+
## Benvenuto
Chiunque tu sia, da qualunque posto tu provenga, benvenuto in un viaggio incredibile nel mondo dello sviluppo software.