Requisitos del proyecto
Requisito común: relación con empleados
Todas las aplicaciones deberán trabajar con empleados del sistema.
La información de los empleados no se duplicará en la base de datos propia de cada aplicación.
Cada aplicación guardará únicamente el identificador del empleado (id_empleado) cuando necesite relacionar una acción, solicitud, registro o elemento con un usuario.
La información completa del empleado se obtendrá mediante una petición HTTP al servidor Flask.
Para consultar los datos de un empleado, la aplicación deberá llamar a la ruta protegida correspondiente del servicio Flask.
Esta consulta solo podrá realizarse si el usuario tiene rol ADMIN.
- La base de datos de cada aplicación tendrá campos como
id_empleado. - Los datos personales del empleado se consultarán desde Flask.
- El acceso a la información de empleados estará protegido.
- Solo los usuarios con rol
ADMINpodrán consultar información completa de empleados.
Ejemplo: aplicación de mantenimiento
En una aplicación de mantenimiento, el administrador puede registrar incidencias y asignarlas a un empleado.
La base de datos propia de la aplicación no guarda los datos completos del empleado.
Solo guarda el identificador del empleado asignado.
Ejemplo de tabla incidencias:
| id_incidencia | titulo | descripcion | estado | id_empleado_asignado |
|---|---|---|---|---|
| 1 | Proyector no funciona | El proyector del aula 204 no enciende | Pendiente | 5 |
En este caso, la incidencia está asignada al empleado con id_empleado = 5.
Para mostrar los datos completos del empleado asignado, la aplicación realiza una petición HTTP al servidor Flask:
GET /empleados/5
El servidor Flask comprueba que el usuario que realiza la petición tiene rol ADMIN.
Si tiene permiso, devuelve los datos del empleado en formato JSON:
{
"id_empleado": 5,
"nombre": "Laura",
"apellidos": "García López",
"correo": "laura.garcia@ercitech.dam",
"id_departamento": 2,
"id_sede": 4
}
- El administrador asigna la incidencia a un empleado.
- La aplicación guarda solo el id_empleado_asignado.
- Los datos completos del empleado se consultan desde Flask.
- La consulta está protegida y requiere rol ADMIN.

