🧱 Arquitectura del Sistema – MiniTweet API
MiniTweet API está desarrollada con una arquitectura n-tier (multicapa) basada en buenas prácticas de diseño con Spring Boot. Esta estructura favorece la separación de responsabilidades, la escalabilidad y el mantenimiento limpio del código.
MiniTweet API está desarrollada con una arquitectura n-tier (multicapa) basada en buenas prácticas de diseño con Spring Boot. Esta estructura favorece la separación de responsabilidades, la escalabilidad y el mantenimiento limpio del código. Además, se hace uso de Programación Orientada a Objetos (POO) para modelar entidades y comportamientos del dominio de forma clara y reutilizable.
🗂️ Capas principales
MiniTweet se organiza en cuatro capas principales, cada una con una responsabilidad específica:
1️⃣ Capa de Controladores (controllers/)
- 📍 Responsabilidad: Maneja las solicitudes HTTP entrantes.
 - 💬 Interactúa directamente con el usuario o cliente (frontend o app móvil).
 - 🧠 Delegan la lógica a los servicios.
 - 🚫 No contiene lógica de negocio.
 
    @PostMapping("/register")
    public ResponseEntity<GeneralResponse>registerUser(@RequestBody @Valid RegisterUserDto userDto){
        try{
            userService.registerUser(userDto);
            return GeneralResponse.getResponse(HttpStatus.CREATED, "User registered successfully");
        }catch (HttpError e){
            return GeneralResponse.getResponse(e.getHttpStatus(), e.getMessage());
        }
    }
2️⃣ Capa de Servicios (services/)
- 🛠️ Responsabilidad: Contiene la lógica de negocio.
 - 🔄 Interactúa con los repositorios para acceder a la base de datos.
 - 📦 Agrupa funcionalidades relacionadas (usuarios, publicaciones, comentarios).
 - 🔐 Puede aplicar reglas de validación o seguridad.
 
    @Override
    @Transactional(rollbackOn = Exception.class)
    public Boolean isTokenValid(User user, String token) {
        try {
            cleanToken(user);
            List<Token> tokens = tokenRepository.findByUserAndActive(user, true);
            tokens.stream()
                    .map(t -> t.getContent().equals(token))
                    .findAny()
                    .orElseThrow(() -> new HttpError(HttpStatus.UNAUTHORIZED, "Token not valid"));
            return true;
        } catch (HttpError e) {
            throw e;
        }
    }
3️⃣ Capa de Repositorios (repositories/)
- 🗄️ Responsabilidad: Interactúa directamente con la base de datos.
 - 🔍 Utiliza Spring Data JPA para realizar consultas.
 - 📑 Peticiones con Hibernate Query Language (HQL).
 - 💾 Realiza operaciones CRUD sobre las entidades.
 
@Repository
public interface CommentRepository extends JpaRepository<Comment, UUID> {
    List<Comment>findAllByPost(Post post);
    Comment findByIdAndAuthor(UUID id, User authorId);
}
4️⃣ Capa de Entidades (domain/)
- 🏷️ Responsabilidad: Define las entidades del dominio.
 - 🧩 Modela los objetos del negocio (usuarios, publicaciones, comentarios).
 - 🔗 Utiliza anotaciones JPA para mapear a la base de datos.
 
@Data
@Entity
@Table(name = "roles")
public class Role {
    @Id
    private String id;
    @Column(nullable = false, unique = true, columnDefinition = "VARCHAR(50)")
    private String name;
    @ManyToMany(mappedBy = "roles")
    @JsonIgnore
    private List<User> users;
}
🛠️ Otras capas y componentes importantes
🧾 DTOs (Data Transfer Objects)
- 📦 Utilizados para transferir datos entre capas.
 - 📝 Definen la estructura de los datos que se envían o reciben.
 - 🚫 No contienen lógica de negocio.
 
🔒 Seguridad y Autenticación (Spring Security y JWT)
- 🔐 Validacion de roles y permisos.
 - 🛡️ Protege los endpoints con roles y permisos.
 - 📜 Configura filtros de seguridad para validar tokens.
 - 🗝️ Utiliza un 
UserDetailsServicepara cargar usuarios desde la base de datos. - 🔑 Genera y valida tokens JWT para acceso seguro.
 
☁️ Integración con Cloudinary
- 🌥️ Maneja la carga y gestión de imágenes.
 - 📸 Utiliza la API de Cloudinary para almacenar imágenes.
 - 🔗 Configuración en 
application.propertiespara acceder a las credenciales de Cloudinary 
🛠️ Manejador Global de Errores
- 📦 Utiliza un 
@ControllerAdvicepara manejar excepciones de forma centralizada. - 🔍 Captura excepciones específicas y devuelve respuestas adecuadas.
 - 🛡️ Protege la aplicación de filtraciones de información sensible.
 
@RestControllerAdvice
public class GlobalErrorHandler {
    @ExceptionHandler(HttpError.class)
    public ResponseEntity<GeneralResponse> handleHttpError(HttpError e) {
        return GeneralResponse.getResponse(e.getHttpStatus(), e.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public ResponseEntity<GeneralResponse> handleGenericError(Exception e) {
        return GeneralResponse.getResponse(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error");
    }
}
🛠️ Excepción Personalizada HttpError
- 📦 Extiende de 
RuntimeException. - 🔍 Permite manejar errores HTTP de forma consistente.
 - 🛡️ Incluye información sobre el estado y el mensaje del error.
 - 📜 Facilita la creación de respuestas de error personalizadas.
 
@Getter
public class HttpError extends RuntimeException {
    private final HttpStatus httpStatus;
    public HttpError(HttpStatus httpStatus,  String message){
        super(message);
        this.httpStatus = httpStatus;
    }
}
🧩 Resumen de la Arquitectura
MiniTweet API sigue una arquitectura limpia y modular, donde cada capa tiene una responsabilidad clara. Esto permite un desarrollo ágil, pruebas unitarias efectivas y una fácil escalabilidad. La separación de preocupaciones facilita el mantenimiento y la evolución del sistema a lo largo del tiempo. Esta estructura modular también permite que diferentes equipos trabajen en paralelo en distintas capas sin interferencias, lo que mejora la productividad y la calidad del código.
🔄 Flujo de una petición
[Cliente (Postman / App / Frontend)]
        ↓
[Controller] → [Service] → [Repository] → [Base de datos]
        ↓
[Response al Cliente]
🛡️ Las respuestas siguen este camino en sentido inverso.
✨ Ventajas de esta arquitectura
- 🔍 Claridad: Cada capa tiene una única responsabilidad.
 - ♻️ Reutilización: Lógica de negocio centralizada y reutilizable.
 - 🔒 Seguridad: Filtros y capas de autenticación aisladas.
 - 🚀 Escalabilidad: Puedes agregar nuevas funcionalidades sin afectar otras capas.
 - 🧪 Testabilidad: Fácil de probar cada capa de forma independiente.
 
📌 Para más detalles sobre la implementación y el uso de MiniTweet API, consulta la sección Guía de Inicio Rápido.
📚 ¿ Te interesa la seguridad del sistema? Consulta la sección Autenticación.