---
# System prepended metadata

title: IVR

---

# IVR
### Lato tecnico

3 October - 1195 BUG 691
15 September - 1120 Cambio messaggi 688
1 September - 1155 BUG
11 August - 1074 Flusso purchase info 701
5 July - 1014 - Flusso documenti  411
13 June - 973 - Flusso documenti  453
2 May - 917 - Flusso documenti 409

Cosa non riuscivamo a fare?
- Partire dal caso dell'ultima modifica su Information che è stato modifica
- Spiegare perchè è stato un problema
- Spiegare come il refactoring abbia migliorato
- Raccogliere metriche a supporto
- Mettere esempi a supporto delle proprie affermazioni, magari mostrando meno argomenti 

#### prima
- L'implementazione era un albero di moduli. 
    - ogni volta che ci si ferma in un punto del albero per richiedere un input all'utente, 
    - si riparte dalla radice una volta che questi ha fornito l'input e non a partire dall'ultimo punto visitato riapplicando tutti gli input già ricevuti e non solo l'ultimo.
- Il codice era diventato estremamente **convoluto** 
    - perchè deve tener conto che per ciascun punto si può passare più volte
    - ma solo al primo passaggio si devono fare azioni (e.g. richiamare servizi esterni, modificare stato interno call) 
    - nelle altre situazioni deve fare da semplice pass-through
- La complicazione del codice aveva negativi effetti collaterali
     - ad avere **moduli grossi** perchè c'era molto accoppiamento nel codice (e bassa coesione). Di fatto spesso ogni flusso era implementato in un singolo modulo (e.g. Information 700+).
    - i **test unitari** erano di conseguenza complicati e ognuno testava più comportamenti: 
        - la fase di setup di ciascuno di essi era enorme, molti mock da programmare => non svolgevano appieno alla loro funzione di documentazione
        - alcuni scenari non avevano una copertura ideale: o per il costo di ogni test o per svista dovuta alla troppa complessità
    - **Problemi di design**: il costo di una modifica cresceva esponenzialmente alla complessità del codice dove si inseriva.
        - *Fragility*: Il codice era fragile, una modifica da una parte poteva creare un bug dall'altra
        - *Rigidity*: una modifica in un punto del sistema forza modifiche anche in altre parti del sistema
        - *Opacity*: il codice era poco leggibile: flussi complessi (e.g. Information) ci voleva grande attenzione, energia e tempo per comprenderli
        - *Immobility*: era difficile disaccoppiare parte di codice utili da altre parti
- Potenziali regressioni quando si doveva lavorare su moduli già esistenti 
 
- **Dopo**
- Con l'introduzione della **FSM** adesso viene salvato l'ultimo modulo visitato prima di chiedere qualche input al customer e quando questi dà un
nuovo input si riparte dall'ultimo modulo visitato
    - Le responsabilità sono distribuite su più moduli e ognuno è molto più granulare (non ancora single responsability ma si può migliorare)
    - codice più leggibile, meno fragile, meno rigido, meno immobile
    - i test unitari sono molto più semplici e comprensibili (uso libreria Mock) => svolgono appieno il loro compito di documentazione
    - i test unitari hanno una copertura maggiore perchè il codice da testare è più semplice
    - Permette i cicli (e.g. vedi ultimo sviluppo sul queue loop CMOEX-35)
    - **Mettere qualche nota su possibili potenzialità future della FSM?**
### Lato processo di sviluppo

- test di accettazione
    - **Prima**
        - Non erano specificati in fase di creazione della card 
        - per ogni card al momento della fase di testing veniva specificato tra tester e developer cosa doveva essere testato e cosa no.
        - di solito era ampio il set di scenari di test a causa della fragilità del codice (**NO**)
        - più tempo dedicato al testing manuale (**NO**)
    - **Dopo**
        - **Gherkhin tests**: i test sono specificati prima che la card vada in progress
        - E' più facile valutare la profondità dell'impatto di una card perchè il numero di test è una misura della complessità del lavoro
        - Con la FSM siamo molto più confidenti che una modifica impatti solo nel punto del grafo dove è applicata. Vengono fatti meno test di non-regressione (**NO**)

- Diagrammi IVR
    - **Prima**
        - scritti prima dell'implementazione da parte di persone del business
        -      => non sempre chiari per uno sviluppatore
        - non rispecchiavano come venivano poi implementati su codice
        - a posteriori integrate da post-it che peggioravano la leggibilità
        - tendevano a non essere aggiornati in modo adeguato
    - **Dopo**
        - scritti a 4 mani tra una persona del business e una di sviluppo
        - sono più descrittivi che in precedenza
        - rispecchiano il workflow implementato sul codice
        - sono il punto di contatto tra business e development
        - (per il momento) sono continuamente aggiornati e in sync col codice



### IVR implementato come un albero di moduli.

