Cuestión 1 — Diagrama de casos de uso
Actores. Tras analizar el enunciado se identifican:
- Profesor/a (actor primario): abre incidencias.
- Coordinador/a TIC (actor primario): asigna incidencias a técnicos y supervisa.
- Técnico/a (actor primario): resuelve y cierra incidencias.
- Sistema de Correo/Notificaciones (actor secundario): recibe la petición de notificar al profesor.
Conviene modelar una jerarquía de actores: Usuario es un actor abstracto del que heredan Profesor, Coordinador TIC y Técnico (todos se autentican), porque comparten el caso de uso de iniciar sesión.
Casos de uso (descripción del diagrama):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 470" font-family="ui-sans-serif, system-ui, Arial, sans-serif">
<!-- system boundary -->
<rect x="170" y="20" width="500" height="430" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="2"/>
<text x="420" y="42" text-anchor="middle" font-size="14" font-weight="700" fill="#0f172a">Sistema Gestor de Incidencias TIC</text>
<!-- Actor: Profesor -->
<g stroke="#334155" stroke-width="1.8" fill="none">
<circle cx="50" cy="95" r="11" fill="#eff6ff"/>
<line x1="50" y1="106" x2="50" y2="135"/>
<line x1="34" y1="116" x2="66" y2="116"/>
<line x1="50" y1="135" x2="36" y2="158"/>
<line x1="50" y1="135" x2="64" y2="158"/>
</g>
<text x="50" y="178" text-anchor="middle" font-size="13" font-weight="600" fill="#0f172a">Profesor</text>
<!-- Actor: Coordinador TIC -->
<g stroke="#334155" stroke-width="1.8" fill="none">
<circle cx="50" cy="235" r="11" fill="#eff6ff"/>
<line x1="50" y1="246" x2="50" y2="275"/>
<line x1="34" y1="256" x2="66" y2="256"/>
<line x1="50" y1="275" x2="36" y2="298"/>
<line x1="50" y1="275" x2="64" y2="298"/>
</g>
<text x="50" y="318" text-anchor="middle" font-size="13" font-weight="600" fill="#0f172a">Coord. TIC</text>
<!-- Actor: Tecnico -->
<g stroke="#334155" stroke-width="1.8" fill="none">
<circle cx="50" cy="375" r="11" fill="#eff6ff"/>
<line x1="50" y1="386" x2="50" y2="415"/>
<line x1="34" y1="396" x2="66" y2="396"/>
<line x1="50" y1="415" x2="36" y2="438"/>
<line x1="50" y1="415" x2="64" y2="438"/>
</g>
<text x="50" y="458" text-anchor="middle" font-size="13" font-weight="600" fill="#0f172a">Técnico</text>
<!-- Actor: Sistema Correo (secundario) -->
<g stroke="#334155" stroke-width="1.8" fill="none">
<circle cx="765" cy="375" r="11" fill="#ecfdf5"/>
<line x1="765" y1="386" x2="765" y2="415"/>
<line x1="749" y1="396" x2="781" y2="396"/>
<line x1="765" y1="415" x2="751" y2="438"/>
<line x1="765" y1="415" x2="779" y2="438"/>
</g>
<text x="765" y="458" text-anchor="middle" font-size="12" font-weight="600" fill="#0f172a">Sistema Correo</text>
<!-- Use cases (ellipses) -->
<!-- Autenticarse (shared, included) -->
<ellipse cx="560" cy="120" rx="78" ry="26" fill="#ecfdf5" stroke="#059669" stroke-width="1.8"/>
<text x="560" y="125" text-anchor="middle" font-size="13" fill="#0f172a">Autenticarse</text>
<!-- Abrir incidencia -->
<ellipse cx="300" cy="95" rx="82" ry="26" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="300" y="100" text-anchor="middle" font-size="13" fill="#0f172a">Abrir incidencia</text>
<!-- Consultar mis incidencias -->
<ellipse cx="300" cy="160" rx="98" ry="24" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="300" y="165" text-anchor="middle" font-size="12" fill="#0f172a">Consultar mis incidencias</text>
<!-- Asignar incidencia a tecnico -->
<ellipse cx="300" cy="235" rx="98" ry="26" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="300" y="232" text-anchor="middle" font-size="12" fill="#0f172a">Asignar incidencia</text>
<text x="300" y="248" text-anchor="middle" font-size="12" fill="#0f172a">a técnico</text>
<!-- Consultar panel/estadisticas -->
<ellipse cx="300" cy="300" rx="98" ry="24" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="300" y="297" text-anchor="middle" font-size="12" fill="#0f172a">Consultar panel /</text>
<text x="300" y="312" text-anchor="middle" font-size="12" fill="#0f172a">estadísticas</text>
<!-- Resolver incidencia -->
<ellipse cx="300" cy="370" rx="92" ry="24" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="300" y="375" text-anchor="middle" font-size="12" fill="#0f172a">Resolver incidencia</text>
<!-- Cerrar incidencia -->
<ellipse cx="300" cy="425" rx="82" ry="24" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="300" y="430" text-anchor="middle" font-size="13" fill="#0f172a">Cerrar incidencia</text>
<!-- Notificar al profesor -->
<ellipse cx="560" cy="425" rx="90" ry="24" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="560" y="430" text-anchor="middle" font-size="12" fill="#0f172a">Notificar al profesor</text>
<!-- Actor associations (solid lines) -->
<line x1="66" y1="115" x2="218" y2="98" stroke="#334155" stroke-width="1.6"/>
<line x1="66" y1="125" x2="202" y2="158" stroke="#334155" stroke-width="1.6"/>
<line x1="66" y1="248" x2="202" y2="237" stroke="#334155" stroke-width="1.6"/>
<line x1="66" y1="258" x2="202" y2="298" stroke="#334155" stroke-width="1.6"/>
<line x1="66" y1="388" x2="208" y2="372" stroke="#334155" stroke-width="1.6"/>
<line x1="66" y1="398" x2="218" y2="423" stroke="#334155" stroke-width="1.6"/>
<!-- Notificar -> Sistema Correo -->
<line x1="650" y1="425" x2="752" y2="408" stroke="#334155" stroke-width="1.6"/>
<!-- include: Abrir -> Autenticarse -->
<line x1="382" y1="98" x2="484" y2="116" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 4"/>
<polygon points="484,116 472,110 474,121" fill="#059669"/>
<text x="430" y="92" text-anchor="middle" font-size="10.5" fill="#059669" font-style="italic">«include»</text>
<!-- include: Asignar -> Autenticarse -->
<line x1="398" y1="232" x2="498" y2="142" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 4"/>
<polygon points="498,142 488,150 495,153" fill="#059669"/>
<text x="470" y="200" text-anchor="middle" font-size="10.5" fill="#059669" font-style="italic">«include»</text>
<!-- include: Cerrar -> Autenticarse -->
<line x1="382" y1="421" x2="500" y2="143" stroke="#059669" stroke-width="1.4" stroke-dasharray="5 4"/>
<polygon points="500,143 491,151 499,154" fill="#059669"/>
<text x="455" y="290" text-anchor="middle" font-size="10.5" fill="#059669" font-style="italic">«include»</text>
<!-- extend: Notificar -> Cerrar -->
<line x1="470" y1="425" x2="384" y2="425" stroke="#b45309" stroke-width="1.6" stroke-dasharray="5 4"/>
<polygon points="384,425 396,419 396,431" fill="#b45309"/>
<text x="430" y="416" text-anchor="middle" font-size="10.5" fill="#b45309" font-style="italic">«extend»</text>
</svg>
Relaciones justificadas:
<<include>> (obligatoria y reutilizada): «Abrir incidencia», «Asignar incidencia» y «Cerrar incidencia» incluyen siempre «Autenticarse». Se factoriza porque es comportamiento común y obligatorio a varios casos de uso (DRY). El caso base SIEMPRE ejecuta el incluido.
<<extend>> (opcional/condicional): «Notificar al profesor» extiende «Cerrar incidencia» en un punto de extensión (tras marcar como cerrada), bajo la condición de extensión {el profesor solicitante tiene notificaciones activas}. Es opcional: la incidencia se puede cerrar sin notificar, por eso es extensión y no inclusión.
Justificación de la elección: include modela una factorización obligatoria (siempre ocurre); extend modela una variación opcional que enriquece un caso base que es válido por sí solo. Confundirlos es el error más penalizado en esta cuestión.
Cuestión 2 — Diagrama de clases
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 880" font-family="ui-sans-serif, system-ui, Arial, sans-serif">
<!-- ===== Usuario (abstract) ===== -->
<g>
<rect x="290" y="20" width="240" height="118" rx="6" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="410" y="38" text-anchor="middle" font-size="12.5" fill="#0f172a" font-style="italic">«abstract»</text>
<text x="410" y="54" text-anchor="middle" font-size="14" font-weight="700" fill="#0f172a">Usuario</text>
<line x1="290" y1="62" x2="530" y2="62" stroke="#2563eb" stroke-width="1.5"/>
<text x="300" y="79" font-size="11.5" fill="#0f172a">- id: int</text>
<text x="300" y="95" font-size="11.5" fill="#0f172a">- nombre: String</text>
<text x="300" y="111" font-size="11.5" fill="#0f172a">- email: String</text>
<text x="300" y="127" font-size="11.5" fill="#0f172a">- login: String</text>
<line x1="290" y1="116" x2="530" y2="116" stroke="#2563eb" stroke-width="1.5"/>
</g>
<!-- second compartment line above methods? methods overlap; adjust: place metodos in own row -->
<!-- methods compartment -->
<rect x="290" y="138" width="240" height="26" rx="0" fill="#eff6ff" stroke="#2563eb" stroke-width="1.8"/>
<text x="300" y="156" font-size="11.5" fill="#0f172a">+ autenticar(pwd): bool</text>
<!-- generalization label -->
<text x="620" y="190" text-anchor="middle" font-size="11" fill="#334155" font-style="italic">herencia / generalización</text>
<!-- ===== Subclasses ===== -->
<!-- Profesor -->
<g>
<rect x="40" y="230" width="190" height="96" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="135" y="250" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">Profesor</text>
<line x1="40" y1="258" x2="230" y2="258" stroke="#334155" stroke-width="1.5"/>
<text x="50" y="276" font-size="11.5" fill="#0f172a">- departamento</text>
<line x1="40" y1="286" x2="230" y2="286" stroke="#334155" stroke-width="1.5"/>
<text x="50" y="304" font-size="11.5" fill="#0f172a">+ abrirInc()</text>
</g>
<!-- CoordinadorTIC -->
<g>
<rect x="310" y="230" width="200" height="96" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="410" y="250" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">CoordinadorTIC</text>
<line x1="310" y1="258" x2="510" y2="258" stroke="#334155" stroke-width="1.5"/>
<text x="320" y="276" font-size="11.5" fill="#64748b">(sin atributos)</text>
<line x1="310" y1="286" x2="510" y2="286" stroke="#334155" stroke-width="1.5"/>
<text x="320" y="302" font-size="11.5" fill="#0f172a">+ asignar(i, t)</text>
<text x="320" y="318" font-size="11.5" fill="#0f172a">+ verPanel()</text>
</g>
<!-- Tecnico -->
<g>
<rect x="590" y="230" width="210" height="96" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="695" y="250" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">Tecnico</text>
<line x1="590" y1="258" x2="800" y2="258" stroke="#334155" stroke-width="1.5"/>
<text x="600" y="276" font-size="11.5" fill="#0f172a">- especialidad: String</text>
<line x1="590" y1="286" x2="800" y2="286" stroke="#334155" stroke-width="1.5"/>
<text x="600" y="302" font-size="11.5" fill="#0f172a">+ resolver(i)</text>
<text x="600" y="318" font-size="11.5" fill="#0f172a">+ cerrar(i)</text>
</g>
<!-- Generalization arrows (hollow triangle to Usuario bottom) -->
<!-- shared vertical from triangle apex at (410,176) -->
<polygon points="410,176 402,196 418,196" fill="#ffffff" stroke="#334155" stroke-width="1.6"/>
<line x1="410" y1="196" x2="410" y2="212" stroke="#334155" stroke-width="1.6"/>
<line x1="135" y1="212" x2="695" y2="212" stroke="#334155" stroke-width="1.6"/>
<line x1="135" y1="212" x2="135" y2="230" stroke="#334155" stroke-width="1.6"/>
<line x1="410" y1="212" x2="410" y2="230" stroke="#334155" stroke-width="1.6"/>
<line x1="695" y1="212" x2="695" y2="230" stroke="#334155" stroke-width="1.6"/>
<!-- ===== Incidencia ===== -->
<g>
<rect x="270" y="430" width="290" height="208" rx="6" fill="#ecfdf5" stroke="#059669" stroke-width="1.8"/>
<text x="415" y="450" text-anchor="middle" font-size="14" font-weight="700" fill="#0f172a">Incidencia</text>
<line x1="270" y1="458" x2="560" y2="458" stroke="#059669" stroke-width="1.5"/>
<text x="280" y="476" font-size="11.5" fill="#0f172a">- id: int</text>
<text x="280" y="492" font-size="11.5" fill="#0f172a">- descripcion: String</text>
<text x="280" y="508" font-size="11.5" fill="#0f172a">- prioridad: Prioridad «enum»</text>
<text x="280" y="524" font-size="11.5" fill="#0f172a">- estado: Estado «enum»</text>
<text x="280" y="540" font-size="11.5" fill="#0f172a">- fechaApertura: DateTime</text>
<text x="280" y="556" font-size="11.5" fill="#0f172a">- fechaCierre: DateTime [0..1]</text>
<line x1="270" y1="566" x2="560" y2="566" stroke="#059669" stroke-width="1.5"/>
<text x="280" y="584" font-size="11.5" fill="#0f172a">+ asignar(t: Tecnico)</text>
<text x="280" y="600" font-size="11.5" fill="#0f172a">+ resolver()</text>
<text x="280" y="616" font-size="11.5" fill="#0f172a">+ cerrar()</text>
</g>
<!-- Associations subclasses -> Incidencia -->
<!-- Profesor 1 -- 0..* Incidencia (solicitante) -->
<line x1="135" y1="326" x2="135" y2="490" stroke="#334155" stroke-width="1.6"/>
<line x1="135" y1="490" x2="262" y2="490" stroke="#334155" stroke-width="1.6"/>
<polygon points="270,490 258,484 258,496" fill="#334155"/>
<text x="150" y="345" font-size="10.5" fill="#334155">1</text>
<text x="150" y="360" font-size="10" fill="#64748b">solicitante</text>
<text x="245" y="484" font-size="10.5" fill="#334155">0..*</text>
<!-- CoordinadorTIC 0..1 -- Incidencia (asignador) -->
<line x1="410" y1="326" x2="410" y2="424" stroke="#334155" stroke-width="1.6"/>
<polygon points="410,430 404,418 416,418" fill="#334155"/>
<text x="420" y="350" font-size="10.5" fill="#334155">0..1</text>
<text x="420" y="364" font-size="10" fill="#64748b">asignador</text>
<!-- Tecnico 0..1 -- 0..* Incidencia (responsable) -->
<line x1="695" y1="326" x2="695" y2="490" stroke="#334155" stroke-width="1.6"/>
<line x1="695" y1="490" x2="568" y2="490" stroke="#334155" stroke-width="1.6"/>
<polygon points="560,490 572,484 572,496" fill="#334155"/>
<text x="660" y="345" font-size="10.5" fill="#334155">0..1</text>
<text x="640" y="360" font-size="10" fill="#64748b">responsable</text>
<text x="575" y="484" font-size="10.5" fill="#334155">0..*</text>
<!-- ===== Equipo ===== -->
<g>
<rect x="120" y="710" width="200" height="118" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="220" y="730" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">Equipo</text>
<line x1="120" y1="738" x2="320" y2="738" stroke="#334155" stroke-width="1.5"/>
<text x="130" y="756" font-size="11.5" fill="#0f172a">- numSerie: String</text>
<text x="130" y="772" font-size="11.5" fill="#0f172a">- tipo: String</text>
<text x="130" y="788" font-size="11.5" fill="#0f172a">- modelo: String</text>
<line x1="120" y1="798" x2="320" y2="798" stroke="#334155" stroke-width="1.5"/>
</g>
<!-- ===== Aula ===== -->
<g>
<rect x="500" y="710" width="200" height="118" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.8"/>
<text x="600" y="730" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">Aula</text>
<line x1="500" y1="738" x2="700" y2="738" stroke="#334155" stroke-width="1.5"/>
<text x="510" y="756" font-size="11.5" fill="#0f172a">- codigo: String</text>
<text x="510" y="772" font-size="11.5" fill="#0f172a">- nombre: String</text>
<line x1="500" y1="798" x2="700" y2="798" stroke="#334155" stroke-width="1.5"/>
</g>
<!-- Incidencia 0..* -- 1 Equipo -->
<line x1="350" y1="638" x2="220" y2="710" stroke="#334155" stroke-width="1.6"/>
<polygon points="220,710 217,697 230,703" fill="#334155"/>
<text x="330" y="660" font-size="10.5" fill="#334155">0..*</text>
<text x="230" y="703" font-size="10.5" fill="#334155">1</text>
<!-- Incidencia 0..* -- 1 Aula -->
<line x1="480" y1="638" x2="600" y2="710" stroke="#334155" stroke-width="1.6"/>
<polygon points="600,710 590,701 603,697" fill="#334155"/>
<text x="470" y="660" font-size="10.5" fill="#334155">0..*</text>
<text x="585" y="703" font-size="10.5" fill="#334155">1</text>
<!-- Aggregation Aula <>-- Equipo (rombo hueco en el todo = Aula) -->
<line x1="500" y1="769" x2="334" y2="769" stroke="#334155" stroke-width="1.6"/>
<polygon points="500,769 487,762 474,769 487,776" fill="#ffffff" stroke="#334155" stroke-width="1.5"/>
<text x="455" y="762" font-size="10.5" fill="#334155">1</text>
<text x="345" y="762" font-size="10.5" fill="#334155">0..*</text>
<text x="410" y="788" text-anchor="middle" font-size="10.5" fill="#334155" font-style="italic">agregación</text>
<!-- Enums note -->
<rect x="40" y="840" width="740" height="34" rx="6" fill="#f8fafc" stroke="#334155" stroke-width="1.2"/>
<text x="52" y="857" font-size="11" fill="#0f172a">«enum» Estado: { ABIERTA, ASIGNADA, EN_PROCESO, RESUELTA, CERRADA }</text>
<text x="52" y="870" font-size="11" fill="#0f172a">«enum» Prioridad: { BAJA, MEDIA, ALTA, CRITICA }</text>
</svg>
Relaciones y multiplicidades:
- Herencia (generalización):
Profesor, CoordinadorTIC y Tecnico heredan de Usuario. Justificación: comparten estado (id, nombre, email, login) y el método autenticar(); satisfacen el LSP (donde se espera un Usuario puede usarse cualquier subtipo). Evita duplicar atributos y permite tratar a todos como usuarios autenticables. Si los roles fueran muy cambiantes (un mismo usuario es profesor y técnico) sería preferible composición de roles sobre herencia; con roles fijos del enunciado, la jerarquía es correcta.
- Asociación Profesor 1 — 0..* Incidencia (rol solicitante): un profesor abre muchas incidencias; cada incidencia tiene un único profesor solicitante.
- Asociación Tecnico 0..1 — 0..* Incidencia (rol responsable): una incidencia puede no tener técnico aún (
0..1); un técnico atiende muchas (0..*).
- Asociación Incidencia 0..* — 1 Equipo: cada incidencia afecta a un equipo; un equipo puede acumular muchas incidencias a lo largo del curso.
- Agregación Aula ◇— Equipo (1 — 0..*): el aula «contiene» equipos, pero es agregación (rombo hueco), no composición: si se elimina el aula los equipos pueden reubicarse (su ciclo de vida no depende del aula).
- Incidencia — Aula (0..* — 1): se puede derivar (el aula es la del equipo) o modelar directa; se incluye por consulta frecuente.
- Estado y Prioridad se modelan como
enum. Si la lógica de transiciones fuera compleja, se justificaría el patrón State (clase Estado abstracta con subclases por estado y método siguiente()).
Cuestión 3 — Modelo de ciclo de vida
Elección: modelo iterativo-incremental, concretado con un marco ágil (Scrum).
Los dos requisitos del enunciado son determinantes:
- «Primera versión funcional pronto» → exige entregar valor temprano, lo que descarta los modelos secuenciales.
- «Cambios frecuentes en los requisitos durante el curso» → exige absorber cambios sin replanificar todo.
Por qué NO cascada: la cascada asume requisitos estables y completos al inicio, congela el alcance y entrega software solo al final. Con requisitos volátiles, cualquier cambio obliga a retroceder fases (caro y rígido) y el centro no vería nada funcional hasta tarde. Ventaja teórica (documentación y trazabilidad), pero inadecuada aquí.
Por qué SÍ iterativo-incremental / ágil (Scrum):
|
Iterativo-incremental / ágil |
Cascada |
| Entrega temprana |
Sí, por incrementos (sprints 2-4 sem.) |
No, solo al final |
| Adaptación a cambios |
Alta (replanificación por sprint) |
Baja |
| Feedback del cliente |
Continuo (revisión de sprint) |
Tardío |
| Riesgo |
Se reduce pronto |
Se acumula al final |
Ventajas para este contexto: MVP usable en pocas semanas; el coordinador TIC valida cada incremento y reorienta el backlog; el riesgo técnico se mitiga pronto; se prioriza por valor.
Inconvenientes a reconocer (honestidad técnica): requiere disponibilidad continua del «product owner» (coordinador TIC), menor documentación formal por defecto, estimación más difícil del alcance total y disciplina del equipo. Aun así, el balance favorece claramente lo ágil para un proyecto pequeño, evolutivo y con cliente accesible dentro del propio centro.
Cuestión 4 — Detección y corrección de incoherencias
Esquema propuesto por el compañero:
Incidencia(id, descripcion, prioridad, nombre_tecnico, telefono_tecnico, aula)
Tecnico(nombre, telefono)
Equipo(num_serie, aula, id_incidencia)
Incoherencias detectadas:
-
Redundancia / dependencia transitiva en Incidencia: nombre_tecnico y telefono_tecnico son atributos del técnico embebidos en la incidencia (viola 3FN: dependen de la clave del técnico, no de id). Si un técnico cambia de teléfono hay que actualizar TODAS sus incidencias → anomalía de actualización. Además, referenciar al técnico por su nombre es frágil (nombres duplicados, sin clave estable).
-
Cardinalidad imposible en Equipo: id_incidencia dentro de Equipo impone que cada equipo tenga una sola incidencia en toda su vida. El dominio dice lo contrario (un equipo sufre varias incidencias a lo largo del curso). La relación es 1 equipo → N incidencias, y se modela con la FK en el lado «muchos» (en Incidencia), no en Equipo.
-
Clave/redundancia en Tecnico y referencia incorrecta: Tecnico no tiene clave artificial estable; usa nombre como identificador implícito (no único, no inmutable). Falta un id_tecnico. Además Incidencia debe referenciar al técnico por clave foránea (id_tecnico), no copiando sus datos.
-
(Adicional) Redundancia de aula: el aula aparece en Incidencia y en Equipo. Si la incidencia es sobre un equipo y el equipo ya está en un aula, Incidencia.aula es derivable y puede contradecir a Equipo.aula → mejor mantenerla solo en Equipo (o como Aula propia con su clave) y derivarla.
Esquema corregido (claves primarias subrayadas con PK, foráneas marcadas FK, normalizado a 3FN):
Aula( _id_aula (PK)_, codigo, nombre )
Tecnico( _id_tecnico (PK)_, nombre, telefono, especialidad )
Equipo( _num_serie (PK)_, tipo, modelo,
id_aula (FK -> Aula) )
Incidencia( _id (PK)_, descripcion, prioridad, estado,
fecha_apertura, fecha_cierre,
num_serie (FK -> Equipo),
id_tecnico (FK -> Tecnico) NULL, -- NULL mientras no esté asignada
id_profesor (FK -> Usuario) )
Justificación: cada hecho se almacena una sola vez (3FN); el teléfono del técnico vive solo en Tecnico (sin anomalías); un equipo soporta N incidencias porque la FK num_serie está en el lado «muchos» (Incidencia); el aula es única (en Equipo) y derivable para la incidencia; todas las relaciones usan claves estables, no atributos descriptivos.
Cuestión 5 — Estimación y planificación
Descomposición en tareas (WBS) y estimación (puntos de historia + jornadas orientativas):
| Fase / Tarea |
Entregable |
Estimación |
| T1 Análisis: casos de uso + backlog |
Documento de requisitos |
3 SP (~2 j) |
| T2 Diseño: clases + modelo de datos |
Diagramas UML + DDL |
5 SP (~3 j) |
| T3 Base de datos + entidades/ORM |
Esquema migrado |
3 SP (~2 j) |
| T4 Login y gestión de usuarios/roles |
Autenticación |
5 SP (~3 j) |
| T5 Abrir incidencia (profesor) |
Form + persistencia |
5 SP (~3 j) |
| T6 Asignar (coordinador TIC) |
Asignación a técnico |
3 SP (~2 j) |
| T7 Resolver y cerrar (técnico) |
Cambio de estados |
3 SP (~2 j) |
| T8 Notificación al profesor (extend) |
Email al cerrar |
2 SP (~1 j) |
| T9 Panel/consultas y estadísticas |
Listados y filtros |
5 SP (~3 j) |
| T10 Pruebas + despliegue + documentación |
App desplegada |
5 SP (~3 j) |
Diagrama de Gantt descrito (sprints de 2 semanas):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 320" font-family="ui-sans-serif, system-ui, Arial, sans-serif">
<!-- Grid columns: weeks 1..8 -->
<!-- chart area x: 120..680 (8 weeks * 70px) -->
<text x="60" y="36" text-anchor="middle" font-size="12" font-weight="700" fill="#0f172a">Semana</text>
<g font-size="11.5" fill="#0f172a" text-anchor="middle" font-weight="600">
<text x="155" y="36">1</text>
<text x="225" y="36">2</text>
<text x="295" y="36">3</text>
<text x="365" y="36">4</text>
<text x="435" y="36">5</text>
<text x="505" y="36">6</text>
<text x="575" y="36">7</text>
<text x="645" y="36">8</text>
</g>
<!-- vertical week gridlines -->
<g stroke="#e2e8f0" stroke-width="1">
<line x1="120" y1="48" x2="120" y2="270"/>
<line x1="190" y1="48" x2="190" y2="270"/>
<line x1="260" y1="48" x2="260" y2="270"/>
<line x1="330" y1="48" x2="330" y2="270"/>
<line x1="400" y1="48" x2="400" y2="270"/>
<line x1="470" y1="48" x2="470" y2="270"/>
<line x1="540" y1="48" x2="540" y2="270"/>
<line x1="610" y1="48" x2="610" y2="270"/>
<line x1="680" y1="48" x2="680" y2="270"/>
</g>
<!-- Sprint 1: weeks 1-2 -->
<text x="14" y="76" font-size="12" font-weight="600" fill="#0f172a">Sprint 1</text>
<rect x="120" y="62" width="140" height="24" rx="6" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
<text x="700" y="78" font-size="11.5" fill="#334155">T1, T2, T3</text>
<!-- Sprint 2: weeks 3-4 -->
<text x="14" y="124" font-size="12" font-weight="600" fill="#0f172a">Sprint 2</text>
<rect x="260" y="110" width="140" height="24" rx="6" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
<text x="700" y="126" font-size="11.5" fill="#334155">T4, T5, T6, T7</text>
<!-- Sprint 3: weeks 5-6 -->
<text x="14" y="172" font-size="12" font-weight="600" fill="#0f172a">Sprint 3</text>
<rect x="400" y="158" width="140" height="24" rx="6" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
<text x="700" y="174" font-size="11.5" fill="#334155">T8, T9</text>
<!-- Sprint 4: weeks 7-8 -->
<text x="14" y="220" font-size="12" font-weight="600" fill="#0f172a">Sprint 4</text>
<rect x="540" y="206" width="140" height="24" rx="6" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
<text x="700" y="222" font-size="11.5" fill="#334155">T10</text>
<!-- Milestone MVP: end of S2 (week 4 = x 400) -->
<line x1="400" y1="48" x2="400" y2="270" stroke="#059669" stroke-width="2" stroke-dasharray="6 4"/>
<polygon points="400,250 408,262 392,262" fill="#059669"/>
<text x="400" y="290" text-anchor="middle" font-size="11" font-weight="700" fill="#059669">HITO MVP (fin S2)</text>
<!-- Milestone Release 1.0: end of S8 (week 8 = x 680) -->
<line x1="680" y1="48" x2="680" y2="270" stroke="#b45309" stroke-width="2" stroke-dasharray="6 4"/>
<polygon points="680,250 688,262 672,262" fill="#b45309"/>
<text x="660" y="290" text-anchor="middle" font-size="11" font-weight="700" fill="#b45309">Release 1.0 (fin S8)</text>
</svg>
Hito MVP (entrega mínima viable, fin del Sprint 2 / semana 4): el sistema permite el flujo de negocio completo end-to-end: el profesor abre una incidencia, el coordinador la asigna a un técnico y el técnico la cierra (T4+T5+T6+T7 básico, con login). Es el conjunto mínimo que aporta valor real al centro y permite recoger feedback. Las notificaciones, el panel de estadísticas y los refinamientos se entregan en incrementos posteriores, coherente con el ciclo de vida iterativo-incremental elegido en la Cuestión 3.