diff --git a/README.md b/README.md index 6e51ec6..241f5da 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,9 @@ sap_tfi_2026/ > **Resolver casos con hojas de ruta paso a paso:** > [https://cursos-uai.github.io/sap_tfi_2026/guias.html](https://cursos-uai.github.io/sap_tfi_2026/guias.html) +> **Controlar la entrega con la checklist interactiva:** +> [https://cursos-uai.github.io/sap_tfi_2026/checklist.html](https://cursos-uai.github.io/sap_tfi_2026/checklist.html) + El directorio **`prototipo/`** contiene una representación interactiva de las pantallas que actúan como fronteras (*boundaries*) en los diagramas de robustez. Permite observar cómo los botones, formularios, tablas, mensajes y otros diff --git a/prototipo/README.md b/prototipo/README.md index 84d44bf..ee54f60 100644 --- a/prototipo/README.md +++ b/prototipo/README.md @@ -54,6 +54,13 @@ comprender el problema, anticipar cambios, descomponer, diseñar interfaces, establecer relaciones y validar el diseño. Cada paso permite registrar el razonamiento, solicitar una pista y comparar al final con una solución modelo. +## Checklist del Trabajo Práctico + +Abrir `checklist.html` para controlar los diez grupos de entregables del TP: +requerimientos, casos de uso, dominio, prototipo, arquitectura, robustez, +secuencia, clases, patrones y testing estructural. Cada criterio admite una +evidencia y el progreso queda guardado localmente en el navegador. + ## Alcance Es un prototipo educativo, no una reproducción exacta ni conectada a Odoo. Los diff --git a/prototipo/checklist.css b/prototipo/checklist.css new file mode 100644 index 0000000..1176cef --- /dev/null +++ b/prototipo/checklist.css @@ -0,0 +1 @@ +:root{--ci:#17233b;--cm:#667085;--cl:#dce3ee;--ct:#087f73;--cs:#eef8f6;--cy:#ffd65a}.checklist-body{background:#f4f7fb;color:var(--ci);min-height:100vh}.checklist-shell{max-width:1240px;margin:auto;padding:46px 28px 70px}.checklist-hero{display:flex;justify-content:space-between;gap:32px;align-items:center;padding:38px 42px;color:#fff;border-radius:28px;background:linear-gradient(125deg,#14203a,#173b54 58%,#087f73 140%);box-shadow:0 20px 60px #15233b20}.checklist-hero h1{max-width:760px;margin:6px 0 12px;font-size:clamp(2rem,4vw,3.7rem);line-height:1.02;letter-spacing:-.045em}.checklist-hero p:not(.eyebrow){max-width:680px;margin:0;color:#d9e6ee}.hero-score{width:166px;aspect-ratio:1;flex:none;display:grid;place-content:center;text-align:center;border:1px solid #ffffff42;border-radius:50%;background:#ffffff10}.hero-score strong{font-size:2.45rem;line-height:1;color:var(--cy)}.hero-score span{font-size:.78rem;margin-top:8px;color:#d9e6ee}.quality-gates{display:flex;align-items:center;justify-content:center;gap:14px;margin:24px 0}.quality-gates article{display:flex;align-items:center;gap:10px;min-width:170px;padding:13px 15px;border:1px solid var(--cl);border-radius:14px;background:#fff}.quality-gates article>span{display:grid;place-content:center;width:30px;height:30px;border-radius:9px;background:var(--cs);color:var(--ct);font-weight:800}.quality-gates b,.quality-gates small{display:block}.quality-gates small{color:var(--cm);font-size:.7rem}.quality-gates>i{color:#98a2b3}.toolbar{position:sticky;z-index:5;top:0;display:flex;gap:10px;align-items:center;padding:14px;margin-bottom:22px;border:1px solid var(--cl);border-radius:16px;background:#ffffffed;backdrop-filter:blur(12px)}.search-box{display:flex;align-items:center;gap:8px;flex:1;padding:0 13px;border:1px solid var(--cl);border-radius:10px;background:#fff}.search-box input{width:100%;padding:10px 0;border:0;outline:0;background:transparent}.filters{display:flex;padding:3px;background:#eef2f7;border-radius:10px}.filters button,.quiet-button{border:0;border-radius:8px;padding:9px 12px;background:transparent;color:var(--cm);cursor:pointer}.filters button.active{background:#fff;color:var(--ci);box-shadow:0 2px 8px #15233b14}.quiet-button{border:1px solid var(--cl);background:#fff}.danger{color:#b42318}.checklist-layout{display:grid;grid-template-columns:245px minmax(0,1fr);gap:24px;align-items:start}.section-index{position:sticky;top:86px;padding:20px;border:1px solid var(--cl);border-radius:18px;background:#fff}.section-index nav{display:grid;gap:4px;margin-top:10px}.section-index a{display:flex;justify-content:space-between;padding:9px 10px;border-radius:9px;color:var(--cm);font-size:.86rem;text-decoration:none}.section-index a:hover{background:#f2f6fa}.count{color:var(--ct)}.evidence-key{margin-top:16px;padding:14px;border-radius:12px;background:#fff8df;font-size:.8rem}.evidence-key p{margin:5px 0 0;color:#695b2d;line-height:1.4}.checklist-sections{display:grid;gap:15px}.check-section{overflow:hidden;border:1px solid var(--cl);border-radius:18px;background:#fff;box-shadow:0 8px 24px #17233b0a}.check-section[hidden]{display:none}.section-head{width:100%;display:grid;grid-template-columns:44px 1fr auto 24px;gap:13px;align-items:center;padding:20px;border:0;background:#fff;text-align:left;cursor:pointer;color:var(--ci)}.section-number{display:grid;place-content:center;width:42px;height:42px;border-radius:12px;background:var(--cs);color:var(--ct);font-weight:850}.section-head h2{margin:0;font-size:1.12rem}.section-head p{margin:4px 0 0;color:var(--cm);font-size:.82rem}.section-progress{text-align:right}.section-progress b,.section-progress small{display:block}.section-progress b{color:var(--ct)}.section-progress small{color:var(--cm);font-size:.7rem}.chevron{transition:.2s}.check-section.open .chevron{transform:rotate(180deg)}.section-body{display:none;border-top:1px solid var(--cl)}.check-section.open .section-body{display:block}.check-item{display:grid;grid-template-columns:28px minmax(0,1fr);gap:12px;padding:16px 20px;border-bottom:1px solid #edf1f6}.check-item[hidden]{display:none}.check-item input[type=checkbox]{appearance:none;width:23px;height:23px;margin:1px 0;border:2px solid #b7c1cf;border-radius:7px;cursor:pointer}.check-item input[type=checkbox]:checked{border-color:var(--ct);background:var(--ct) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='white' stroke-width='3' d='m5 12 4 4 10-10'/%3E%3C/svg%3E") center/17px}.item-copy label{display:block;font-weight:680;line-height:1.35;cursor:pointer}.item-copy p{margin:4px 0;color:var(--cm);font-size:.82rem;line-height:1.45}.evidence-input{width:100%;box-sizing:border-box;margin-top:7px;padding:9px 11px;border:1px dashed #bcc7d5;border-radius:9px;background:#fafbfd}.check-item.done{background:#f7fbfa}.check-item.done label{text-decoration:line-through;color:#5d736f}.empty-state{padding:36px;text-align:center;color:var(--cm)}.traceability-card{display:flex;justify-content:space-between;align-items:center;gap:30px;margin-top:24px;padding:28px;border-radius:20px;background:#17233b;color:#fff}.traceability-card h2{margin:5px 0}.traceability-card p{margin:0;color:#cdd7e3}.trace-chain{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}.trace-chain span{padding:9px 10px;border-radius:9px;background:#ffffff12;border:1px solid #ffffff20;color:var(--cy);font-weight:800;font-size:.77rem}.trace-chain i{color:#8db6b0}.checklist-sources{display:flex;flex-wrap:wrap;gap:12px 18px;margin-top:20px;padding:20px;border:1px solid var(--cl);border-radius:16px;background:#fff;font-size:.84rem}.checklist-sources a{color:var(--ct)}@media(max-width:900px){.quality-gates{display:grid;grid-template-columns:1fr 1fr}.quality-gates>i{display:none}.checklist-layout{grid-template-columns:1fr}.section-index{position:static}.section-index nav{grid-template-columns:1fr 1fr}.toolbar{flex-wrap:wrap}.search-box{flex-basis:100%}.traceability-card{display:block}.trace-chain{margin-top:20px}}@media(max-width:620px){.checklist-shell{padding:24px 14px}.checklist-hero{display:block;padding:28px 22px}.hero-score{width:auto;aspect-ratio:auto;margin-top:24px;padding:18px;border-radius:16px}.quality-gates,.section-index nav{grid-template-columns:1fr}.section-head{grid-template-columns:38px 1fr 20px;padding:16px}.section-progress{display:none}.trace-chain i{display:none}} diff --git a/prototipo/checklist.html b/prototipo/checklist.html new file mode 100644 index 0000000..22a6455 --- /dev/null +++ b/prototipo/checklist.html @@ -0,0 +1,10 @@ +Checklist del TP · SAP-TFI-2026 +
SSAP · TFILaboratorio ICONIX
+
+

Control de entrega

¿Tu TP está completo y es trazable?

Marcá cada criterio sólo cuando puedas señalar su evidencia. El progreso se guarda en este navegador.

0%0 de 0 criterios
+
1
RRRRequerimientos
→
2
PDRDiseño preliminar
→
3
CDRDiseño crítico
→
4
V&VTesting y evidencias
+
+
+

Chequeo transversal

Cadena mínima de trazabilidad

Elegí un caso de uso central y seguí la misma historia de extremo a extremo.

REQ→CU→UI→ROB→SEC→CLA→TEST
+ +
diff --git a/prototipo/checklist.js b/prototipo/checklist.js new file mode 100644 index 0000000..aa6b296 --- /dev/null +++ b/prototipo/checklist.js @@ -0,0 +1,20 @@ +const S=[ +['req','Requerimientos','Capacidades y restricciones',[['Funcionales identificados, numerados y sin decisiones de implementación','Cada requisito expresa una capacidad observable.'],['No funcionales clasificados','Considerar seguridad, desempeño, usabilidad, portabilidad y disponibilidad.'],['Alcance, actores y glosario acordados','El vocabulario es consistente en todos los artefactos.'],['Cada requisito se vincula con casos de uso','La matriz permite recorrer REQ → CU.'],['Al menos un criterio de aceptación por requisito','Debe ser comprobable y describir el resultado esperado.']]], +['cu','Casos de uso y especificaciones','Comportamiento desde la mirada del actor',[['Diagrama general con actores, casos y límite del sistema','Cada actor persigue un objetivo claro.'],['include y extend usados con sentido','include es obligatorio reutilizado; extend, opcional o condicionado.'],['Una especificación por caso relevante','Incluye objetivo, actor, precondiciones, disparador y postcondiciones.'],['Curso básico escrito en voz activa','Cada paso muestra actor, acción y respuesta del sistema.'],['Alternativos, excepciones y reglas documentados','Cada desvío tiene condición, respuesta y cierre.'],['Hito RRR revisado con interesados','Casos de uso, dominio y prototipo capturan los requerimientos.']]], +['dom','Modelo de dominio','Vocabulario conceptual del problema',[['Clases tomadas del lenguaje del negocio','No incluye pantallas, controles ni detalles técnicos.'],['Atributos conceptuales relevantes','Evita claves foráneas y decisiones de persistencia.'],['Relaciones y multiplicidades justificadas','Cada asociación expresa un hecho del dominio.'],['Nombres sin sinónimos ni ambigüedades','El mismo concepto conserva su nombre.'],['Modelo actualizado después de robustez','Todas las entidades descubiertas aparecen en el dominio.']]], +['ui','Prototipo','Fronteras y recorrido del usuario',[['Pantallas y estados relevantes representados','Incluye formularios, listados, mensajes, confirmaciones y errores.'],['Cada pantalla se vincula con casos y actores','La navegación materializa cursos básicos y alternativos.'],['Controles y datos coinciden con las especificaciones','No hay acciones huérfanas ni entradas faltantes.'],['Prototipo revisado con usuarios','Se registraron observaciones y decisiones.'],['Se usa como especificación, no como producto final','Sirve para desambiguar y descubrir fronteras.']]], +['arch','Arquitectura','Estructura y decisiones técnicas',[['Vistas funcional, de datos y del sistema separadas','Cada una responde una pregunta arquitectónica.'],['Componentes, capas, responsabilidades e interfaces visibles','Las dependencias respetan el estilo declarado.'],['Despliegue, nodos y tecnologías documentados','Incluye persistencia e integraciones externas.'],['Decisiones justificadas por requerimientos','No se basan sólo en preferencias tecnológicas.'],['Calidad y testing considerados','Contempla cambio, seguridad, rendimiento y comprobabilidad.']]], +['rob','Diagramas de robustez','Puente entre casos de uso y diseño',[['Un diagrama por caso de uso diseñado','El texto se sigue frase por frase.'],['Actor, Boundary, Control y Entity diferenciados','Fronteras y entidades son sustantivos; controles, acciones.'],['Reglas de comunicación respetadas','Actor↔Boundary; Boundary↔Control; Entity↔Control.'],['Una frontera clara por pantalla o interfaz','Los nombres coinciden con prototipo y texto.'],['Entidades consistentes con el dominio','Toda entidad está en el modelo actualizado.'],['Controles cubren cursos básicos y alternativos','Sin asignar todavía métodos ni algoritmos.'],['Hito PDR aprobado','Texto, robustez, dominio, datos y arquitectura son consistentes.']]], +['seq','Diagramas de secuencia','Diseño detallado por escenario',[['Un diagrama por caso de uso','Incluye curso básico y alternativos.'],['Participantes derivados de robustez','No aparecen objetos sin responsabilidad explicada.'],['Texto del caso mapeado a mensajes','Orden, retornos, condiciones y ciclos son visibles.'],['Controles asignados a operaciones u objetos','Cada mensaje llega al responsable del comportamiento.'],['Mensajes respetan arquitectura y patrones','El detalle orienta la implementación.'],['Errores y resultados observables representados','Las respuestas regresan a la frontera.']]], +['class','Diagrama de clases','Modelo estático listo para implementar',[['Clases con responsabilidades, atributos y operaciones','Las operaciones surgen de secuencia.'],['Tipos, visibilidad y firmas especificados','Los contratos permiten comprender la colaboración.'],['Relaciones y multiplicidades correctas','Herencia y composición tienen necesidad demostrable.'],['Alta cohesión y bajo acoplamiento revisados','Cada clase protege un secreto coherente.'],['Interfaces aíslan decisiones que pueden cambiar','Se aplica ocultamiento de información.'],['Consistencia con dominio, secuencias y código','No faltan ni sobran elementos sin trazabilidad.'],['Hito CDR aprobado','Diseño completo, correcto, realizable y alineado.']]], +['patterns','Patrones de diseño','Problema, decisión y consecuencias',[['Cada patrón resuelve un problema concreto','Se explica contexto y necesidad.'],['Participantes y colaboraciones identificados','Las clases del TP se mapean a roles.'],['Clases reflejan la estructura del patrón','No es sólo un ejemplo genérico copiado.'],['Secuencias reflejan su comportamiento','Los mensajes muestran un escenario real.'],['Alternativas, beneficios y costos documentados','Evalúa acoplamiento, extensión y complejidad.']]], +['test','Testing estructural','Pruebas derivadas del código',[['Unidad, especificación y dominio de entrada definidos','Cada caso usa valores concretos y salida esperada.'],['Grafo de flujo de control construido','Nodos, decisiones y flechas corresponden al código.'],['Criterio de cobertura declarado','Distingue sentencias, ramas, condiciones y caminos.'],['Conjunto de pruebas satisface el criterio','Vincula entrada, camino, esperado y obtenido.'],['Cobertura medida y evidencia adjunta','Incluye reporte o cálculo verificable.'],['Casos normales, límites y fallas incluidos','La selección busca revelar defectos.'],['Pruebas re-ejecutables y resultado registrado','Documenta ambiente, versión, fecha y estado.'],['Trazabilidad hasta TEST comprobada','Una prueba demuestra cada requisito del alcance.']]]]; +const K='sap-tfi-checklist-v1',root=document.querySelector('#checklist-sections'),index=document.querySelector('#section-index');let st=JSON.parse(localStorage.getItem(K)||'{}'),filter='all',query=''; +const items=S.flatMap(([sid,,,a])=>a.map((x,i)=>[`${sid}-${i}`, ...x])); +const get=id=>st[id]||{done:false,evidence:''},esc=v=>(v||'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])),save=()=>localStorage.setItem(K,JSON.stringify(st)); +function match(id,t,h){const x=get(id);return(filter==='all'||(filter==='done'?x.done:!x.done))&&`${t} ${h}`.toLowerCase().includes(query)} +function render(){root.innerHTML=S.map(([sid,title,sub,a],n)=>{const done=a.filter((_,i)=>get(`${sid}-${i}`).done).length,vis=a.map((x,i)=>[`${sid}-${i}`,...x]).filter(x=>match(...x));return`
${vis.map(row).join('')}
`}).join('');if(!root.querySelector('.check-section:not([hidden])'))root.innerHTML='
No hay criterios que coincidan con este filtro.
';index.innerHTML=S.map(([sid,t,,a])=>`${t}${a.filter((_,i)=>get(`${sid}-${i}`).done).length}/${a.length}`).join('');bind();total()} +function row([id,t,h]){const x=get(id);return`

${h}

`} +function bind(){document.querySelectorAll('.section-head').forEach(b=>b.onclick=()=>{const c=b.closest('.check-section');c.classList.toggle('open');b.setAttribute('aria-expanded',c.classList.contains('open'))});document.querySelectorAll('.check-item').forEach(r=>{const id=r.dataset.id,c=r.querySelector('[type=checkbox]'),e=r.querySelector('.evidence-input');c.onchange=()=>{st[id]={done:c.checked,evidence:e.value};save();render()};e.oninput=()=>{st[id]={done:c.checked,evidence:e.value};save()}})} +function total(){const done=items.filter(([id])=>get(id).done).length;document.querySelector('#total-percent').textContent=`${Math.round(done/items.length*100)}%`;document.querySelector('#total-copy').textContent=`${done} de ${items.length} criterios`} +document.querySelector('#search').oninput=e=>{query=e.target.value.trim().toLowerCase();render()};document.querySelectorAll('[data-filter]').forEach(b=>b.onclick=()=>{filter=b.dataset.filter;document.querySelectorAll('[data-filter]').forEach(x=>x.classList.toggle('active',x===b));render()});document.querySelector('#expand-all').onclick=e=>{const a=[...document.querySelectorAll('.check-section')],open=a.some(c=>!c.classList.contains('open'));a.forEach(c=>c.classList.toggle('open',open));e.target.textContent=open?'Contraer todo':'Expandir todo'};document.querySelector('#reset-checklist').onclick=()=>{if(confirm('¿Borrar todos los tildes y evidencias?')){st={};save();render()}};render(); diff --git a/prototipo/ejercicios.html b/prototipo/ejercicios.html index 246bb5a..a012557 100644 --- a/prototipo/ejercicios.html +++ b/prototipo/ejercicios.html @@ -11,7 +11,7 @@
SSAP · TFILaboratorio ICONIX - +
diff --git a/prototipo/guias.html b/prototipo/guias.html index 07c1e1a..9a6facb 100644 --- a/prototipo/guias.html +++ b/prototipo/guias.html @@ -11,7 +11,7 @@
SSAP · TFILaboratorio ICONIX - +
diff --git a/prototipo/index.html b/prototipo/index.html index 7396cc2..e0951a3 100644 --- a/prototipo/index.html +++ b/prototipo/index.html @@ -13,7 +13,7 @@ S SAP · TFILaboratorio ICONIX - +