Skip to content

Commit 4178bee

Browse files
committed
Aggiunta campo "Stato" nei metadati delle annotazioni nelle tabelle
1 parent 09b1989 commit 4178bee

File tree

61 files changed

+2747
-1184
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2747
-1184
lines changed

README.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -756,25 +756,28 @@ Questa modalità consente di eseguire l'intero stack annotazioni su AWS ECS con
756756
- ✅ ⚙️ Creazione progetto con maven, creazione dei moduli adapter, adapter web con pagina web di esempio, test generale di esecuzione
757757
- ✅ 📝 Funzione di modifica annotazioni con registro con precedenti versioni delle note
758758
- ✅ 📖 Configurazione di OpenApi-Swagger e Quality-SonarQube, test coverage e compilazione dei moduli
759-
- ✅ 🤖 Modifica nome dell'applicazione in *gestione personale* e test applicazione web di esempio
760-
- ✅ 🛠️ Modifica nome dell'applicazione in *gestione annotazioni* e test applicazione web di esempio anche su AWS
761-
- ✅ 🔧 Modifica nome adapter "app" e "port" in "application" e "core"
762-
- ✅ 🎯 Creazione portService, modifica ai Controller-api e spostamento logiche dai Controller nei Service nel core
763-
- 🚧 🔧 Nuove tabelle Stati (nome, descrizione, utente) e Cagetoria (nome)
764-
- 🚧 🧩 Service per aggiungere le categorie e interfaccia API per permettere ad AMIN di creare le categorie
765-
- 🚧 🔄 Aggiunta campo "Stato" nei metadati delle annotazioni
766-
- 🚧 🧿 Script per aggiungere stati e categorie all'avvio dell'infrastruttura, creazione di tre profili in ogni ambiente!
767-
- 🚧 🧮 Nuova tabella StoricoStati (id, ...)
768-
- 🚧 🕸️ Service per cambio stato che modifica solo il metadata e non il valore ma salva nella tabella storico
769-
- 🚧 🧑‍🔬 Solo chi ha profilo USER può inserire una nota: contollo lato API e l'annotazione va in stato INSERITA
770-
- 🚧 🛰️ Solo chi ha profilo MODERATOR può confermare una nota: contollo lato API e l'annotazione va in stato CONFERMATA
771-
- 🚧 🛡️ Solo chi ha profilo MODERATOR può rifiutare una nota e metterla in stato RIFIUTATA
772-
- 🚧 🧱 Una annotazione già esistente è modificabile da chiunque solo se è in INSERITA e/o RIFIUTATA
773-
- 🚧 🧬 Solo chi ha profilo ADMIN può pubblicare la annotazione che va in stato PUBBLICATA oppure RIFIUTATA
774-
- 🚧 🧭 Quando una annotazione è in stato PUBBLICATA solo ADMIN può rimetterla in RIFIUTATA
775-
- 🚧 🧑‍🤝‍🧑 Elenco task: utenti USER vedono le annotazioni RIFIUTATE con la possiblità di cambiarle in INSERITA
776-
- 🚧 🗃️ Elenco task: utenti MODERATOR vedono le annotazioni INSERITA con la possibiltà di rifiutarle o confermarle
777-
- 🚧 🏁 Elenco task: utenti ADMIN vedono le annotazioni CONFERMATA con la possiblità di pubblicarle
759+
- ✅ 📦 Creazione adapter con implementazione con SQLite come unica base dati
760+
- ✅ ☁️ Sviluppo script per esecuzione profilo sqlite in sistema Replit
761+
- ✅ ⚙️ Sviluppo script per esecuzione profilo sqlite in sistema AWS-EC2 con Docker senza RDS e Dynamo
762+
- ✅ 🤖 Gestione dell'applicazione in *gestione annotazioni* e test applicazione web di esempio
763+
- ✅ 🛠️ Test applicazione web di esempio anche su AWS
764+
- ✅ 🔧 Modifica nome adapter "app" e "port" in "application" e "core"
765+
- ✅ 🎯 Creazione portService, modifica ai Controller-api e spostamento logiche dai Controller nei Service nel core
766+
- ✅ 🔧 Creazione enum Stato di una annotazione
767+
- ✅ 🔄 Aggiunta campo "Stato" nei metadati delle annotazioni nelle tabelle
768+
- ✅ 🧮 Nuova tabella StoricoStati, sviluppo service e port per la gestione dello storico
769+
- ✅ 🕸️ Modifica service per cambio stato che modifica il metadata e non il valore più la tabella storico
770+
- ✅ 🧩 Service per modificar lo stato con salvataggio nella tabella StoricoStati
771+
- 🚧 🧿 Script per creazione di tre profili in ogni ambiente
772+
- ✅ 🧑‍🔬 Inserimento di una nuova annotazione in stato INSERITA
773+
- 🚧 🛰️ Gestione delle annotazioni quando son in CONFERMATA
774+
- 🚧 🛡️ Gestione delle annotazioni in stato RIFIUTATA o BANNATA
775+
- 🚧 🧱 Verifica che utenti non possano fare operazioni il cui ruolo non lo prevede
776+
- 🚧 🧬 Gestione delle annotazioni instato PUBBLICATA
777+
- 🚧 🧭 Quando una annotazione è in stato PUBBLICATA solo ADMIN può rimetterla in RIFIUTATA
778+
- 🚧 🧑‍🤝‍🧑 Elenco task: utenti USER vedono le annotazioni RIFIUTATE con la possiblità di cambiarle in INSERITA
779+
- 🚧 🗃️ Elenco task: utenti MODERATOR vedono le annotazioni INSERITA con la possibiltà di rifiutarle o confermarle
780+
- 🚧 🏁 Elenco task: utenti ADMIN vedono le annotazioni CONFERMATA con la possiblità di pubblicarle
778781
- ✅ 🐳 Build e deploy su DockerHub della versione *OnPrem*
779782
- ✅ 🐳 configurazione di docker-compose con MongoDb e Postgresql
780783
- ✅ ☸️ Esecuzione su Kubernetes/Minikube locale con yaml dedicati
@@ -784,9 +787,6 @@ Questa modalità consente di eseguire l'intero stack annotazioni su AWS ECS con
784787
- 🚧 🐳 Deploy su AWS su EKS
785788
- 🚧 🔧 Sistem di Deploy con Kubernetes Helm charts
786789
- 🚧 📈 Auto-Scaling Policies: Horizontal Pod Autoscaler (HPA) e Vertical Pod Autoscaler (VPA) per Kubernetes
787-
- ✅ 📦 Creazione adapter con implementazione con SQLite come unica base dati
788-
- ✅ ☁️ Sviluppo script per esecuzione profilo sqlite in sistema Replit
789-
- ✅ ⚙️ Sviluppo script per esecuzione profilo sqlite in sistema AWS-EC2 con Docker senza RDS e Dynamo
790790
- ✅ 🔒 Autenticazione e autorizzazione (Spring Security) e token Jwt
791791
- ✅ 👥 introduzione sistema di verifica degli utenti e validazione richieste con tabella utenti
792792
- ✅ 📝 Gestione multiutente e modifica annotazioni con utente diverso dal creatore, test nell'applicazione web
@@ -800,7 +800,7 @@ Questa modalità consente di eseguire l'intero stack annotazioni su AWS ECS con
800800
- 🚧 ⚡ Redis Caching Layer: Cache multi-livello (L1: in-memory, L2: Redis) con invalidation strategies e cache warming
801801
- 🚧 📊 Read Replicas: Separazione read/write con eventual consistency e load balancing intelligente
802802
- 🚧 👥 Social Reminders: Notifiche quando qualcuno interagisce con annotazioni modificate
803-
- 🚧 💾 Backup & Disaster Recovery: Cross-region backup, point-in-time recovery, RTO/RPO compliance
803+
- 🚧 💾 Backup & Disaster Recovery: Cross-region backup, point-in-time recovery, RTO/RPO compliance
804804
- 🚧 🔒 API Rate Limiting: Rate limiting intelligente con burst allowance, IP whitelisting, geographic restrictions
805805
- 🚧 🔍 Elasticsearch Integration: Ricerca full-text avanzata con highlighting, auto-complete, ricerca semantica
806806
- 🚧 🏗️ GitOps Workflow: ArgoCD/Flux per deployment automatici, configuration drift detection

