Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
164 changes: 164 additions & 0 deletions READMEJtoro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# 🧩 Desafío Técnico: Servlets + AJAX

Aplicación web desarrollada en Java 8 que implementa un servicio de gestión de empleados utilizando **Servlets**, **JDBC** y **AJAX nativo**, cumpliendo con los requisitos del desafío.

---

## 🚀 Tecnologías utilizadas

- Java 8
- Spring Boot 2.7 (runtime)
- Apache Tomcat embebido
- Servlets (HttpServlet)
- JDBC (sin ORM)
- Base de datos en memoria H2
- HTML + CSS + JavaScript (Fetch API)
- Maven

---

## 📦 Cómo ejecutar la aplicación

### 1. Requisitos

- Java 8 instalado
- Maven instalado

### 2. Ejecutar el proyecto

Desde consola:

```bash
mvn spring-boot:run
```

O desde IntelliJ:

Ejecutar la clase principal:
DesafioServletsAjaxApplication

---

## 🌐 Acceso a la aplicación

Frontend:
http://localhost:8080/index.html

Consola H2:
http://localhost:8080/h2-console

### Configuración H2

- JDBC URL: jdbc:h2:mem:empleadosdb
- User: sa
- Password: (vacío)

---

## 🔌 Endpoints disponibles

### 🔹 GET /api/empleados
Obtiene la lista de empleados.

### 🔹 POST /api/empleados
Crea un nuevo empleado.

Ejemplo request:

```json
{
"nombre": "Juan",
"apellido": "Perez",
"rutDni": "12345678-5",
"cargo": "Backend",
"salarioBase": 700000,
"bono": 100000,
"descuentos": 50000
}
```

### 🔹 DELETE /api/empleados/{id}

Ejemplo:

```text
DELETE http://localhost:8080/api/empleados/1
```

---

## 🧪 Cómo probar la aplicación

### ✔ Opción 1: Desde la interfaz web

1. Abrir:
http://localhost:8080/index.html

2. Probar:
- Crear empleado
- Validaciones del formulario
- Listar empleados
- Eliminar empleados

### ✔ Opción 2: Usando Postman

#### Crear empleado (POST)

```text
POST http://localhost:8080/api/empleados
```

#### Listar empleados (GET)

```text
GET http://localhost:8080/api/empleados
```

#### Eliminar empleado (DELETE)

```text
DELETE http://localhost:8080/api/empleados/1
```

---

## ⚠️ Validaciones implementadas

### 🔹 Backend

- RUT/DNI duplicado
- Salario base mínimo configurable
- Bono máximo (50% del salario base)
- Descuentos no pueden superar el salario
- Validación real de RUT (módulo 11)
- Sugerencia del RUT correcto cuando el DV es inválido

> Para cubrir las validaciones de la segunda parte del desafío, se incorporaron los campos **bono** y **descuentos** dentro de la carga de empleados.

### 🔹 Frontend

- Campos obligatorios
- Validación de formato de RUT/DNI
- Validación de salario mínimo
- Validación de bono y descuentos
- Mensajes dinámicos sin recargar la página

---

## 🧠 Consideraciones técnicas

- Arquitectura por capas (DAO / Service / Servlet)
- Manejo de errores con HTTP 400 + JSON estructurado
- Uso de @ConfigurationProperties para reglas de negocio configurables
- Uso de JDBC con PreparedStatement para prevenir SQL Injection
- Obtención del ID generado en el INSERT
- Uso de AJAX con Fetch API sin frameworks frontend

---

## 👤 Autor

- Nombre: Jonnathan Toro Jara
- Email: jonnathan.toro@live.com
- Cargo postulante: Desarrollador Java
- Empresa reclutadora: Tecnova
81 changes: 81 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>

<groupId>com.prueba</groupId>
<artifactId>desafio-legaxy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>desafio-legaxy</name>
<description>Desafío técnico Servlets + AJAX</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.prueba.desafio;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DesafioServletsAjaxApplication {

public static void main(String[] args) {
SpringApplication.run(DesafioServletsAjaxApplication.class, args);
}

}
30 changes: 30 additions & 0 deletions src/main/java/com/prueba/desafio/config/EmpleadoProperties.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.prueba.desafio.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Component
@ConfigurationProperties(prefix = "app.empleado")
public class EmpleadoProperties {

private BigDecimal salarioMinimo;
private BigDecimal bonoMaxPorcentaje;

public BigDecimal getSalarioMinimo() {
return salarioMinimo;
}

public void setSalarioMinimo(BigDecimal salarioMinimo) {
this.salarioMinimo = salarioMinimo;
}

public BigDecimal getBonoMaxPorcentaje() {
return bonoMaxPorcentaje;
}

public void setBonoMaxPorcentaje(BigDecimal bonoMaxPorcentaje) {
this.bonoMaxPorcentaje = bonoMaxPorcentaje;
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/prueba/desafio/config/ServletConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.prueba.desafio.config;
import com.prueba.desafio.service.EmpleadoService;
import com.prueba.desafio.servlet.EmpleadoServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ServletConfig {

@Bean
public ServletRegistrationBean<EmpleadoServlet> empleadoServletRegistration(EmpleadoService empleadoService) {
ServletRegistrationBean<EmpleadoServlet> registrationBean =
new ServletRegistrationBean<EmpleadoServlet>(
new EmpleadoServlet(empleadoService),
"/api/empleados",
"/api/empleados/*"
);

registrationBean.setName("empleadoServlet");
return registrationBean;
}
}
Loading