Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1615f8e
create Word class and controller
AlbertProfe Jan 10, 2025
55f09b9
add repository and application.properties
AlbertProfe Jan 10, 2025
17056d0
create controller word method get all words
AlbertProfe Jan 10, 2025
4116bbd
spring boot rest controller docs
AlbertProfe Jan 10, 2025
8f2660e
renaming files
AlbertProfe Jan 10, 2025
5cbb18b
renaming files
AlbertProfe Jan 10, 2025
656ac27
WordController comments
AlbertProfe Jan 16, 2025
0b15c36
test with JUnit to word entity
AlbertProfe Jan 16, 2025
b5c117a
spring docs-resources images project structure
AlbertProfe Jan 16, 2025
aa68930
spring docs-resources test JUnit word
AlbertProfe Jan 16, 2025
0eb0b0f
db local
AlbertProfe Jan 17, 2025
557b0d6
new folder Test Junit
AlbertProfe Jan 17, 2025
f596df5
basic wordController CRUD
AlbertProfe Jan 17, 2025
8fd89c9
H2 local db and word controller
AlbertProfe Jan 17, 2025
8fdc1ad
move md
AlbertProfe Jan 17, 2025
6c6a27e
doc: containers and pronunciationApp-v0.1
AlbertProfe Jan 23, 2025
50b30db
feat: refactor controller and repository
AlbertProfe Jan 23, 2025
052eeef
doc: spring boot for 5yo
AlbertProfe Jan 23, 2025
bc9c5ee
fix: getWordByPhoneticSpelling at WordRepository pronunciation fields…
AlbertProfe Jan 23, 2025
c4bc3db
feat: createWords and deleteAllWords
AlbertProfe Jan 23, 2025
52be154
doc: styling docs
AlbertProfe Jan 23, 2025
04dde27
doc: annotations
AlbertProfe Jan 24, 2025
7685ec5
doc: add mock-data script
AlbertProfe Jan 24, 2025
eea3805
doc: image h2 with mock data
AlbertProfe Jan 24, 2025
90e659a
feat: refactor with ResponseEntity, headers and optional
AlbertProfe Jan 24, 2025
ec64ac1
doc: import .csv to H2 DB
AlbertProfe Jan 24, 2025
bc73644
feat: complete user CRUD with validation
bielidev Feb 2, 2025
ba7fa58
modify gitignore
bielidev Feb 2, 2025
3a716e5
practice finished
bielidev Mar 9, 2025
0d3d436
small fixes
bielidev Mar 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
.idea
pronunciationDB
51 changes: 51 additions & 0 deletions backend/pronunciationAppBack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@


# Descripción
Este PR introduce mejoras en la estructura de datos de la aplicación Spring Boot, enfocándose en la optimización del modelo de entidades y la correcta implementación de relaciones en JPA. Se han creado las relaciones One-to-One, Many-to-Many, One-to-Many y Many-to-One. Además, se han implementado pruebas para validar el correcto funcionamiento del sistema.


1. **Revisar y Mejorar Model v0.2**
- Se ha analizado el diagrama de clases proporcionado.
- Se han identificado mejoras o relaciones faltantes.
- Se ha actualizado el modelo según sea necesario.

2. **Implementar One-to-One: User y GameProgress**
- Se ha creado una relación bidireccional **One-to-One**.
- Se ha definido a **User** como el lado propietario de la relación.
- Se han utilizado las anotaciones adecuadas de JPA (`@OneToOne`, `@JoinColumn`).

3. **Crear Many-to-Many: Word y Category**
- Se ha implementado una relación **Many-to-Many**.
- Se ha creado una tabla de unión utilizando la anotación `@JoinTable`.
- Se ha configurado la relación bidireccional si era necesario.

4. **Implementar One-to-Many y Many-to-One Relationships**
- Se han identificado e implementado todas las relaciones **One-to-Many** y **Many-to-One** a partir del diagrama de clases.
- Se han utilizado las anotaciones correspondientes (`@OneToMany`, `@ManyToOne`).
- Se han configurado los tipos de cascada y estrategias de recuperación adecuadas.