Funzionamento:
Si parte dal nodo radice
Quando c'è bisogno di un input ci si ferma
Non viene salvato lo stato
Quando viene fornito l'input si riparte comunque dalla radice riapplicando tutti gli input ricevuti durante la chiamata.
Bisognava garantire che ripartendo dalla radice dopo ogni nuovo input
 si ripercorresse lo stesso percorso precedente
 si evitassero di rifare chiamate esterne
l'aggregato della Call era diventato uno stato mutabile per evitare side-effects


### Breakthrough

Consapevolezza che a lungo andare non saremmo riusciti a soddisfare i desideri del business e i requisiti di qualità
Certezza che nel 2023 ci sarebbero stati rami nuovi.
Lato tecnico siamo stati proattivi proponendo una pura riscrittura dell'esistente nessun cambiamento di comportamento
Il business ha acconsentito di fermare le evoluzioni IVR in Q1


### Solution implemented

IVR è implementato come un grafo di moduli.
Si parte dal nodo radice
Quando c'è bisogno di un input ci si ferma e viene salvato lo stato nella tabella DB della Call
Quando viene fornito l'input si riparte dall stato salvato in precedenza (as videogame)


### Presentazione

Benvenuti a questa presentazione dove racconteremo le evoluzioni tecniche che ci sono state sull'IVR di Squillo.

Premessa: 
- I'll try to do my best shot but if something is not clear enough, please stop me. For any other curiosity or further details please wait the end of the presentation to ask them


### 1 A bit of history
- Squillo è andato online la prima volta Nov. 2020
- Inizialmente era un router dove a secondo dei digit premuti finivi in un flusso e poi inevitabilmente ad un operatore.
- Col tempo una serie di automazioni via via più complesse sono state introdotte per dare informazioni ai clienti senza coinvolgere l'operatore e senza far aspettare il customer

### 2 what was going on at that time?

**But when we start implementing features that were not foreseen when the design was conceived the problems started to arrive.**

Nei metodi agili non si fa design “up front” ma si fa “design continuo”, ovvero “design evolutivo” (evolutionary design): il design del sistema cresce man mano che il sistema stesso viene realizzato. 
Questo ci consente di mantenere il sw in uno stato tale da essere sempre modificabile a basso costo. (**Evolutionary design allows us to keep the sw in a state where it can always be modified at low cost.**)

Il design è parte del processo di sviluppo, e man mano che il programma evolve, il design cambia ed evolve di pari passo.


### 3 Consequences for the business

- I primi due punti erano a seguito del debito tecnico accumulato
- **Before that moment we had realised the limitations of the system**
- Il terzo era già noto che troppo complessità era ingestibile
- In ogni caso aveva dei limiti

- to keep riding the same route meant that development times would have become longer and less predictable 
### 4 How did it work?

Perchè Il design dll'IVR era diventato un problema? Perchè prima andava bene e poi non più fino al punto di non essere in grado di fare più nulla? Come funzionava?

Premessa: 
    - Prendiamo il caso di un utente che chiama per avere informazioni sul rimborso di una policy interruption?
        Il caso è semplificato rispetto alla realtà
    - Per far vedere come funzionava vi mostrerò 
        - una astrazione del nostro flusso IVR come era implementato e come veniva percorso 
        - i dati collezionati nel frattempo
        
#### 4.4 

Notate che dove c'è automazione c'è complessità e i dati servono per dare informazioni

Ma cosa succede se il customer non è soddisfatto e vuole parlare con un operatore?

#### 4.5

Voglio fare lo stesso percorso precedente ma evitando di fare dispendiose chiamate esterne già fatte.
Per far questo introduco molta logica condizionale e mi serve conservare dati.

Tutto questo perchè parto dall'inizio a ripercorrere il flusso IVR: ma mi serve? Non è che questa è solo needless complexity.

### 5 Implementation issues

### 6 the breakthrough

- Consapevolezza che a lungo andare non saremmo riusciti a soddisfare i desideri del business e i requisiti di qualità
- Certezza che nel 2023 ci sarebbero stati rami nuovi.
- Lato tecnico siamo stati proattivi proponendo una pura riscrittura dell'esistente nessun cambiamento di comportamento
- Il business ha acconsentito di fermare le evoluzioni IVR in Q1

### 7 Solution proposed: FSM

- In questa nuova soluzione si è cercato di rimuovere quella che era una needless complexity: partire sempre dalla radice nel percorrere il flusso IVR
- Ogni volta che ci ferma si salva il modulo dove ci si ferma nella call


### How we improved are way of warking

Previously, diagrams were written by a person from the business. 
- They were high level, 
- there were not so many details
- During implementation to know details developers kept asking to business
- After implementation they were no good as documentation. It was so easy to misunderstand


Now IVR diagrams are written by a person from the business and one from development. 
- take into account the views of both parties in all details.
- they are much more precise 