adapter-api/src/main/java/it/alnao/springbootexample/api/controller/AnnotazioneController.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
import io.swagger.v3.oas.annotations.tags.Tag;
88
import it.alnao.springbootexample.api.dto.AggiornaAnnotazioneRequest;
99
import it.alnao.springbootexample.api.dto.AnnotazioneResponse;
10+
import it.alnao.springbootexample.api.dto.CambiaStatoAnnotazioneRequest;
1011
import it.alnao.springbootexample.api.dto.CreaAnnotazioneRequest;
12+
import it.alnao.springbootexample.api.dto.TransizioneStatoResponse;
1113
import it.alnao.springbootexample.api.mapper.AnnotazioneMapper;
14+
import it.alnao.springbootexample.api.mapper.TransizioneStatoMapper;
1215
import it.alnao.springbootexample.core.domain.AnnotazioneCompleta;
16+
import it.alnao.springbootexample.core.domain.StatoAnnotazione;
1317
import it.alnao.springbootexample.core.portService.AnnotazioniPortService;
1418
import jakarta.validation.Valid;
1519
import org.slf4j.Logger;
@@ -139,6 +143,23 @@ public ResponseEntity<List<AnnotazioneResponse>> ottieniAnnotazioniPubbliche() {
139143
return ResponseEntity.ok(AnnotazioneMapper.toResponseList(annotazioni));
140144
}
141145

