Sistema bancario REST API para gestionar clientes, cuentas y transacciones.
- Docker
- (Opcional) Java 17+ y Maven, solo si deseas ejecutar la app localmente sin Docker
# Construir y levantar base de datos, Adminer y la API
docker compose up -d --build
# (Opcional) Ver logs de la API
docker logs -f banca-app
# Abrir en navegador
start http://localhost:8000/swagger-ui/index.htmlPara detener los servicios:
docker compose downNota: el primer build puede tardar unos minutos porque descarga dependencias y crea la imagen.
# 1) Levantar solo la base de datos y Adminer
docker compose up -d postgres adminer
# 2) Ejecutar la aplicación localmente
mvn spring-boot:run
# 3) Abrir en navegador
start http://localhost:8000/swagger-ui/index.html| Servicio | URL |
|---|---|
| API | http://localhost:8000 |
| Swagger UI | http://localhost:8000/swagger-ui/index.html |
| OpenAPI (JSON) | http://localhost:8000/v3/api-docs |
| Tester Web | http://localhost:8000/lab.html |
| Base de Datos | http://localhost:8081 |
- Swagger UI: http://localhost:8000/swagger-ui/index.html#/
- OpenAPI (JSON): http://localhost:8000/v3/api-docs
POST /api/clientes- Crear clienteGET /api/clientes- Listar clientesGET /api/clientes/{id}- Ver clientePUT /api/clientes/{id}- Actualizar clienteDELETE /api/clientes/{id}- Eliminar cliente
POST /api/cuentas- Crear cuentaPOST /api/cuentas/con-saldo- Crear cuenta con saldo inicialGET /api/cuentas- Listar cuentasGET /api/cuentas/{id}- Ver cuentaPUT /api/cuentas/{id}- Cambiar estado (ACTIVA/INACTIVA/CANCELADA)
POST /api/transacciones/consignacion- Depositar dineroPOST /api/transacciones/retiro- Retirar dineroPOST /api/transacciones/transferencia- Transferir entre cuentasGET /api/transacciones- Ver historial (filtros: cuenta, fechaDesde, fechaHasta)
- POST
/api/clientes- Request
{ "tipoIdentificacion": "CC", "numIdentificacion": "1001", "nombres": "Juan", "apellidos": "Pérez", "email": "juan@example.com", "fechaNacimiento": "1990-05-10" }- Response (201)
{ "id": "<UUID>", "tipoIdentificacion": "CC", "numIdentificacion": "1001", "nombres": "Juan", "apellidos": "Pérez", "email": "juan@example.com", "fechaNacimiento": "1990-05-10", "fechaCreacion": "2025-08-10T12:00:00Z", "fechaModificacion": "2025-08-10T12:00:00Z", "version": 0 } - GET
/api/clientes- Query params (opcionales):
tipoIdentificacion,numIdentificacion,nombre,apellido,email - Response (200)
[ { "id": "<UUID>", "tipoIdentificacion": "CC", "numIdentificacion": "1001", "nombres": "Juan", "apellidos": "Pérez", "email": "juan@example.com", "fechaNacimiento": "1990-05-10", "fechaCreacion": "2025-08-10T12:00:00Z", "fechaModificacion": "2025-08-10T12:00:00Z", "version": 0 } ] - Query params (opcionales):
- GET
/api/clientes/{id}- Response (200): igual a POST (201)
- PUT
/api/clientes/{id}- Request: igual a POST
- Response (200): cliente actualizado
- DELETE
/api/clientes/{id}- Response (204 No Content)
- POST
/api/cuentas- Request
{ "clienteId": "<UUID_CLIENTE>", "tipoCuenta": "AHORROS", "exentaGmf": false, "usuarioPropietario": "empleado.demo" }- Response (201)
{ "id": "<UUID>", "clienteId": "<UUID_CLIENTE>", "tipoCuenta": "AHORROS", "numeroCuenta": "53XXXXXXXX", "estado": "ACTIVA", "saldo": 0.0, "exentaGmf": false, "usuarioPropietario": "empleado.demo", "fechaCreacion": "2025-08-10T12:00:00Z", "fechaModificacion": "2025-08-10T12:00:00Z", "version": 0 } - POST
/api/cuentas/con-saldo- Request
{ "clienteId": "<UUID_CLIENTE>", "tipoCuenta": "AHORROS", "saldoInicial": 100000.00, "exentaGmf": false, "usuarioPropietario": "empleado.demo" }- Response (201): igual a POST
/api/cuentasconsaldoinicial
- GET
/api/cuentas- Query params (opcionales):
clienteId,tipoCuenta,estado,numeroCuenta - Response (200)
[ { "id": "<UUID>", "clienteId": "<UUID_CLIENTE>", "tipoCuenta": "AHORROS", "numeroCuenta": "53XXXXXXXX", "estado": "ACTIVA", "saldo": 0.0, "exentaGmf": false, "usuarioPropietario": "empleado.demo", "fechaCreacion": "2025-08-10T12:00:00Z", "fechaModificacion": "2025-08-10T12:00:00Z", "version": 0 } ] - Query params (opcionales):
- GET
/api/cuentas/{id}- Response (200)
{ "id": "<UUID>", "clienteId": "<UUID_CLIENTE>", "tipoCuenta": "AHORROS", "numeroCuenta": "53XXXXXXXX", "estado": "ACTIVA", "saldo": 0.0, "exentaGmf": false, "usuarioPropietario": "empleado.demo", "fechaCreacion": "2025-08-10T12:00:00Z", "fechaModificacion": "2025-08-10T12:00:00Z", "version": 0, "movimientosRecientes": [ { "id": "<UUID>", "cuentaId": "<UUID>", "tipoMov": "CREDIT", "monto": 50000.0, "saldoAntes": 0.0, "saldoDespues": 50000.0, "fecha": "2025-08-10T12:00:00Z" } ] } - PUT
/api/cuentas/{id}- Request
{ "estado": "INACTIVA" }- Response (200): cuenta en
CuentaResponse(igual a creación con estado actualizado)
- POST
/api/transacciones/consignacion- Headers opcional:
X-User: empleado.demo - Request
{ "cuentaDestinoId": "<UUID_CUENTA>", "monto": 50000, "descripcion": "Consignación" }- Response (201)
{ "id": "<UUID>", "tipo": "CONSIGNACION", "fecha": "2025-08-10T12:00:00Z", "cuentaDestinoId": "<UUID_CUENTA>", "monto": 50000.0, "descripcion": "Consignación", "referencia": null, "estado": "OK", "creadoPor": "empleado.demo" } - Headers opcional:
- POST
/api/transacciones/retiro- Request
{ "cuentaOrigenId": "<UUID_CUENTA>", "monto": 20000, "descripcion": "Retiro" }- Response (201):
TransaccionResponse(tipoRETIRO)
- POST
/api/transacciones/transferencia- Request
{ "cuentaOrigenId": "<UUID_ORIGEN>", "cuentaDestinoId": "<UUID_DESTINO>", "monto": 30000, "descripcion": "Transferencia" }- Response (201):
TransaccionResponse(tipoTRANSFERENCIA)
- GET
/api/transacciones- Query params (opcionales):
cuenta=<UUID>fechaDesde=2025-01-01T00:00:00ZfechaHasta=2025-12-31T23:59:59Z
- Response (200)
[ { "id": "<UUID>", "tipo": "CONSIGNACION", "fecha": "2025-08-10T12:00:00Z", "cuentaDestinoId": "<UUID_CUENTA>", "monto": 50000.0, "descripcion": "Consignación", "estado": "OK", "creadoPor": "empleado.demo" } ] - Query params (opcionales):
POST /api/clientes
{
"tipoIdentificacion": "CC",
"numIdentificacion": "1001",
"nombres": "Juan",
"apellidos": "Pérez",
"email": "juan@example.com",
"fechaNacimiento": "1990-05-10"
}POST /api/cuentas
{
"clienteId": "<UUID_DEL_CLIENTE>",
"tipoCuenta": "AHORROS",
"exentaGmf": false
}POST /api/transacciones/consignacion
{
"cuentaDestinoId": "<UUID_CUENTA>",
"monto": 50000,
"descripcion": "Consignación inicial"
}POST /api/transacciones/retiro
{
"cuentaOrigenId": "<UUID_CUENTA>",
"monto": 20000,
"descripcion": "Retiro cajero"
}POST /api/transacciones/transferencia
{
"cuentaOrigenId": "<UUID_ORIGEN>",
"cuentaDestinoId": "<UUID_DESTINO>",
"monto": 30000,
"descripcion": "Pago servicios"
}- Mayor de 18 años
- Email válido
- Nombres y apellidos mínimo 2 caracteres
- No se puede eliminar si tiene cuentas
- Tipos: AHORROS o CORRIENTE
- Número se genera automático:
- Ahorros: 53XXXXXXXX
- Corriente: 33XXXXXXXX
- Cuenta ahorros nunca puede quedar en negativo
- Solo se cancela con saldo en 0
- Monto debe ser mayor a 0
- Debe haber fondos suficientes
- No se puede transferir a la misma cuenta
- Todas las operaciones se registran en movimientos
# Ejecutar todas las pruebas
mvn test
# Ejecutar prueba específica
mvn -Dtest=TransaccionServiceTest test
# Ver cobertura
mvn clean test jacoco:report
#Con Docker
docker run --rm -v "${PWD}:/workspace" -w /workspace maven:3.9.6-eclipse-temurin-17 mvn clean test- Services:
ClienteServiceTest,CuentaServiceTest,TransaccionServiceTest - Controllers:
ClienteControllerTest,CuentaControllerTest,TransaccionControllerTest
- Ir a http://localhost:8081
- Configurar:
- Sistema: PostgreSQL
- Servidor: postgres
- Usuario: banca
- Contraseña: banca
- Base de datos: banca
Versión: 1.0.0
Actualizado: 2025