mirror of
https://github.com/cursos-uai/sap_tfi_2026.git
synced 2026-09-17 17:29:21 -03:00
feat: documentar proceso de entrega final
Co-authored-by: wsf <alejandro.sartorio@gmail.com> Signed-off-by: wsf <alejandro.sartorio@gmail.com>
This commit is contained in:
@@ -48,6 +48,7 @@ sap_tfi_2026/
|
||||
├── evidence/
|
||||
│ └── index.md ← catálogo de evidencias
|
||||
├── prototipo/ ← pantallas navegables y trazabilidad ICONIX
|
||||
├── trabajo_final/ ← entregas de alumnos por pull request
|
||||
└── .gitignore
|
||||
```
|
||||
|
||||
@@ -68,6 +69,24 @@ entrega final.
|
||||
|
||||
---
|
||||
|
||||
## Procedimiento de entrega final
|
||||
|
||||
Antes de rendir, cada alumno debe entregar el trabajo mediante GitHub:
|
||||
|
||||
1. Hacer un [fork de este repositorio](https://github.com/cursos-uai/sap_tfi_2026/fork).
|
||||
2. Subir el trabajo completo dentro de
|
||||
**`trabajo_final/Apellido_Nombre/`**, reemplazando el ejemplo por los datos
|
||||
del alumno y sin utilizar espacios.
|
||||
3. Abrir un **pull request** desde el fork hacia la rama `main` de este
|
||||
repositorio.
|
||||
4. Presentar cada actualización posterior mediante un **nuevo pull request**.
|
||||
|
||||
Las instrucciones completas y la estructura esperada están en
|
||||
[`trabajo_final/README.md`](trabajo_final/README.md). No se deben modificar las
|
||||
carpetas correspondientes a otros alumnos.
|
||||
|
||||
---
|
||||
|
||||
## Prototipo navegable de fronteras ICONIX
|
||||
|
||||
El directorio **`prototipo/`** contiene una representación interactiva de las
|
||||
|
||||
+3
-1
@@ -62,7 +62,9 @@ secuencia, clases, patrones y testing estructural. Cada criterio admite una
|
||||
referencia precisa al borrador —página, sección, tabla, figura, párrafo u otra—
|
||||
y el progreso queda guardado localmente en el navegador. Al finalizar se puede
|
||||
generar un informe `.md`, descargarlo y preparar el correo de seguimiento para
|
||||
el profesor Alejandro Sartorio.
|
||||
el profesor Alejandro Sartorio. Para la entrega definitiva antes de rendir, la
|
||||
página también guía el fork del repositorio, la ubicación obligatoria
|
||||
`trabajo_final/Apellido_Nombre/` y el pull request que registra cada versión.
|
||||
|
||||
## Alcance
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@
|
||||
<section class="toolbar"><label class="search-box"><span>⌕</span><input id="search" type="search" placeholder="Buscar criterio o artefacto…"></label><div class="filters"><button class="active" data-filter="all">Todos</button><button data-filter="pending">Pendientes</button><button data-filter="done">Completos</button></div><button id="expand-all" class="quiet-button">Contraer todo</button><button id="reset-checklist" class="quiet-button danger">Reiniciar</button></section>
|
||||
<div class="checklist-layout"><aside class="section-index"><div class="step-badge">Paso 2</div><p class="eyebrow">Validar y referenciar</p><nav id="section-index"></nav><div class="evidence-key"><b>Regla de oro</b><p>Para completar un ítem indicá el tipo y la ubicación exacta de la evidencia dentro del borrador.</p></div></aside><section id="checklist-sections" class="checklist-sections" aria-live="polite"></section></div>
|
||||
<section class="submission-card"><div class="submission-copy"><div class="step-badge">Paso 3</div><p class="eyebrow">Preparar el seguimiento</p><h2>Generá y enviá el informe</h2><p>Revisá los datos, descargá el archivo Markdown y enviáselo al profesor para tutoría y evaluación.</p><div id="readiness" class="readiness" role="status"></div></div><div class="submission-actions"><button id="preview-report" class="quiet-button">Vista previa</button><button id="download-report" class="primary-action">Generar archivo .md</button><button id="email-report" class="email-action">Enviar al profesor</button><small>El correo se abrirá dirigido a <b>alejandro.sartorio@gmail.com</b>. Adjuntá el `.md` descargado antes de enviarlo.</small></div></section>
|
||||
<section class="final-delivery" aria-labelledby="delivery-title"><header><div class="step-badge">Paso 4 · Entrega final</div><p class="eyebrow">Antes de rendir</p><h2 id="delivery-title">Publicá tu trabajo mediante un pull request</h2><p>La entrega oficial queda registrada en GitHub. Repetí el pull request cada vez que presentes una actualización.</p></header><ol class="delivery-steps"><li><span>1</span><div><h3>Hacé un fork del repositorio</h3><p>Creá una copia en tu cuenta desde <a href="https://github.com/cursos-uai/sap_tfi_2026/fork" target="_blank" rel="noreferrer">cursos-uai/sap_tfi_2026 ↗</a>.</p><label><input id="delivery-fork" type="checkbox"> Ya creé mi fork</label></div></li><li><span>2</span><div><h3>Subí el trabajo en la ubicación obligatoria</h3><p>Usá exactamente <code>trabajo_final/Apellido_Nombre/</code>, reemplazando el ejemplo por tus datos y sin espacios.</p><label>Nombre de la carpeta<input id="delivery-folder" placeholder="Ej.: Sartorio_Alejandro"></label></div></li><li><span>3</span><div><h3>Abrí un pull request hacia este repositorio</h3><p>En el título indicá apellido, nombre y versión. Para cada actualización, agregá cambios a tu fork y abrí un nuevo PR.</p><label>Link del pull request<input id="delivery-pr" type="url" placeholder="https://github.com/cursos-uai/sap_tfi_2026/pull/…"></label></div></li></ol><div id="delivery-status" class="delivery-status" role="status"></div></section>
|
||||
<dialog id="report-dialog"><div class="dialog-head"><div><p class="eyebrow">Vista previa</p><h2>Informe de seguimiento</h2></div><button id="close-report" aria-label="Cerrar">×</button></div><pre id="report-preview"></pre></dialog>
|
||||
<section class="traceability-card"><div><p class="eyebrow">Chequeo transversal</p><h2>Cadena mínima de trazabilidad</h2><p>Elegí un caso de uso central y seguí la misma historia de extremo a extremo.</p></div><div class="trace-chain"><span>REQ</span><i>→</i><span>CU</span><i>→</i><span>UI</span><i>→</i><span>ROB</span><i>→</i><span>SEC</span><i>→</i><span>CLA</span><i>→</i><span>TEST</span></div></section>
|
||||
<footer class="checklist-sources"><b>Fuentes:</b><a href="https://docs.google.com/document/d/1oThnR9euP2YW4K94A3oAoE3pvHdeDyNShRdwWDY-Nmk/edit?usp=sharing" target="_blank" rel="noreferrer">Temas técnicos ↗</a><a href="https://docs.google.com/document/d/1_ZjiF3pUANt0-bm4V6Xph6hdJuHCnxbp/edit?usp=sharing" target="_blank" rel="noreferrer">Apunte ICONIX ↗</a><a href="https://www.fceia.unr.edu.ar/ingsoft/testing-intro-a.pdf" target="_blank" rel="noreferrer">Testing ↗</a><a href="https://www.fceia.unr.edu.ar/ingsoft/testing-estruct-a.pdf" target="_blank" rel="noreferrer">Testing estructural ↗</a><a href="https://www.fceia.unr.edu.ar/ingsoft/p-testing.pdf" target="_blank" rel="noreferrer">Práctica ↗</a></footer>
|
||||
|
||||
@@ -23,10 +23,11 @@ function render(){root.innerHTML=S.map(([sid,title,sub,a],n)=>{const done=a.filt
|
||||
function row([id,t,h]){const x=get(id),invalid=x.done&&(!x.type||!x.location.trim());return`<div class="check-item ${x.done?'done':''} ${invalid?'invalid':''}" data-id="${id}"><input id="${id}" type="checkbox" ${x.done?'checked':''}><div class="item-copy"><label for="${id}">${t}</label><p>${h}</p><div class="evidence-fields"><select class="evidence-type" aria-label="Tipo de referencia para ${t}"><option value="">Tipo de referencia…</option>${types.map(v=>`<option ${x.type===v?'selected':''}>${v}</option>`).join('')}</select><input class="evidence-location" aria-label="Ubicación para ${t}" placeholder="Ej.: pág. 12, sección 3.2, figura D-ROB-01" value="${esc(x.location)}"></div><small class="reference-help">Indicá dónde puede encontrar el profesor la evidencia dentro del borrador.</small></div></div>`}
|
||||
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]'),t=r.querySelector('.evidence-type'),l=r.querySelector('.evidence-location');const update=()=>{st[id]={done:c.checked,type:t.value,location:l.value};save();total()};c.onchange=()=>{update();render()};t.onchange=update;l.oninput=update})}
|
||||
function total(){const done=items.filter(([id])=>get(id).done).length,valid=items.filter(([id])=>{const x=get(id);return x.done&&x.type&&x.location.trim()}).length,missing=done-valid;document.querySelector('#total-percent').textContent=`${Math.round(valid/items.length*100)}%`;document.querySelector('#total-copy').textContent=`${valid} de ${items.length} referenciados`;const box=document.querySelector('#readiness');box.className=`readiness ${missing?'warning':valid?'ready':''}`;box.textContent=missing?`${missing} ítem${missing===1?'':'s'} marcado${missing===1?'':'s'} sin referencia completa.`:valid?`El informe tiene ${valid} evidencias listas para compartir.`:'Completá criterios para construir el informe.'}
|
||||
function syncMeta(){meta={student:document.querySelector('#student-name').value.trim(),group:document.querySelector('#course-group').value.trim(),draft:document.querySelector('#draft-link').value.trim()};save()}
|
||||
function report(){syncMeta();const done=items.filter(([id])=>get(id).done);let out=`# Informe de seguimiento del Trabajo Práctico\n\n- **Alumno/a o equipo:** ${md(meta.student)||'Sin completar'}\n- **Comisión:** ${md(meta.group)||'Sin completar'}\n- **Documento borrador:** ${meta.draft?`[Abrir borrador](${meta.draft})`:'Sin completar'}\n- **Fecha de generación:** ${new Date().toLocaleDateString('es-AR')}\n- **Avance referenciado:** ${done.filter(([id])=>get(id).type&&get(id).location.trim()).length}/${items.length} criterios\n\n`;S.forEach(([sid,title,,a])=>{out+=`## ${title}\n\n| Estado | Criterio | Tipo de referencia | Ubicación en el documento |\n|---|---|---|---|\n`;a.forEach(([t],i)=>{const x=get(`${sid}-${i}`);out+=`| ${x.done?'✅ Cumple':'⬜ Pendiente'} | ${md(t)} | ${md(x.type)||'—'} | ${md(x.location)||'—'} |\n`});out+='\n'});out+='---\n\nInforme generado con la checklist interactiva SAP-TFI-2026.\n';return out}
|
||||
function syncMeta(){meta={student:document.querySelector('#student-name').value.trim(),group:document.querySelector('#course-group').value.trim(),draft:document.querySelector('#draft-link').value.trim(),fork:document.querySelector('#delivery-fork').checked,folder:document.querySelector('#delivery-folder').value.trim(),pr:document.querySelector('#delivery-pr').value.trim()};save();deliveryStatus()}
|
||||
function report(){syncMeta();const done=items.filter(([id])=>get(id).done);let out=`# Informe de seguimiento del Trabajo Práctico\n\n- **Alumno/a o equipo:** ${md(meta.student)||'Sin completar'}\n- **Comisión:** ${md(meta.group)||'Sin completar'}\n- **Documento borrador:** ${meta.draft?`[Abrir borrador](${meta.draft})`:'Sin completar'}\n- **Fecha de generación:** ${new Date().toLocaleDateString('es-AR')}\n- **Avance referenciado:** ${done.filter(([id])=>get(id).type&&get(id).location.trim()).length}/${items.length} criterios\n\n`;S.forEach(([sid,title,,a])=>{out+=`## ${title}\n\n| Estado | Criterio | Tipo de referencia | Ubicación en el documento |\n|---|---|---|---|\n`;a.forEach(([t],i)=>{const x=get(`${sid}-${i}`);out+=`| ${x.done?'✅ Cumple':'⬜ Pendiente'} | ${md(t)} | ${md(x.type)||'—'} | ${md(x.location)||'—'} |\n`});out+='\n'});out+=`## Entrega final por GitHub\n\n- **Fork creado:** ${meta.fork?'Sí':'Pendiente'}\n- **Carpeta de entrega:** ${meta.folder?`\`trabajo_final/${md(meta.folder)}/\``:'Pendiente'}\n- **Pull request:** ${meta.pr?`[Abrir pull request](${meta.pr})`:'Pendiente'}\n- **Política de actualización:** abrir un nuevo pull request por cada actualización de la entrega.\n\n---\n\nInforme generado con la checklist interactiva SAP-TFI-2026.\n`;return out}
|
||||
function validateForShare(){syncMeta();const errors=[];if(!meta.student)errors.push('el nombre del alumno o equipo');if(!meta.draft||!/^https?:\/\//i.test(meta.draft))errors.push('un link válido al borrador');const incomplete=items.filter(([id])=>{const x=get(id);return x.done&&(!x.type||!x.location.trim())}).length;if(incomplete)errors.push(`la referencia de ${incomplete} ítem${incomplete===1?'':'s'} marcado${incomplete===1?'':'s'}`);if(errors.length){alert(`Antes de compartir, completá ${errors.join(', ')}.`);return false}return true}
|
||||
function download(){if(!validateForShare())return false;const blob=new Blob([report()],{type:'text/markdown;charset=utf-8'}),url=URL.createObjectURL(blob),a=document.createElement('a'),slug=(meta.student||'alumno').toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');a.href=url;a.download=`seguimiento-tp-${slug||'alumno'}.md`;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);return true}
|
||||
['student-name','course-group','draft-link'].forEach(id=>{const el=document.querySelector(`#${id}`),key=id==='student-name'?'student':id==='course-group'?'group':'draft';el.value=meta[key]||'';el.oninput=syncMeta});
|
||||
['student-name','course-group','draft-link'].forEach(id=>{const el=document.querySelector(`#${id}`),key=id==='student-name'?'student':id==='course-group'?'group':'draft';el.value=meta[key]||'';el.oninput=syncMeta});const fork=document.querySelector('#delivery-fork'),folder=document.querySelector('#delivery-folder'),pr=document.querySelector('#delivery-pr');fork.checked=!!meta.fork;folder.value=meta.folder||'';pr.value=meta.pr||'';fork.onchange=syncMeta;folder.oninput=syncMeta;pr.oninput=syncMeta;
|
||||
function deliveryStatus(){const box=document.querySelector('#delivery-status'),folderOk=/^[A-Za-zÀ-ÿ'’-]+_[A-Za-zÀ-ÿ'’-]+$/.test(meta.folder||''),prOk=/^https:\/\/github\.com\/[^/]+\/sap_tfi_2026\/pull\/\d+/i.test(meta.pr||'');const count=[meta.fork,folderOk,prOk].filter(Boolean).length;box.className=`delivery-status ${count===3?'ready':''}`;box.textContent=count===3?'Entrega final documentada: fork, carpeta y pull request completos.':`${count}/3 pasos documentados. La carpeta debe usar Apellido_Nombre y el link debe corresponder a un pull request.`}
|
||||
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 datos, tildes y referencias?')){st={};meta={};localStorage.removeItem(K);localStorage.removeItem(META);location.reload()}};
|
||||
const dialog=document.querySelector('#report-dialog');document.querySelector('#preview-report').onclick=()=>{document.querySelector('#report-preview').textContent=report();dialog.showModal()};document.querySelector('#close-report').onclick=()=>dialog.close();document.querySelector('#download-report').onclick=download;document.querySelector('#email-report').onclick=()=>{if(!download())return;const subject=encodeURIComponent(`Seguimiento TP SAP-TFI-2026 · ${meta.student}`),body=encodeURIComponent(`Profesor Alejandro Sartorio:\n\nAdjunto el informe Markdown de seguimiento de nuestro Trabajo Práctico.\n\nDocumento borrador: ${meta.draft}\n\nAlumno/a o equipo: ${meta.student}\nComisión: ${meta.group||'Sin completar'}\n\nImportante: adjuntar el archivo .md que acaba de descargarse antes de enviar este correo.`);window.location.href=`mailto:alejandro.sartorio@gmail.com?subject=${subject}&body=${body}`};render();
|
||||
const dialog=document.querySelector('#report-dialog');document.querySelector('#preview-report').onclick=()=>{document.querySelector('#report-preview').textContent=report();dialog.showModal()};document.querySelector('#close-report').onclick=()=>dialog.close();document.querySelector('#download-report').onclick=download;document.querySelector('#email-report').onclick=()=>{if(!download())return;const subject=encodeURIComponent(`Seguimiento TP SAP-TFI-2026 · ${meta.student}`),body=encodeURIComponent(`Profesor Alejandro Sartorio:\n\nAdjunto el informe Markdown de seguimiento de nuestro Trabajo Práctico.\n\nDocumento borrador: ${meta.draft}\n\nAlumno/a o equipo: ${meta.student}\nComisión: ${meta.group||'Sin completar'}\n\nImportante: adjuntar el archivo .md que acaba de descargarse antes de enviar este correo.`);window.location.href=`mailto:alejandro.sartorio@gmail.com?subject=${subject}&body=${body}`};deliveryStatus();render();
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Entregas finales de alumnos
|
||||
|
||||
Cada alumno debe entregar su Trabajo Final dentro de una carpeta propia con
|
||||
este formato:
|
||||
|
||||
```text
|
||||
trabajo_final/
|
||||
└── Apellido_Nombre/
|
||||
├── README.md
|
||||
└── ...archivos del trabajo...
|
||||
```
|
||||
|
||||
## Procedimiento obligatorio
|
||||
|
||||
1. Hacer un **fork** de
|
||||
[cursos-uai/sap_tfi_2026](https://github.com/cursos-uai/sap_tfi_2026/fork)
|
||||
en la cuenta personal de GitHub.
|
||||
2. Crear una rama en el fork para la entrega.
|
||||
3. Crear `trabajo_final/Apellido_Nombre/`, sin espacios, y colocar allí todos
|
||||
los archivos. No modificar carpetas de otros alumnos.
|
||||
4. Agregar dentro de la carpeta personal un `README.md` con nombre, comisión,
|
||||
link al documento borrador o final y una breve descripción de la versión.
|
||||
5. Hacer commit y push de la rama al fork.
|
||||
6. Abrir un **pull request** hacia la rama `main` de este repositorio.
|
||||
|
||||
## Actualizaciones
|
||||
|
||||
Cada actualización de una entrega se presenta mediante un **nuevo pull
|
||||
request**. El título recomendado es:
|
||||
|
||||
```text
|
||||
Entrega TP — Apellido Nombre — versión N
|
||||
```
|
||||
|
||||
Antes de abrirlo, sincronizar el fork con `main`, crear una nueva rama, cambiar
|
||||
únicamente la carpeta personal y describir en el PR qué se actualizó.
|
||||
|
||||
> No subir credenciales, contraseñas, tokens, datos personales sensibles,
|
||||
> bases de datos productivas ni archivos que no correspondan al TP.
|
||||
Reference in New Issue
Block a user