ProyectoGrupal/VerifactuMidAPI/presentacion/slides.html

313 lines
14 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>VeriFactu — Presentación del proyecto</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Segoe UI', sans-serif; background: #0f1117; color: #e8eaf0; overflow: hidden; }
.slide {
display: none;
width: 100vw; height: 100vh;
padding: 60px 80px;
flex-direction: column;
justify-content: center;
}
.slide.active { display: flex; }
h1 { font-size: 2.6rem; font-weight: 700; color: #fff; margin-bottom: 12px; }
h2 { font-size: 1.9rem; font-weight: 600; color: #7eb8f7; margin-bottom: 28px; border-bottom: 2px solid #2a3050; padding-bottom: 12px; }
h3 { font-size: 1.2rem; color: #a0b4cc; margin-bottom: 10px; }
p { font-size: 1.15rem; line-height: 1.7; color: #c8d0dc; max-width: 860px; }
ul { list-style: none; padding: 0; }
ul li { font-size: 1.1rem; padding: 7px 0 7px 22px; color: #c8d0dc; position: relative; line-height: 1.5; }
ul li::before { content: "→"; position: absolute; left: 0; color: #7eb8f7; }
.subtitle { font-size: 1.3rem; color: #7eb8f7; margin-bottom: 40px; }
.tag { display: inline-block; background: #1e2d45; color: #7eb8f7; border: 1px solid #2e4a6e; border-radius: 6px; padding: 3px 12px; font-size: 0.85rem; margin: 3px; }
.tag.green { background: #1a2e1a; color: #6fcf97; border-color: #2e6e2e; }
.tag.amber { background: #2e2208; color: #f2c94c; border-color: #6e4e08; }
.tag.red { background: #2e1010; color: #eb5757; border-color: #6e1010; }
.cols { display: grid; gap: 40px; }
.cols-2 { grid-template-columns: 1fr 1fr; }
.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.card {
background: #181d2e;
border: 1px solid #2a3050;
border-radius: 12px;
padding: 24px 28px;
}
.card h3 { color: #7eb8f7; margin-bottom: 12px; font-size: 1rem; text-transform: uppercase; letter-spacing: 0.05em; }
.flow {
display: flex;
align-items: center;
gap: 0;
margin: 30px 0;
flex-wrap: wrap;
}
.flow-step {
background: #181d2e;
border: 1px solid #2a3050;
border-radius: 10px;
padding: 16px 22px;
font-size: 1rem;
color: #e8eaf0;
text-align: center;
min-width: 130px;
}
.flow-arrow {
font-size: 1.6rem;
color: #7eb8f7;
padding: 0 10px;
}
table { border-collapse: collapse; width: 100%; margin-top: 10px; }
th { text-align: left; padding: 10px 16px; background: #181d2e; color: #7eb8f7; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.05em; }
td { padding: 10px 16px; border-top: 1px solid #1e2535; font-size: 1rem; color: #c8d0dc; }
td code { background: #1e2535; padding: 2px 8px; border-radius: 4px; font-size: 0.9rem; color: #9ecbff; }
.status-ok { color: #6fcf97; font-weight: 600; }
.status-wip { color: #f2c94c; font-weight: 600; }
.status-no { color: #eb5757; font-weight: 600; }
.nav {
position: fixed;
bottom: 24px; right: 32px;
display: flex; gap: 12px; align-items: center;
}
.nav span { color: #4a5568; font-size: 0.9rem; }
#counter { color: #7eb8f7; font-size: 0.95rem; min-width: 60px; text-align: right; }
.note {
margin-top: 28px;
background: #1a1e2e;
border-left: 3px solid #f2c94c;
padding: 14px 20px;
border-radius: 0 8px 8px 0;
font-size: 0.95rem;
color: #b0b8c8;
max-width: 860px;
}
/* Slide 1 — portada */
#s1 { justify-content: center; align-items: flex-start; background: radial-gradient(ellipse at 70% 40%, #0d2140 0%, #0f1117 60%); }
#s1 h1 { font-size: 3.2rem; }
#s1 .meta { margin-top: 48px; font-size: 0.95rem; color: #4a5568; }
</style>
</head>
<body>
<!-- ═══════════════════════════════════════════════════ SLIDE 1 — PORTADA -->
<div class="slide active" id="s1">
<div class="tag">BYolivia · 2025</div>
<br>
<h1>Integración VeriFactu</h1>
<p class="subtitle">Facturación electrónica obligatoria con la AEAT</p>
<p>Presentación del sistema de envío de facturas al sistema VeriFactu de la Agencia Tributaria, integrado en la suite de gestión empresarial.</p>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 2 — CONTEXTO -->
<div class="slide" id="s2">
<h2>¿Por qué VeriFactu?</h2>
<div class="cols cols-2">
<div class="card">
<h3>Obligación legal</h3>
<ul>
<li>Reglamento de facturación electrónica (RD 1007/2023)</li>
<li>Obligatorio para empresas y autónomos en España</li>
<li>Cada factura debe enviarse a la AEAT en tiempo real</li>
<li>Las facturas se encadenan con hash para garantizar integridad</li>
</ul>
</div>
<div class="card">
<h3>El reto técnico</h3>
<ul>
<li>La AEAT usa SOAP/XML con firma digital</li>
<li>Requiere certificado digital de empresa (FNMT/ACCV)</li>
<li>TLS mútuo (mTLS) para autenticarse</li>
<li>El software ERP (Dolibarr) no lo soporta de forma nativa</li>
</ul>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 3 — ECOSISTEMA -->
<div class="slide" id="s3">
<h2>El ecosistema del proyecto</h2>
<!-- Flujo principal -->
<div class="flow" style="font-size:0.9rem; margin-bottom:8px; margin-top:16px">
<div class="flow-step">Dolibarr ERP<br><small style="color:#4a5568">datos de facturas</small></div>
<div class="flow-arrow"></div>
<div class="flow-step">Backend<br><small style="color:#4a5568">dolibarr-bff :5269</small></div>
<div class="flow-arrow"></div>
<div class="flow-step">Front<br><small style="color:#4a5568">doli-front :5173</small></div>
<div class="flow-arrow"></div>
<div class="flow-step">VerifactuMidAPI<br><small style="color:#4a5568">Go :6789</small></div>
<div class="flow-arrow" style="color:#f2c94c">- - →</div>
<div class="flow-step" style="border-color:#f2c94c; color:#f2c94c">AEAT<br><small style="color:#4a5568">VeriFactu</small></div>
</div>
<div style="margin-top:20px; display:flex; flex-direction:column; gap:10px; max-width:860px">
<div style="display:flex; align-items:flex-start; gap:10px">
<span class="tag green" style="white-space:nowrap">Implementado</span>
<span style="font-size:0.9rem; color:#c8d0dc">Dolibarr → Backend → Front → VerifactuMidAPI. El backend almacena el token que devuelve la API tras registrar el certificado.</span>
</div>
<div style="display:flex; align-items:flex-start; gap:10px">
<span class="tag amber" style="white-space:nowrap">Sin probar</span>
<span style="font-size:0.9rem; color:#c8d0dc">VerifactuMidAPI → AEAT. El envío real a VeriFactu no ha podido validarse por el tema del certificado. Es el único tramo pendiente de verificar.</span>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 4 — VERIFACTU API -->
<div class="slide" id="s4">
<h2>VerifactuMidAPI — Qué hace</h2>
<div class="cols cols-2">
<ul style="gap:4px">
<li>Recibe la factura en JSON (formato nativo o Dolibarr)</li>
<li>Calcula el hash SHA-256 encadenado (norma AEAT)</li>
<li>Genera el XML SOAP con todos los campos requeridos</li>
<li>Firma digitalmente con el certificado de empresa</li>
<li>Envía a la AEAT por SOAP con mTLS (TLS 1.2)</li>
<li>Si la AEAT no responde → guarda en fallback local</li>
<li>Devuelve el resultado al BFF</li>
</ul>
<div>
<div class="card">
<h3>Endpoints</h3>
<table>
<tr><td><code>GET /health</code></td><td>Estado</td></tr>
<tr><td><code>GET /auth/public-key</code></td><td>Clave RSA pública</td></tr>
<tr><td><code>POST /auth/register</code></td><td>Subir certificado P12</td></tr>
<tr><td><code>GET /formats</code></td><td>Formatos aceptados</td></tr>
<tr><td><code>POST /facturas</code></td><td>Alta de factura</td></tr>
<tr><td><code>POST /facturas/anular</code></td><td>Anulación</td></tr>
</table>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 5 — SEGURIDAD CERTS -->
<div class="slide" id="s5">
<h2>Seguridad — Certificados y tokens</h2>
<div class="cols cols-2">
<div class="card">
<h3>Registro del certificado</h3>
<ul>
<li>El front cifra la contraseña del .p12 con RSA (clave pública de la API)</li>
<li>La API descifra, valida el P12 y lo almacena</li>
<li>Soporta certificados FNMT y ACCV (multi-cert)</li>
<li>La API extrae automáticamente los datos del emisor del propio certificado</li>
<li>Devuelve un <strong>token</strong> de sesión para usar en los envíos</li>
</ul>
</div>
<div class="card">
<h3>Flujo de registro</h3>
<div class="flow" style="flex-direction:column; align-items:flex-start; gap:8px; margin:0">
<div class="flow-step" style="width:100%">Front: selecciona .p12 + contraseña</div>
<div class="flow-arrow" style="padding:0 0 0 20px"></div>
<div class="flow-step" style="width:100%">Front: cifra pass con RSA pública</div>
<div class="flow-arrow" style="padding:0 0 0 20px"></div>
<div class="flow-step" style="width:100%">API: valida, almacena, genera token</div>
<div class="flow-arrow" style="padding:0 0 0 20px"></div>
<div class="flow-step" style="width:100%">BFF: guarda el token para futuros envíos</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 6 — ESTADO -->
<div class="slide" id="s6">
<h2>Estado actual del proyecto</h2>
<div class="cols cols-2">
<div class="card">
<h3>VerifactuMidAPI (este repo — rama main)</h3>
<table>
<tr><td class="status-ok"></td><td>Alta de facturas con hash encadenado</td></tr>
<tr><td class="status-ok"></td><td>Anulación de facturas</td></tr>
<tr><td class="status-ok"></td><td>Registro y validación de certificados P12</td></tr>
<tr><td class="status-ok"></td><td>Soporte multi-cert (FNMT / ACCV)</td></tr>
<tr><td class="status-ok"></td><td>Fallback local si AEAT no responde</td></tr>
<tr><td class="status-ok"></td><td>TLS 1.2 + auto-fill datos emisor del cert</td></tr>
<tr><td class="status-no"></td><td>Consultas y subsanación (pendiente)</td></tr>
</table>
</div>
<div class="card">
<h3>Integración en el ecosistema (rama verifactu)</h3>
<table>
<tr><td class="status-ok"></td><td>Front: subida del certificado P12</td></tr>
<tr><td class="status-ok"></td><td>Front: cifrado RSA de contraseña</td></tr>
<tr><td class="status-ok"></td><td>Front: recepción y uso del token</td></tr>
<tr><td class="status-ok"></td><td>BFF: guardado del token en backend</td></tr>
<tr><td class="status-wip"></td><td>Pendiente de merge a main</td></tr>
</table>
<div class="note" style="margin-top:16px">La integración completa estaba bloqueada por el problema del certificado en la API, ya resuelto.</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════ SLIDE 8 — PRÓXIMOS PASOS -->
<div class="slide" id="s8">
<h2>Próximos pasos</h2>
<div class="cols cols-2">
<div>
<h3 style="color:#6fcf97; margin-bottom:12px">Inmediatos</h3>
<ul>
<li>Merge de rama <code>verifactu</code> a main en front y BFF</li>
<li>Pruebas end-to-end con el ecosistema completo</li>
<li>Validar con certificado real en entorno de pruebas AEAT</li>
</ul>
</div>
<div>
<h3 style="color:#f2c94c; margin-bottom:12px">Siguientes funcionalidades</h3>
<ul>
<li>Consultas a la AEAT (estado de facturas enviadas)</li>
<li>Subsanación de facturas incorrectas</li>
<li>Panel de estado VeriFactu en el front</li>
</ul>
</div>
</div>
<div class="note" style="margin-top:36px">El núcleo de la integración está completo y probado. El bloqueo original (gestión del certificado) está resuelto.</div>
</div>
<!-- NAV -->
<div class="nav">
<span id="counter">1 / 7</span>
</div>
<script>
const slides = document.querySelectorAll('.slide');
let cur = 0;
function show(n) {
slides[cur].classList.remove('active');
cur = Math.max(0, Math.min(n, slides.length - 1));
slides[cur].classList.add('active');
document.getElementById('counter').textContent = (cur + 1) + ' / ' + slides.length;
}
document.addEventListener('keydown', e => {
if (e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === ' ') show(cur + 1);
if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') show(cur - 1);
if (e.key === 'f' || e.key === 'F') document.documentElement.requestFullscreen?.();
if (e.key === 'Escape' && document.fullscreenElement) document.exitFullscreen?.();
});
document.addEventListener('click', e => {
if (e.target.closest('a, button, code')) return;
const mitad = window.innerWidth / 2;
if (e.clientX >= mitad) show(cur + 1);
else show(cur - 1);
});
</script>
</body>
</html>