diff --git a/README.md b/README.md index 4c8945c..2e569e9 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/prototipo/README.md b/prototipo/README.md index 4d4fe1b..f5d9905 100644 --- a/prototipo/README.md +++ b/prototipo/README.md @@ -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 diff --git a/prototipo/checklist.css b/prototipo/checklist.css index 088381d..8afca63 100644 --- a/prototipo/checklist.css +++ b/prototipo/checklist.css @@ -1,2 +1,3 @@ :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}} .step-badge{display:inline-block;padding:5px 9px;border-radius:999px;background:#dff3ef;color:var(--ct);font-size:.72rem;font-weight:850;text-transform:uppercase;letter-spacing:.05em}.project-card{display:grid;grid-template-columns:auto 260px 1fr;gap:20px;align-items:start;margin:24px 0;padding:24px;border:1px solid var(--cl);border-radius:20px;background:#fff}.project-intro h2,.submission-card h2{margin:4px 0 6px}.project-intro p:not(.eyebrow),.submission-card p:not(.eyebrow){margin:0;color:var(--cm);line-height:1.45}.project-fields{display:grid;grid-template-columns:1fr 1fr;gap:13px}.project-fields label{font-size:.78rem;font-weight:750;color:#475467}.project-fields label.wide{grid-column:1/-1}.project-fields input{width:100%;box-sizing:border-box;margin-top:6px;padding:11px 12px;border:1px solid #bfc9d7;border-radius:9px;color:var(--ci)}.project-fields small{display:block;margin-top:5px;color:var(--cm);font-weight:400}.evidence-fields{display:grid;grid-template-columns:180px 1fr;gap:8px;margin-top:10px}.evidence-type,.evidence-location{width:100%;box-sizing:border-box;padding:9px 11px;border:1px solid #bcc7d5;border-radius:9px;background:#fafbfd;color:var(--ci)}.check-item.invalid{background:#fff7f5}.check-item.invalid .evidence-type,.check-item.invalid .evidence-location{border-color:#e0796f}.reference-help{display:block;margin-top:5px;color:var(--cm);font-size:.72rem}.submission-card{display:grid;grid-template-columns:1fr 430px;gap:30px;align-items:center;margin-top:24px;padding:30px;border:1px solid #b8d8d2;border-radius:22px;background:linear-gradient(125deg,#f4fbfa,#fff)}.submission-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px}.submission-actions button{padding:12px;border-radius:10px;cursor:pointer;font-weight:750}.primary-action{border:0;background:var(--ct);color:#fff}.email-action{grid-column:1/-1;border:0;background:var(--ci);color:#fff}.submission-actions small{grid-column:1/-1;color:var(--cm);line-height:1.4}.readiness{margin-top:14px;padding:10px 12px;border-radius:10px;background:#eef2f7;color:#475467;font-size:.82rem}.readiness.ready{background:#e8f7f1;color:#08734f}.readiness.warning{background:#fff3e8;color:#9a3412}#report-dialog{width:min(860px,90vw);max-height:82vh;padding:0;border:0;border-radius:18px;box-shadow:0 30px 90px #1018284d}#report-dialog::backdrop{background:#10182899}.dialog-head{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid var(--cl)}.dialog-head h2{margin:3px 0}.dialog-head button{border:0;background:transparent;font-size:1.8rem;cursor:pointer}#report-preview{max-height:62vh;margin:0;padding:24px;overflow:auto;white-space:pre-wrap;font:13px/1.55 ui-monospace,monospace;background:#f8fafc;color:#344054}@media(max-width:900px){.project-card{grid-template-columns:auto 1fr}.project-fields{grid-column:1/-1}.submission-card{grid-template-columns:1fr}}@media(max-width:620px){.project-card{grid-template-columns:1fr}.project-fields{grid-template-columns:1fr}.project-fields label.wide{grid-column:auto}.evidence-fields,.submission-actions{grid-template-columns:1fr}.email-action{grid-column:auto}} +.final-delivery{margin-top:24px;padding:30px;border-radius:22px;background:#fff;border:1px solid var(--cl)}.final-delivery header{max-width:780px}.final-delivery header h2{margin:7px 0}.final-delivery header p:not(.eyebrow){margin:0;color:var(--cm)}.delivery-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:24px 0;padding:0;list-style:none}.delivery-steps li{display:grid;grid-template-columns:34px 1fr;gap:12px;padding:18px;border:1px solid var(--cl);border-radius:16px;background:#fafbfd}.delivery-steps li>span{display:grid;place-content:center;width:32px;height:32px;border-radius:10px;background:var(--ci);color:#fff;font-weight:800}.delivery-steps h3{margin:5px 0 7px;font-size:.98rem}.delivery-steps p{min-height:62px;margin:0 0 14px;color:var(--cm);font-size:.8rem;line-height:1.45}.delivery-steps a{color:var(--ct)}.delivery-steps label{display:block;color:#475467;font-size:.76rem;font-weight:750}.delivery-steps label input:not([type=checkbox]){width:100%;box-sizing:border-box;margin-top:6px;padding:9px 10px;border:1px solid #bfc9d7;border-radius:9px}.delivery-steps input[type=checkbox]{margin-right:6px}.delivery-status{padding:12px 14px;border-radius:11px;background:#fff3e8;color:#9a3412;font-size:.84rem}.delivery-status.ready{background:#e8f7f1;color:#08734f}@media(max-width:900px){.delivery-steps{grid-template-columns:1fr}.delivery-steps p{min-height:auto}} diff --git a/prototipo/checklist.html b/prototipo/checklist.html index 874a481..db834e0 100644 --- a/prototipo/checklist.html +++ b/prototipo/checklist.html @@ -7,6 +7,7 @@
Paso 3

Preparar el seguimiento

Generá y enviá el informe

Revisá los datos, descargá el archivo Markdown y enviáselo al profesor para tutoría y evaluación.

El correo se abrirá dirigido a alejandro.sartorio@gmail.com. Adjuntá el `.md` descargado antes de enviarlo.
+
Paso 4 · Entrega final

Antes de rendir

Publicá tu trabajo mediante un pull request

La entrega oficial queda registrada en GitHub. Repetí el pull request cada vez que presentes una actualización.

  1. 1

    Hacé un fork del repositorio

    Creá una copia en tu cuenta desde cursos-uai/sap_tfi_2026 ↗.

  2. 2

    Subí el trabajo en la ubicación obligatoria

    Usá exactamente trabajo_final/Apellido_Nombre/, reemplazando el ejemplo por tus datos y sin espacios.

  3. 3

    Abrí un pull request hacia este repositorio

    En el título indicá apellido, nombre y versión. Para cada actualización, agregá cambios a tu fork y abrí un nuevo PR.

Vista previa

Informe de seguimiento

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 index bfcb301..6e7e3d1 100644 --- a/prototipo/checklist.js +++ b/prototipo/checklist.js @@ -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`

${h}

Indicá dónde puede encontrar el profesor la evidencia dentro del borrador.
`} 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(); diff --git a/trabajo_final/README.md b/trabajo_final/README.md new file mode 100644 index 0000000..48605e4 --- /dev/null +++ b/trabajo_final/README.md @@ -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.