146+
@Operation(summary = "Ottieni annotazioni per stato")
147+
@GetMapping("/stato/{stato}")
148+
public ResponseEntity<List<AnnotazioneResponse>> ottieniAnnotazioniPerStato(
149+
@Parameter(description = "Stato delle annotazioni")
150+
@PathVariable String stato) {
151+
152+
logger.info("GET /api/annotazioni/stato/{} - Richiesta annotazioni per stato", stato);
153+
try {
154+
StatoAnnotazione statoEnum = StatoAnnotazione.valueOf(stato.toUpperCase());
155+
List<AnnotazioneCompleta> annotazioni = annotazioniPortService.trovaPerStato(statoEnum);
156+
return ResponseEntity.ok(AnnotazioneMapper.toResponseList(annotazioni));
157+
} catch (IllegalArgumentException e) {
158+
logger.error("GET /api/annotazioni/stato/{} - Stato non valido: {}", stato, e.getMessage());
159+
return ResponseEntity.badRequest().build();
160+
}
161+
}
162+
142163
@Operation(summary = "Ottieni statistiche delle annotazioni")
143164
@GetMapping("/statistiche")
144165
public ResponseEntity<StatisticheResponse> ottieniStatistiche() {
@@ -151,6 +172,70 @@ public ResponseEntity<StatisticheResponse> ottieniStatistiche() {
151172

152173
return ResponseEntity.ok(statistiche);
153174
}
175+
176+
@Operation(summary = "Ottieni tutte le transizioni di stato configurate")
177+
@ApiResponses(value = {
178+
@ApiResponse(responseCode = "200", description = "Lista delle transizioni ottenuta con successo"),
179+
@ApiResponse(responseCode = "500", description = "Errore interno del server")
180+
})
181+
@GetMapping("/transizioni-stato")
182+
public ResponseEntity<List<TransizioneStatoResponse>> ottieniTransizioniStato() {
183+
logger.info("GET /api/annotazioni/transizioni-stato - Richiesta lista transizioni di stato");
184+
185+
try {
186+
List<TransizioneStatoResponse> transizioni = TransizioneStatoMapper.toResponseList(
187+
annotazioniPortService.listaCambiamentiStati()
188+
);
189+
190+
logger.info("GET /api/annotazioni/transizioni-stato - Restituite {} transizioni", transizioni.size());
191+
return ResponseEntity.ok(transizioni);
192+
193+
} catch (Exception e) {
194+
logger.error("GET /api/annotazioni/transizioni-stato - Errore: {}", e.getMessage());
195+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
196+
}
197+
}
198+
199+
@Operation(summary = "Cambia lo stato di un'annotazione")
200+
@ApiResponses(value = {
201+
@ApiResponse(responseCode = "200", description = "Stato cambiato con successo"),
202+
@ApiResponse(responseCode = "400", description = "Dati di input non validi o transizione non permessa"),
203+
@ApiResponse(responseCode = "404", description = "Annotazione o utente non trovato"),
204+
@ApiResponse(responseCode = "403", description = "Utente non autorizzato per questa transizione")
205+
})
206+
@PatchMapping("/{id}/stato")
207+
public ResponseEntity<AnnotazioneResponse> cambiaStato(
208+
@Parameter(description = "ID dell'annotazione")
209+
@PathVariable UUID id,
210+
@Valid @RequestBody CambiaStatoAnnotazioneRequest request) {
211+
212+
logger.info("PATCH /api/annotazioni/{}/stato - Cambio stato da {} a {} per utente: {}",
213+
id, request.getVecchioStato(), request.getNuovoStato(), request.getUtente());
214+
215+
try {
216+
StatoAnnotazione vecchioStato = StatoAnnotazione.valueOf(request.getVecchioStato());
217+
StatoAnnotazione nuovoStato = StatoAnnotazione.valueOf(request.getNuovoStato());
218+
219+
AnnotazioneCompleta annotazioneAggiornata = annotazioniPortService.cambiaStato(
220+
id, vecchioStato, nuovoStato, request.getUtente()
221+
);
222+
223+
logger.info("PATCH /api/annotazioni/{}/stato - Stato cambiato con successo da {} a {}",
224+
id, request.getVecchioStato(), request.getNuovoStato());
225+
226+
return ResponseEntity.ok(AnnotazioneMapper.toResponse(annotazioneAggiornata));
227+
228+
} catch (IllegalArgumentException e) {
229+
logger.error("PATCH /api/annotazioni/{}/stato - Errore validazione: {}", id, e.getMessage());
230+
return ResponseEntity.badRequest().build();
231+
} catch (IllegalStateException e) {
232+
logger.error("PATCH /api/annotazioni/{}/stato - Transizione non permessa: {}", id, e.getMessage());
233+
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
234+
} catch (Exception e) {
235+
logger.error("PATCH /api/annotazioni/{}/stato - Errore interno: {}", id, e.getMessage());
236+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
237+
}
238+
}
154239

155240
// Classe interna per le statistiche
156241
public static class StatisticheResponse {

adapter-api/src/main/java/it/alnao/springbootexample/api/controller/auth/AuthController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public ResponseEntity<JwtResponse> loginLocal(@Valid @RequestBody LoginRequest r
8080
logger.info("POST /api/auth/login - Ultimo login aggiornato per username: {}", request.getUsername());
8181

8282
JwtResponse response = new JwtResponse(token, user.getUsername(), user.getEmail(),
83-
user.getAccountType(), 86400L); // 24 ore
83+
user.getAccountType(), user.getRole().getRoleName(), 86400L); // 24 ore
8484

8585
logger.info("POST /api/auth/login - Login completato con successo per username: {}", request.getUsername());
8686
return ResponseEntity.ok(response);

adapter-api/src/main/java/it/alnao/springbootexample/api/dto/AnnotazioneResponse.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class AnnotazioneResponse {
2020
private String tags;
2121
private Boolean pubblica;
2222
private Integer priorita;
23+
private String stato;
2324

2425
// Constructors
2526
public AnnotazioneResponse() {}
@@ -120,4 +121,12 @@ public Integer getPriorita() {
120121
public void setPriorita(Integer priorita) {
121122
this.priorita = priorita;
122123
}
124+
125+
public String getStato() {
126+
return stato;
127+
}
128+
129+
public void setStato(String stato) {
130+
this.stato = stato;
131+
}
123132
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package it.alnao.springbootexample.api.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.NotNull;
6+
7+
/**
8+
* DTO per la richiesta di cambio stato di un'annotazione
9+
*/
10+
@Schema(description = "Richiesta di cambio stato annotazione")
11+
public class CambiaStatoAnnotazioneRequest {
12+
13+
@NotNull(message = "Il vecchio stato è obbligatorio")
14+
@Schema(description = "Stato attuale dell'annotazione", example = "INSERITA")
15+
private String vecchioStato;
16+
17+
@NotNull(message = "Il nuovo stato è obbligatorio")
18+
@Schema(description = "Nuovo stato dell'annotazione", example = "CONFERMATA")
19+
private String nuovoStato;
20+
21+
@NotBlank(message = "L'utente è obbligatorio")
22+
@Schema(description = "Username dell'utente che effettua il cambio", example = "admin")
23+
private String utente;
24+
25+
// Costruttori
26+
public CambiaStatoAnnotazioneRequest() {}
27+
28+
public CambiaStatoAnnotazioneRequest(String vecchioStato, String nuovoStato, String utente) {
29+
this.vecchioStato = vecchioStato;
30+
this.nuovoStato = nuovoStato;
31+
this.utente = utente;
32+
}
33+
34+
// Getters e Setters
35+
public String getVecchioStato() {
36+
return vecchioStato;
37+
}
38+
39+
public void setVecchioStato(String vecchioStato) {
40+
this.vecchioStato = vecchioStato;
41+
}
42+
43+
public String getNuovoStato() {
44+
return nuovoStato;
45+
}
46+
47+
public void setNuovoStato(String nuovoStato) {
48+
this.nuovoStato = nuovoStato;
49+
}
50+
51+
public String getUtente() {
52+
return utente;
53+
}
54+
55+
public void setUtente(String utente) {
56+
this.utente = utente;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return "CambiaStatoAnnotazioneRequest{" +
62+
"vecchioStato='" + vecchioStato + '\'' +
63+
", nuovoStato='" + nuovoStato + '\'' +
64+
", utente='" + utente + '\'' +
65+
'}';
66+
}
67+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package it.alnao.springbootexample.api.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
/**
6+
* DTO per rappresentare una transizione di stato nelle risposte API
7+
*/
8+
@Schema(description = "Rappresenta una transizione di stato permessa con le regole di autorizzazione")
9+
public class TransizioneStatoResponse {
10+
11+
@Schema(description = "Stato di partenza dell'annotazione", example = "INSERITA")
12+
private String statoPartenza;
13+
14+
@Schema(description = "Stato di arrivo dell'annotazione", example = "MODIFICATA")
15+
private String statoArrivo;
16+
17+
@Schema(description = "Ruolo utente richiesto per questa transizione", example = "USER")
18+
private String ruoloRichiesto;
19+
20+
@Schema(description = "Descrizione della transizione", example = "Utente può modificare la propria annotazione")
21+
private String descrizione;
22+
23+
public TransizioneStatoResponse() {
24+
}
25+
26+
public TransizioneStatoResponse(String statoPartenza, String statoArrivo, String ruoloRichiesto, String descrizione) {
27+
this.statoPartenza = statoPartenza;
28+
this.statoArrivo = statoArrivo;
29+
this.ruoloRichiesto = ruoloRichiesto;
30+
this.descrizione = descrizione;
31+
}
32+
33+
public String getStatoPartenza() {
34+
return statoPartenza;
35+
}
36+
37+
public void setStatoPartenza(String statoPartenza) {
38+
this.statoPartenza = statoPartenza;
39+
}
40+
41+
public String getStatoArrivo() {
42+
return statoArrivo;
43+
}
44+
45+
public void setStatoArrivo(String statoArrivo) {
46+
this.statoArrivo = statoArrivo;
47+
}
48+
49+
public String getRuoloRichiesto() {
50+
return ruoloRichiesto;
51+
}
52+
53+
public void setRuoloRichiesto(String ruoloRichiesto) {
54+
this.ruoloRichiesto = ruoloRichiesto;
55+
}
56+
57+
public String getDescrizione() {
58+
return descrizione;
59+
}
60+
61+
public void setDescrizione(String descrizione) {
62+
this.descrizione = descrizione;
63+
}
64+
}

adapter-api/src/main/java/it/alnao/springbootexample/api/dto/auth/JwtResponse.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class JwtResponse {
1212
private String username;
1313
private String email;
1414
private AccountType accountType;
15+
private String role;
1516
private List<String> linkedProviders;
1617
private String tokenType = "Bearer";
1718
private long expiresIn;
@@ -25,11 +26,12 @@ public JwtResponse(String token, String username, AccountType accountType) {
2526
this.accountType = accountType;
2627
}
2728

28-
public JwtResponse(String token, String username, String email, AccountType accountType, long expiresIn) {
29+
public JwtResponse(String token, String username, String email, AccountType accountType, String role, long expiresIn) {
2930
this.token = token;
3031
this.username = username;
3132
this.email = email;
3233
this.accountType = accountType;
34+
this.role = role;
3335
this.expiresIn = expiresIn;
3436
}
3537

@@ -66,6 +68,14 @@ public void setAccountType(AccountType accountType) {
6668
this.accountType = accountType;
6769
}
6870

71+
public String getRole() {
72+
return role;
73+
}
74+
75+
public void setRole(String role) {
76+
this.role = role;
77+
}
78+
6979
public List<String> getLinkedProviders() {
7080
return linkedProviders;
7181
}
@@ -96,6 +106,7 @@ public String toString() {
96106
"username='" + username + '\'' +
97107
", email='" + email + '\'' +
98108
", accountType=" + accountType +
109+
", role='" + role + '\'' +
99110
", tokenType='" + tokenType + '\'' +
100111
", expiresIn=" + expiresIn +
101112
'}';

adapter-api/src/main/java/it/alnao/springbootexample/api/mapper/AnnotazioneMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public static AnnotazioneResponse toResponse(AnnotazioneCompleta annotazioneComp
7878
response.setTags(annotazioneCompleta.getMetadata().getTags());
7979
response.setPubblica(annotazioneCompleta.getMetadata().getPubblica());
8080
response.setPriorita(annotazioneCompleta.getMetadata().getPriorita());
81+
response.setStato(annotazioneCompleta.getMetadata().getStato());
8182
}
8283

8384
return response;

0 commit comments

Comments
 (0)