Requisito común: sedes y departamentos
Las sedes y departamentos son recursos comunes compartidos por todas las aplicaciones del proyecto.
La información de sedes y departamentos se obtendrá mediante peticiones HTTP a la API correspondiente.
Las aplicaciones no deben guardar el nombre completo de la sede o departamento en sus tablas principales.
Únicamente se almacenarán sus identificadores:
id_sedeid_departamento
Por ejemplo, al registrar un nuevo empleado desde el panel de administración:
- La aplicación realizará una petición HTTP para obtener la lista de sedes.
- La aplicación realizará una petición HTTP para obtener la lista de departamentos.
- El administrador seleccionará una sede y un departamento.
- La aplicación almacenará únicamente sus identificadores en la base de datos.
Ejemplo:
GET http://info.empresa.dam.es:8055/items/sedes
GET http://info.empresa.dam.es:8055/items/departamentos
Ejemplo de respuesta JSON:
{
"data": [
{
"id": 1,
"nombre": "Recursos Humanos",
"descripcion": "Gestión de personal, contratación y desarrollo profesional"
},
{
"id": 2,
"nombre": "Consultoría",
"descripcion": "Asesoramiento técnico y estratégico a clientes"
},
{
"id": 3,
"nombre": "Calidad",
"descripcion": "Control de calidad, auditorías y mejora continua"
},
{
"id": 4,
"nombre": "Eventos",
"descripcion": "Organización y gestión de eventos corporativos"
}
]
}
Ejemplo de tabla empleados:
| id_empleado | nombre | id_departamento | id_sede |
|---|---|---|---|
| 5 | Laura | 1 | 2 |
En este caso:
id_departamento = 1id_sede = 2
-
La aplicación deberá consultar la información completa mediante la API cuando necesite mostrar el nombre del departamento o la sede.
-
Para consultar una sede o departamento concreto hay que pasar el id en la propia ruta. Por ejemplo si quiero la sede con id=3, pondría:
GET http://info.empresa.dam.es:8055/items/sedes/3
Retorna:
{
"data": {
"id": 3,
"nombre": "Delegación Barcelona",
"direccion": "Carrer Diagonal 200",
"ciudad": "Barcelona"
}
}
Las respuestas de la API siempre devuelven un objeto principal llamado data
Por tanto, para acceder a la información real será necesario acceder primero a la clave data
Adaptaciones en Flask
1. Importar dependencias necesarias
Para realizar peticiones HTTP a la API:
import requests
Para retornar respuestas JSON desde Flask:
from flask import jsonify
También puedes añadir jsonify al import principal de Flask:
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
2. Instalar dependencias
Con el entorno virtual activado, ejecutar:
pip install requests
El paquete correcto es
requests, norequest.
3. Actualizar archivo requirements.txt
Desde la raíz del proyecto ejecutar:
pip freeze > requirements.txt
4. Adaptar el método que carga el formulario de registro
La aplicación debe obtener la lista de sedes y departamentos mediante peticiones HTTP a la API.
Ejemplo:
@app.route("/form", methods=['GET'])
def form():
print("Has entrado en el formulario")
# Obtener sedes
url = "http://info.empresa.dam.es:8055/items/sedes"
respuesta = requests.get(url)
datosSedes = respuesta.json()
# Obtener departamentos
url = "http://info.empresa.dam.es:8055/items/departamentos"
respuesta = requests.get(url)
datosDepartamentos = respuesta.json()
return render_template(
"formulario.html",
departamentos=datosDepartamentos['data'],
sedes=datosSedes['data']
)
5. Uso de sedes y departamentos en HTML
La API retorna un JSON con una estructura similar a esta:
{
"data": [
{
"id": 1,
"nombre": "Mantenimiento"
}
]
}
Por tanto, será necesario acceder a la clave data.
Sedes
<select name="id_sede" id="id_sede">
{% for sede in sedes %}
<option value="{{ sede.id }}">
{{ sede.nombre }}
</option>
{% endfor %}
</select>
Departamentos
<select name="id_dpto" id="id_dpto">
{% for dpto in departamentos %}
<option value="{{ dpto.id }}">
{{ dpto.nombre }}
</option>
{% endfor %}
</select>
6. Capturar datos enviados desde el formulario
Ejemplo:
id_dpto = int(request.form.get("id_dpto"))
id_sede = int(request.form.get("id_sede"))
Estos valores corresponden a los identificadores seleccionados en los <select> del formulario.
Será necesario adaptar el procedimiento almacenado para aceptar estos nuevos parámetros.
Obtener empleados mediante API Flask
La información de empleados debe obtenerse mediante la API desarrollada en Flask.
La aplicación no debe acceder directamente a la base de datos de empleados desde otros servicios.
Ejemplo de ruta protegida
@app.route("/usuarios", methods=["GET"])
@login_requerido
def usuarios():
if session.get("user") == "admin" and session.get("roles") == "admin":
with get_conn() as conn:
with conn.cursor() as cur:
cur.execute("SELECT * FROM usuarios;")
filas = cur.fetchall()
return jsonify(filas)
else:
return f"No tienes permisos {session.get('user')}"
Funcionamiento
- El cliente realiza una petición GET a la ruta
/usuarios. - La ruta está protegida mediante
@login_requerido. - Flask comprueba que existe una sesión activa.
- Se obtienen los datos guardados en
session. - Se verifica que el usuario tenga rol
ADMIN. - Si tiene permisos:
- Se consulta la base de datos.
- Se retornan los datos en formato JSON.
- Si no tiene permisos:
- Se bloquea el acceso.
Decorador @login_requerido
El decorador @login_requerido permite proteger rutas privadas.
Su objetivo es comprobar que el usuario ha iniciado sesión antes de acceder a determinadas páginas o recursos.
Ejemplo:
@login_requerido
Si no existe sesión activa:
- El usuario no podrá acceder.
- Flask podrá redirigir al login o bloquear el acceso.
Uso de session
Durante el login se almacenan datos en la sesión:
session["user"] = usuario
session["roles"] = rol
Estos valores pueden utilizarse posteriormente para:
- Comprobar permisos.
- Identificar al usuario autenticado.
- Restringir acceso a rutas privadas.
- Mostrar información personalizada.