5. **Configurar Anotaciones de JPA**
- Se han asegurado que todas las entidades tengan las anotaciones adecuadas de JPA.
- Se ha configurado `@Id, @GeneratedValue` para las claves primarias.
- Se han utilizado `@Column` para configuraciones específicas de las columnas.

6. **Crear Interfaces de Repositorio**
- Se han desarrollado interfaces `JpaRepository` para cada entidad.
- Se han añadido métodos de consulta personalizados si era necesario.

7. **Implementar Métodos Básicos de Servicio**
- Se han creado clases de servicio para cada entidad.
- Se han implementado operaciones **CRUD** en la capa de servicio.

8. **Probar Relaciones**
- Se ha creado una clase de prueba para poblar la base de datos con datos de muestra.
- Se ha verificado que todas las relaciones funcionan correctamente.
- Se han probado las operaciones en cascada y las estrategias de recuperación.

---

## Capturas

### **Análisis y Mejora del Modelo**
> **Diagrama de clases actualizado**
![Class Diagram](screenshots/newModelUml.png)
9 changes: 9 additions & 0 deletions backend/pronunciationAppBack/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand Down Expand Up @@ -65,6 +70,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Binary file added backend/pronunciationAppBack/screenshots/bdh2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/attempts")
public class AttemptController {

@Autowired
private AttemptService attemptService;

@PostMapping
public ResponseEntity<Attempt> createAttempt(@RequestBody Attempt attempt) {
Attempt createdAttempt = attemptService.createAttempt(attempt);
return ResponseEntity.ok(createdAttempt);
}

@GetMapping("/{id}")
public ResponseEntity<Attempt> getAttemptById(@PathVariable Long id) {
Optional<Attempt> attempt = attemptService.getAttemptById(id);
return attempt.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<Attempt>> getAllAttempts() {
List<Attempt> attempts = attemptService.getAllAttempts();
return ResponseEntity.ok(attempts);
}

@PutMapping("/{id}")
public ResponseEntity<Attempt> updateAttempt(@PathVariable Long id, @RequestBody Attempt attemptDetails) {
Attempt updatedAttempt = attemptService.updateAttempt(id, attemptDetails);
if (updatedAttempt != null) {
return ResponseEntity.ok(updatedAttempt);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteAttempt(@PathVariable Long id) {
attemptService.deleteAttempt(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/categories")
public class CategoryController {

@Autowired
private CategoryService categoryService;

@PostMapping
public ResponseEntity<Category> createCategory(@RequestBody Category category) {
Category createdCategory = categoryService.createCategory(category);
return ResponseEntity.ok(createdCategory);
}

@GetMapping("/{id}")
public ResponseEntity<Category> getCategoryById(@PathVariable Long id) {
Optional<Category> category = categoryService.getCategoryById(id);
return category.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<Category>> getAllCategories() {
List<Category> categories = categoryService.getAllCategories();
return ResponseEntity.ok(categories);
}

@PutMapping("/{id}")
public ResponseEntity<Category> updateCategory(@PathVariable Long id, @RequestBody Category categoryDetails) {
Category updatedCategory = categoryService.updateCategory(id, categoryDetails);
if (updatedCategory != null) {
return ResponseEntity.ok(updatedCategory);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteCategory(@PathVariable Long id) {
categoryService.deleteCategory(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/gameprogresses")
public class GameProgressController {

@Autowired
private GameProgressService gameProgressService;

@PostMapping
public ResponseEntity<GameProgress> createGameProgress(@RequestBody GameProgress gameProgress) {
GameProgress createdGameProgress = gameProgressService.createGameProgress(gameProgress);
return ResponseEntity.ok(createdGameProgress);
}

@GetMapping("/{id}")
public ResponseEntity<GameProgress> getGameProgressById(@PathVariable Long id) {
Optional<GameProgress> gameProgress = gameProgressService.getGameProgressById(id);
return gameProgress.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<GameProgress>> getAllGameProgresses() {
List<GameProgress> gameProgresses = gameProgressService.getAllGameProgresses();
return ResponseEntity.ok(gameProgresses);
}

@PutMapping("/{id}")
public ResponseEntity<GameProgress> updateGameProgress(@PathVariable Long id, @RequestBody GameProgress gameProgressDetails) {
GameProgress updatedGameProgress = gameProgressService.updateGameProgress(id, gameProgressDetails);
if (updatedGameProgress != null) {
return ResponseEntity.ok(updatedGameProgress);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteGameProgress(@PathVariable Long id) {
gameProgressService.deleteGameProgress(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/levels")
public class LevelController {

@Autowired
private LevelService levelService;

@PostMapping
public ResponseEntity<Level> createLevel(@RequestBody Level level) {
Level createdLevel = levelService.createLevel(level);
return ResponseEntity.ok(createdLevel);
}

@GetMapping("/{id}")
public ResponseEntity<Level> getLevelById(@PathVariable Long id) {
Optional<Level> level = levelService.getLevelById(id);
return level.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<Level>> getAllLevels() {
List<Level> levels = levelService.getAllLevels();
return ResponseEntity.ok(levels);
}

@PutMapping("/{id}")
public ResponseEntity<Level> updateLevel(@PathVariable Long id, @RequestBody Level levelDetails) {
Level updatedLevel = levelService.updateLevel(id, levelDetails);
if (updatedLevel != null) {
return ResponseEntity.ok(updatedLevel);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteLevel(@PathVariable Long id) {
levelService.deleteLevel(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/pronunciations")
public class PronunciationController {

@Autowired
private PronunciationService pronunciationService;

@PostMapping
public ResponseEntity<Pronunciation> createPronunciation(@RequestBody Pronunciation pronunciation) {
Pronunciation createdPronunciation = pronunciationService.createPronunciation(pronunciation);
return ResponseEntity.ok(createdPronunciation);
}

@GetMapping("/{id}")
public ResponseEntity<Pronunciation> getPronunciationById(@PathVariable Long id) {
Optional<Pronunciation> pronunciation = pronunciationService.getPronunciationById(id);
return pronunciation.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<Pronunciation>> getAllPronunciations() {
List<Pronunciation> pronunciations = pronunciationService.getAllPronunciations();
return ResponseEntity.ok(pronunciations);
}

@PutMapping("/{id}")
public ResponseEntity<Pronunciation> updatePronunciation(@PathVariable Long id, @RequestBody Pronunciation pronunciationDetails) {
Pronunciation updatedPronunciation = pronunciationService.updatePronunciation(id, pronunciationDetails);
if (updatedPronunciation != null) {
return ResponseEntity.ok(updatedPronunciation);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePronunciation(@PathVariable Long id) {
pronunciationService.deletePronunciation(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.pronunciationAppBack.controller;

import dev.pronunciationAppBack.model.*;
import dev.pronunciationAppBack.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/stages")
public class StageController {

@Autowired
private StageService stageService;

@PostMapping
public ResponseEntity<Stage> createStage(@RequestBody Stage stage) {
Stage createdStage = stageService.createStage(stage);
return ResponseEntity.ok(createdStage);
}

@GetMapping("/{id}")
public ResponseEntity<Stage> getStageById(@PathVariable Long id) {
Optional<Stage> stage = stageService.getStageById(id);
return stage.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

@GetMapping
public ResponseEntity<List<Stage>> getAllStages() {
List<Stage> stages = stageService.getAllStages();
return ResponseEntity.ok(stages);
}

@PutMapping("/{id}")
public ResponseEntity<Stage> updateStage(@PathVariable Long id, @RequestBody Stage stageDetails) {
Stage updatedStage = stageService.updateStage(id, stageDetails);
if (updatedStage != null) {
return ResponseEntity.ok(updatedStage);
} else {
return ResponseEntity.notFound().build();
}
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteStage(@PathVariable Long id) {
stageService.deleteStage(id);
return ResponseEntity.noContent().build();
}
}
Loading