Created
March 9, 2026 14:45
-
-
Save skozz/4f049fbe3c5b0e1069b485d5ddda33fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Flujo de Fichaje y Firma — Compliance España</title> | |
| <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --bg: #0a0b0f; | |
| --surface: #12131a; | |
| --surface-2: #1a1b25; | |
| --border: #2a2b3a; | |
| --text: #e8e9f0; | |
| --text-dim: #8889a0; | |
| --accent: #6366f1; | |
| --accent-glow: rgba(99, 102, 241, 0.15); | |
| --green: #22c55e; | |
| --green-glow: rgba(34, 197, 94, 0.12); | |
| --amber: #f59e0b; | |
| --amber-glow: rgba(245, 158, 11, 0.12); | |
| --red: #ef4444; | |
| --red-glow: rgba(239, 68, 68, 0.12); | |
| --cyan: #06b6d4; | |
| --cyan-glow: rgba(6, 182, 212, 0.12); | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| font-family: 'DM Sans', sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| } | |
| .noise { | |
| position: fixed; | |
| inset: 0; | |
| opacity: 0.03; | |
| background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); | |
| pointer-events: none; | |
| z-index: 0; | |
| } | |
| .container { | |
| position: relative; | |
| z-index: 1; | |
| max-width: 1100px; | |
| margin: 0 auto; | |
| padding: 40px 24px 60px; | |
| } | |
| header { | |
| text-align: center; | |
| margin-bottom: 48px; | |
| } | |
| .badge { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| background: var(--accent-glow); | |
| border: 1px solid rgba(99, 102, 241, 0.25); | |
| border-radius: 100px; | |
| padding: 6px 16px; | |
| font-size: 12px; | |
| font-weight: 600; | |
| color: var(--accent); | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-bottom: 16px; | |
| } | |
| .badge::before { | |
| content: ''; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| background: var(--accent); | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.4; } | |
| } | |
| h1 { | |
| font-size: clamp(28px, 4vw, 42px); | |
| font-weight: 700; | |
| line-height: 1.15; | |
| letter-spacing: -0.02em; | |
| margin-bottom: 12px; | |
| } | |
| h1 span { color: var(--accent); } | |
| .subtitle { | |
| color: var(--text-dim); | |
| font-size: 15px; | |
| line-height: 1.6; | |
| max-width: 600px; | |
| margin: 0 auto; | |
| } | |
| /* Tab Navigation */ | |
| .tabs { | |
| display: flex; | |
| gap: 4px; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| padding: 4px; | |
| margin-bottom: 36px; | |
| overflow-x: auto; | |
| } | |
| .tab { | |
| flex: 1; | |
| min-width: 120px; | |
| padding: 10px 16px; | |
| border: none; | |
| border-radius: 8px; | |
| background: transparent; | |
| color: var(--text-dim); | |
| font-family: inherit; | |
| font-size: 13px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| white-space: nowrap; | |
| } | |
| .tab:hover { color: var(--text); background: var(--surface-2); } | |
| .tab.active { color: var(--text); background: var(--accent); } | |
| /* Flow Section */ | |
| .flow-section { | |
| display: none; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| .flow-section.active { display: block; } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(8px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| /* Flow Steps */ | |
| .flow { | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0; | |
| } | |
| .flow::before { | |
| content: ''; | |
| position: absolute; | |
| left: 23px; | |
| top: 36px; | |
| bottom: 36px; | |
| width: 2px; | |
| background: linear-gradient(to bottom, var(--accent) 0%, var(--border) 100%); | |
| opacity: 0.4; | |
| } | |
| .step { | |
| position: relative; | |
| display: flex; | |
| gap: 20px; | |
| padding: 16px 0; | |
| } | |
| .step-marker { | |
| position: relative; | |
| z-index: 2; | |
| width: 48px; | |
| height: 48px; | |
| min-width: 48px; | |
| border-radius: 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 18px; | |
| font-weight: 700; | |
| border: 2px solid; | |
| } | |
| .step-marker.action { | |
| background: var(--accent-glow); | |
| border-color: rgba(99, 102, 241, 0.35); | |
| color: var(--accent); | |
| } | |
| .step-marker.check { | |
| background: var(--amber-glow); | |
| border-color: rgba(245, 158, 11, 0.35); | |
| color: var(--amber); | |
| } | |
| .step-marker.success { | |
| background: var(--green-glow); | |
| border-color: rgba(34, 197, 94, 0.35); | |
| color: var(--green); | |
| } | |
| .step-marker.data { | |
| background: var(--cyan-glow); | |
| border-color: rgba(6, 182, 212, 0.35); | |
| color: var(--cyan); | |
| } | |
| .step-marker.alert { | |
| background: var(--red-glow); | |
| border-color: rgba(239, 68, 68, 0.35); | |
| color: var(--red); | |
| } | |
| .step-content { | |
| flex: 1; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| padding: 20px 24px; | |
| transition: border-color 0.2s; | |
| } | |
| .step-content:hover { | |
| border-color: rgba(99, 102, 241, 0.3); | |
| } | |
| .step-title { | |
| font-size: 15px; | |
| font-weight: 700; | |
| margin-bottom: 6px; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .step-label { | |
| font-size: 10px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| padding: 2px 8px; | |
| border-radius: 4px; | |
| background: var(--surface-2); | |
| color: var(--text-dim); | |
| } | |
| .step-desc { | |
| font-size: 13.5px; | |
| color: var(--text-dim); | |
| line-height: 1.65; | |
| } | |
| .step-desc strong { color: var(--text); font-weight: 600; } | |
| .data-fields { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| margin-top: 10px; | |
| } | |
| .field { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 4px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: 11px; | |
| padding: 4px 10px; | |
| border-radius: 6px; | |
| background: var(--surface-2); | |
| border: 1px solid var(--border); | |
| color: var(--text-dim); | |
| } | |
| .field .dot { | |
| width: 5px; | |
| height: 5px; | |
| border-radius: 50%; | |
| } | |
| .field .dot.required { background: var(--red); } | |
| .field .dot.recommended { background: var(--amber); } | |
| .field .dot.optional { background: var(--text-dim); } | |
| /* Legal References */ | |
| .legal-ref { | |
| margin-top: 40px; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 16px; | |
| padding: 28px; | |
| } | |
| .legal-ref h3 { | |
| font-size: 16px; | |
| font-weight: 700; | |
| margin-bottom: 16px; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .legal-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 12px; | |
| } | |
| .legal-card { | |
| background: var(--surface-2); | |
| border: 1px solid var(--border); | |
| border-radius: 10px; | |
| padding: 16px; | |
| } | |
| .legal-card .tag { | |
| font-size: 11px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| color: var(--accent); | |
| margin-bottom: 6px; | |
| } | |
| .legal-card .title { | |
| font-size: 13px; | |
| font-weight: 600; | |
| margin-bottom: 4px; | |
| } | |
| .legal-card .desc { | |
| font-size: 12px; | |
| color: var(--text-dim); | |
| line-height: 1.55; | |
| } | |
| /* Sanctions bar */ | |
| .sanctions { | |
| margin-top: 24px; | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 12px; | |
| } | |
| .sanction { | |
| text-align: center; | |
| padding: 16px; | |
| border-radius: 10px; | |
| border: 1px solid var(--border); | |
| } | |
| .sanction.leve { background: var(--amber-glow); border-color: rgba(245,158,11,0.25); } | |
| .sanction.grave { background: rgba(249,115,22,0.1); border-color: rgba(249,115,22,0.25); } | |
| .sanction.muy-grave { background: var(--red-glow); border-color: rgba(239,68,68,0.25); } | |
| .sanction .level { | |
| font-size: 11px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-bottom: 4px; | |
| } | |
| .sanction.leve .level { color: var(--amber); } | |
| .sanction.grave .level { color: #f97316; } | |
| .sanction.muy-grave .level { color: var(--red); } | |
| .sanction .amount { | |
| font-size: 18px; | |
| font-weight: 700; | |
| } | |
| .sanction .per { | |
| font-size: 11px; | |
| color: var(--text-dim); | |
| margin-top: 2px; | |
| } | |
| /* Legend */ | |
| .legend { | |
| display: flex; | |
| gap: 16px; | |
| flex-wrap: wrap; | |
| margin-bottom: 20px; | |
| padding: 12px 16px; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 10px; | |
| font-size: 12px; | |
| color: var(--text-dim); | |
| } | |
| .legend-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| .legend-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| } | |
| /* Arrow connector */ | |
| .arrow-down { | |
| display: flex; | |
| justify-content: center; | |
| padding: 4px 0; | |
| color: var(--text-dim); | |
| opacity: 0.4; | |
| font-size: 12px; | |
| } | |
| /* Qamarero Status Panel */ | |
| .qamarero-status { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 16px; | |
| padding: 24px; | |
| margin-bottom: 8px; | |
| } | |
| .qs-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| flex-wrap: wrap; | |
| gap: 12px; | |
| margin-bottom: 20px; | |
| } | |
| .qs-title { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: 16px; | |
| font-weight: 700; | |
| } | |
| .qs-logo { | |
| width: 32px; | |
| height: 32px; | |
| border-radius: 8px; | |
| background: linear-gradient(135deg, var(--accent), #a855f7); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 16px; | |
| font-weight: 800; | |
| color: #fff; | |
| } | |
| .qs-summary { | |
| font-size: 13px; | |
| color: var(--text-dim); | |
| } | |
| .qs-pending { | |
| color: var(--amber); | |
| font-weight: 600; | |
| } | |
| .qs-grid { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .qs-item { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 12px; | |
| padding: 14px 16px; | |
| border-radius: 10px; | |
| border: 1px solid var(--border); | |
| background: var(--surface-2); | |
| } | |
| .qs-item.covered { | |
| border-color: rgba(34, 197, 94, 0.2); | |
| } | |
| .qs-item.partial { | |
| border-color: rgba(245, 158, 11, 0.25); | |
| background: rgba(245, 158, 11, 0.04); | |
| } | |
| .qs-item.pending { | |
| border-color: rgba(245, 158, 11, 0.35); | |
| background: rgba(245, 158, 11, 0.06); | |
| } | |
| .qs-item.blocker { | |
| border-color: rgba(239, 68, 68, 0.35); | |
| background: rgba(239, 68, 68, 0.06); | |
| } | |
| .qs-icon { | |
| font-size: 16px; | |
| min-width: 24px; | |
| height: 24px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .qs-item.covered .qs-icon { color: var(--green); } | |
| .qs-item.partial .qs-icon { color: var(--amber); } | |
| .qs-item.pending .qs-icon { color: var(--amber); } | |
| .qs-item.blocker .qs-icon { color: var(--red); } | |
| .qs-body { flex: 1; } | |
| .qs-item-title { | |
| font-size: 13.5px; | |
| font-weight: 600; | |
| margin-bottom: 2px; | |
| } | |
| .qs-item-desc { | |
| font-size: 12.5px; | |
| color: var(--text-dim); | |
| line-height: 1.5; | |
| } | |
| .qs-badge { | |
| font-size: 11px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| padding: 4px 10px; | |
| border-radius: 6px; | |
| white-space: nowrap; | |
| flex-shrink: 0; | |
| } | |
| .qs-badge.done { | |
| background: rgba(34, 197, 94, 0.12); | |
| color: var(--green); | |
| } | |
| .qs-badge.partial { | |
| background: rgba(245, 158, 11, 0.15); | |
| color: var(--amber); | |
| } | |
| .qs-badge.todo { | |
| background: rgba(245, 158, 11, 0.15); | |
| color: var(--amber); | |
| } | |
| .qs-badge.blocker { | |
| background: rgba(239, 68, 68, 0.15); | |
| color: var(--red); | |
| } | |
| /* Responsive */ | |
| @media (max-width: 640px) { | |
| .flow::before { left: 19px; } | |
| .step-marker { width: 40px; height: 40px; min-width: 40px; font-size: 15px; } | |
| .step-content { padding: 16px; } | |
| .sanctions { grid-template-columns: 1fr; } | |
| .tabs { flex-wrap: nowrap; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="noise"></div> | |
| <div class="container"> | |
| <header> | |
| <div class="badge">Normativa Laboral España 2026</div> | |
| <h1>Flujo de <span>Fichaje y Firma</span></h1> | |
| <p class="subtitle">Diseño de flujo compliant con el Art. 34.9 del Estatuto de los Trabajadores, RDL 8/2019 y el nuevo decreto de registro horario digital obligatorio.</p> | |
| </header> | |
| <div class="tabs"> | |
| <button class="tab active" onclick="showTab('fichaje')">Fichaje Diario</button> | |
| <button class="tab" onclick="showTab('firma')">Firma Semanal</button> | |
| <button class="tab" onclick="showTab('regulacion')">Regulación</button> | |
| <button class="tab" onclick="showTab('sanciones')">Compliance Qamarero</button> | |
| <button class="tab" onclick="showTab('roadmap')">Roadmap</button> | |
| </div> | |
| <!-- TAB 1: FICHAJE DIARIO --> | |
| <div class="flow-section active" id="tab-fichaje"> | |
| <div class="legend"> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--accent)"></div> Acción del trabajador</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--amber)"></div> Validación del sistema</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--green)"></div> Registro guardado</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--red)"></div> Alerta / Error</div> | |
| </div> | |
| <!-- Qamarero status summary for this flow --> | |
| <div class="qamarero-status" style="margin-bottom: 24px;"> | |
| <div class="qs-header"> | |
| <div class="qs-title"> | |
| <span class="qs-logo">Q</span> | |
| Estado del flujo de fichaje en Qamarero | |
| </div> | |
| <div class="qs-summary">3 cubiertos · 1 parcial · 2 prioritarios · 1 pendiente</div> | |
| </div> | |
| <div class="qs-grid"> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Fichaje entrada / salida</div> | |
| <div class="qs-item-desc">Implementado. Fichaje digital desde la app con timestamp.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Validación en tiempo real</div> | |
| <div class="qs-item-desc">Implementado. Se valida contra turno planificado.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Registro de pausas</div> | |
| <div class="qs-item-desc">Implementado vía diferencia entre fichajes de entrada y salida.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item partial"> | |
| <div class="qs-icon">◐</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Detección de horas extra</div> | |
| <div class="qs-item-desc">Solo visual: contador en tiempo real en UI cuando se superan horas planificadas. No se persiste, no hay gestión de compensación ni aprobación.</div> | |
| </div> | |
| <div class="qs-badge partial">Parcial</div> | |
| </div> | |
| <div class="qs-item blocker"> | |
| <div class="qs-icon">✕</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Inmutabilidad y traza de auditoría</div> | |
| <div class="qs-item-desc">No implementado. Turnos y fichajes son editables por el manager sin dejar registro. Esto es un blocker de compliance — prioritario.</div> | |
| </div> | |
| <div class="qs-badge blocker">Prioritario</div> | |
| </div> | |
| <div class="qs-item blocker"> | |
| <div class="qs-icon">✕</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Soft-delete: anulación de fichajes erróneos</div> | |
| <div class="qs-item-desc">No implementado. Los fichajes se pueden eliminar (hard-delete). Se necesita soft-delete con estado anulado, motivo y traza. Vinculado al audit log.</div> | |
| </div> | |
| <div class="qs-badge blocker">Prioritario</div> | |
| </div> | |
| <div class="qs-item partial"> | |
| <div class="qs-icon">◐</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Gestión de incidencias</div> | |
| <div class="qs-item-desc">Hay feedback visual en la UI, pero las incidencias no se persisten ni se almacenan como registro formal.</div> | |
| </div> | |
| <div class="qs-badge partial">Parcial</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flow"> | |
| <div class="step"> | |
| <div class="step-marker action">1</div> | |
| <div class="step-content"> | |
| <div class="step-title">Fichaje de ENTRADA <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">El camarero abre la app y pulsa <strong>"Fichar entrada"</strong>. El sistema captura automáticamente: <strong>timestamp exacto (hora:minuto)</strong>, ID del trabajador y centro de trabajo. El fichaje debe ser <strong>personal e intransferible</strong> — cada trabajador con sus propias credenciales (PIN, QR, tarjeta NFC). <strong>Prohibido:</strong> biometría (huella/rostro) salvo que no exista alternativa, según la AEPD.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check">⟐</div> | |
| <div class="step-content"> | |
| <div class="step-title">Validación en tiempo real <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">El sistema valida: ¿El trabajador tiene turno asignado hoy? ¿Está dentro del margen horario razonable? Si hay <strong>desviación significativa</strong> respecto al turno planificado, se genera una <strong>incidencia automática</strong> (retraso / fichaje fuera de horario). El registro queda <strong>inmutable</strong> desde el momento de la captura.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker action">2</div> | |
| <div class="step-content"> | |
| <div class="step-title">Registro de PAUSAS <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">Aunque no es estrictamente obligatorio, el decreto reforzado de 2026 exige <strong>distinguir horas efectivas de trabajo, pausas, y horas extra</strong>. En hostelería, registrar el descanso intrajornada es clave para calcular correctamente las horas efectivas y evitar disputas. En Qamarero se calcula actualmente por <strong>diferencia entre fichajes de entrada y salida</strong>.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker action">3</div> | |
| <div class="step-content"> | |
| <div class="step-title">Fichaje de SALIDA <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">Al terminar el turno, el camarero pulsa <strong>"Fichar salida"</strong>. El sistema registra el timestamp exacto. Se calcula automáticamente: <strong>horas totales</strong>, <strong>horas efectivas</strong> (descontando pausas), y si hay <strong>horas extra</strong> respecto a la jornada planificada.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check">⟐</div> | |
| <div class="step-content"> | |
| <div class="step-title">Detección de horas extra <span class="step-label" style="background:rgba(245,158,11,0.15); color:var(--amber);">Parcial</span></div> | |
| <div class="step-desc">Si las horas efectivas <strong>superan la jornada contratada</strong>, el sistema marca automáticamente las horas excedentes como <strong>horas extraordinarias</strong>. Se debe documentar cómo se compensan: <strong>retribución económica o descanso compensatorio</strong>. El manager debe aprobar/justificar las horas extra.<br><br><strong style="color:var(--amber);">◐ En Qamarero:</strong> Existe un <strong>contador visual en tiempo real</strong> en la UI que muestra cuando se superan las horas planificadas. Sin embargo: el dato <strong>no se persiste</strong> ni se almacena como registro formal de horas extra, <strong>no hay flujo de compensación</strong> (dinero vs descanso), <strong>no hay aprobación</strong> del manager, y <strong>no se refleja en nómina</strong>. Es puramente informativo. Para compliance se necesita: persistir las horas extra detectadas, registrar tipo de compensación, y flujo de aprobación formal.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker alert">✕</div> | |
| <div class="step-content"> | |
| <div class="step-title">Registro diario completado <span class="step-label" style="background:rgba(239,68,68,0.15); color:var(--red);">Prioritario</span></div> | |
| <div class="step-desc">Se genera el <strong>registro diario completo</strong>: entrada, pausas, salida, horas efectivas, horas extra (si aplica). El dato queda <strong>sellado digitalmente</strong> — cualquier corrección posterior deja <strong>traza de auditoría</strong> (quién, qué, cuándo). El trabajador puede consultar su fichaje en cualquier momento desde la app.<br><br><strong style="color:var(--red);">✕ En Qamarero:</strong> Actualmente tanto los turnos planificados como los fichajes son <strong>mutables por el manager sin dejar registro</strong> de la edición. Esto es un <strong>blocker de compliance</strong> — sin traza de auditoría, ante Inspección el registro puede considerarse manipulable y perder toda validez. Acción: implementar audit log inmutable (quién editó, valor anterior → nuevo, timestamp, motivo).</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker alert">✕</div> | |
| <div class="step-content"> | |
| <div class="step-title">Anulación de fichajes erróneos (soft-delete) <span class="step-label" style="background:rgba(239,68,68,0.15); color:var(--red);">Prioritario</span></div> | |
| <div class="step-desc"> | |
| <strong>Caso típico:</strong> un camarero ficha 3 veces en un día por error de UI (entrada, salida, entrada accidental). Uno de esos fichajes sobra y hay que corregirlo.<br><br> | |
| <strong>Principio legal:</strong> un fichaje nunca se borra (hard-delete). Se marca como <strong>"anulado"</strong> con motivo y traza. Ante Inspección, un registro que desaparece sin rastro es peor que no tener registro — un fichaje anulado con justificación cuenta una historia coherente y transparente.<br><br> | |
| <strong>Flujo requerido:</strong><br> | |
| — El manager (o empleado + aprobación manager) marca el fichaje erróneo como <strong>anulado</strong>.<br> | |
| — Se registra: motivo (<code>error_fichaje_empleado</code>, <code>duplicado</code>, <code>correccion_manager</code>, etc.), quién lo anuló, timestamp de la anulación.<br> | |
| — El fichaje original <strong>permanece en BBDD</strong> con status <code>anulado</code> — nunca <code>DELETE FROM</code>.<br> | |
| — En la <strong>UI normal</strong>: los fichajes anulados aparecen tachados o colapsados, sin ensuciar la vista del día.<br> | |
| — En la <strong>vista de auditoría / exportación</strong> para Inspección: se muestra todo — activos y anulados con su traza completa.<br> | |
| — El empleado recibe <strong>notificación</strong> de que su fichaje fue anulado para poder reclamar si no está de acuerdo.<br><br> | |
| <strong>Modelo de datos sugerido:</strong> campo <code>status</code> en cada fichaje con valores <code>activo</code> | <code>modificado</code> | <code>anulado</code>, más campo <code>motivo_anulacion</code> y referencia al audit log. | |
| <br><br> | |
| <strong style="color:var(--red);">✕ En Qamarero:</strong> Actualmente los fichajes se eliminan con <strong>hard-delete</strong>. Se necesita migrar a soft-delete con estados + motivos + traza. Este cambio está directamente vinculado al audit log del punto anterior — ambos deberían implementarse juntos. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check">◐</div> | |
| <div class="step-content"> | |
| <div class="step-title">Gestión de olvidos / incidencias <span class="step-label" style="background:rgba(245,158,11,0.15); color:var(--amber);">Parcial</span></div> | |
| <div class="step-desc">Si el trabajador olvida fichar, el manager puede <strong>crear un registro manual</strong>, pero: debe quedar <strong>trazado como edición manual</strong>, requiere <strong>justificación escrita</strong>, y el trabajador debe <strong>confirmarlo</strong>. El sistema nunca puede permitir editar un fichaje sin dejar rastro — eso invalida todo el registro ante Inspección.<br><br><strong style="color:var(--amber);">◐ En Qamarero:</strong> Se da <strong>feedback visual en la UI</strong> cuando hay olvidos o desviaciones, pero las incidencias <strong>no se almacenan</strong> como registro formal. Para compliance, cada incidencia debería persistirse con: tipo, timestamp, estado de resolución y quién la resolvió.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- TAB 2: FIRMA SEMANAL/MENSUAL --> | |
| <div class="flow-section" id="tab-firma"> | |
| <div class="legend"> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--cyan)"></div> Generación automática</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--accent)"></div> Acción del trabajador</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--green)"></div> Documento firmado</div> | |
| </div> | |
| <div class="flow"> | |
| <div class="step"> | |
| <div class="step-marker data">①</div> | |
| <div class="step-content"> | |
| <div class="step-title">Generación del resumen periódico <span class="step-label">Automático</span></div> | |
| <div class="step-desc">Al cierre de cada <strong>semana o mes</strong> (tú decides la cadencia; semanal es más seguro en hostelería), el sistema genera un <strong>resumen de fichajes</strong> del trabajador: días trabajados, hora entrada/salida de cada día, pausas, horas totales, horas extra y su compensación.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker action">②</div> | |
| <div class="step-content"> | |
| <div class="step-title">Revisión por el trabajador <span class="step-label">Trabajador</span></div> | |
| <div class="step-desc">El trabajador recibe una <strong>notificación push</strong> para revisar su resumen. Tiene un <strong>plazo definido</strong> (ej. 48-72h) para revisarlo. Puede ver el detalle de cada día y <strong>reclamar discrepancias</strong> antes de firmar. Si hay reclamación, se abre un <strong>flujo de incidencia</strong> que el manager debe resolver.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker action">③</div> | |
| <div class="step-content"> | |
| <div class="step-title">Firma digital del resumen <span class="step-label">Trabajador</span></div> | |
| <div class="step-desc">El trabajador pulsa <strong>"Firmar y conformar"</strong>. La firma debe ser: <strong>personal</strong> (con las credenciales del trabajador, no la del manager), <strong>trazable</strong> (timestamp + IP/dispositivo), <strong>vinculante</strong> (el resumen firmado tiene valor probatorio ante tribunales — un TSJ de Madrid ya ha dictaminado que el registro firmado prevalece sobre WhatsApps). No es necesario firma manuscrita digital; basta un <strong>consentimiento explícito digital</strong> tipo "Confirmo que los datos son correctos".</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check">⟐</div> | |
| <div class="step-content"> | |
| <div class="step-title">Firma del responsable <span class="step-label">Manager</span></div> | |
| <div class="step-desc">Opcionalmente (pero muy recomendable), el <strong>encargado o gerente</strong> también firma/conforma el resumen. Esto genera un <strong>documento bilateral</strong> que protege tanto al trabajador como a la empresa. Si el manager detecta incidencias no reportadas, puede añadir <strong>observaciones</strong> antes de firmar.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker success">✓</div> | |
| <div class="step-content"> | |
| <div class="step-title">Resumen sellado y archivado <span class="step-label">4 años</span></div> | |
| <div class="step-desc">El resumen firmado se archiva como <strong>documento inmutable</strong>. Debe estar disponible para: el <strong>trabajador</strong> (acceso directo desde app), los <strong>representantes legales</strong> de los trabajadores, y la <strong>Inspección de Trabajo</strong> (acceso remoto en tiempo real, sin necesidad de que la empresa lo envíe). Conservación mínima: <strong>4 años</strong>.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker alert">!</div> | |
| <div class="step-content"> | |
| <div class="step-title">¿Qué pasa si no firma? <span class="step-label">Importante</span></div> | |
| <div class="step-desc">Si el trabajador <strong>no firma en plazo</strong>, el sistema debe registrar que se le notificó y no actuó. El registro sigue siendo válido (la firma del trabajador no es requisito legal para la validez del registro, pero sí añade mucho valor probatorio). Si <strong>se niega reiteradamente</strong> a fichar o firmar, la empresa puede aplicar medidas disciplinarias, ya que es una obligación laboral del empleado.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- TAB 3: REGULACIÓN --> | |
| <div class="flow-section" id="tab-regulacion"> | |
| <div class="legend"> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--red)"></div> Obligatorio por ley</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--amber)"></div> Muy recomendado</div> | |
| <div class="legend-item"><div class="legend-dot" style="background:var(--text-dim)"></div> Opcional</div> | |
| </div> | |
| <div class="flow"> | |
| <div class="step"> | |
| <div class="step-marker data">📋</div> | |
| <div class="step-content"> | |
| <div class="step-title">Cada registro diario debe contener</div> | |
| <div class="data-fields"> | |
| <span class="field"><span class="dot required"></span> ID trabajador</span> | |
| <span class="field"><span class="dot required"></span> Fecha</span> | |
| <span class="field"><span class="dot required"></span> Hora inicio jornada</span> | |
| <span class="field"><span class="dot required"></span> Hora fin jornada</span> | |
| <span class="field"><span class="dot recommended"></span> Inicio pausa</span> | |
| <span class="field"><span class="dot recommended"></span> Fin pausa</span> | |
| <span class="field"><span class="dot recommended"></span> Horas efectivas</span> | |
| <span class="field"><span class="dot recommended"></span> Horas extra (si aplica)</span> | |
| <span class="field"><span class="dot recommended"></span> Compensación h. extra</span> | |
| <span class="field"><span class="dot recommended"></span> Centro de trabajo</span> | |
| <span class="field"><span class="dot optional"></span> Tipo de turno</span> | |
| <span class="field"><span class="dot optional"></span> Observaciones</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data">🔐</div> | |
| <div class="step-content"> | |
| <div class="step-title">Requisitos técnicos del sistema (Decreto 2026)</div> | |
| <div class="step-desc"> | |
| <strong>Digital obligatorio</strong> — nada de papel ni Excel.<br> | |
| <strong>Tiempo real</strong> — el fichaje se registra en el momento, no a posteriori.<br> | |
| <strong>Inmutable</strong> — los datos no se pueden modificar sin dejar traza de auditoría.<br> | |
| <strong>Accesible</strong> — el trabajador consulta sus fichajes en cualquier momento.<br> | |
| <strong>Interoperable</strong> — Inspección de Trabajo puede acceder en remoto sin intervención de la empresa.<br> | |
| <strong>Credenciales individuales</strong> — usuario+clave, PIN, QR o NFC (no biometría).<br> | |
| <strong>Cifrado</strong> — en tránsito y en reposo, con control de accesos y backups. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data">🏪</div> | |
| <div class="step-content"> | |
| <div class="step-title">Particularidades hostelería</div> | |
| <div class="step-desc"> | |
| <strong>Turnos partidos</strong> — muy comunes en restaurantes. Cada turno necesita su propio fichaje entrada/salida (ej.: 12:00-16:00 + 20:00-00:00 = 2 fichajes de entrada y 2 de salida).<br> | |
| <strong>Tiempo parcial</strong> — obligatorio entregar resumen mensual de horas junto con la nómina (Art. 12.4.c ET).<br> | |
| <strong>Extras y eventos</strong> — las horas trabajadas en eventos especiales deben registrarse igualmente.<br> | |
| <strong>Jornada flexible</strong> — aunque haya flexibilidad, el horario real debe quedar registrado con precisión. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data">💾</div> | |
| <div class="step-content"> | |
| <div class="step-title">Conservación y almacenamiento: 4 años mínimo</div> | |
| <div class="step-desc">Los registros deben conservarse durante <strong>4 años</strong> desde la fecha del fichaje. Deben estar disponibles de forma inmediata para Inspección, trabajadores y sus representantes legales. La integridad de los datos debe poder <strong>demostrarse</strong> (hashing, sellos de tiempo, etc.).</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data">👁️</div> | |
| <div class="step-content"> | |
| <div class="step-title">Acceso en tiempo real — 3 niveles</div> | |
| <div class="step-desc"> | |
| <strong>Trabajador:</strong> accede a sus propios fichajes desde la app en cualquier momento. Puede descargar informes.<br> | |
| <strong>Representantes legales (RLT):</strong> acceso a los registros de toda la plantilla, respetando el RGPD.<br> | |
| <strong>Inspección de Trabajo:</strong> acceso remoto directo sin que la empresa tenga que enviar nada. Este es uno de los cambios más fuertes del decreto 2026. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check">🛡️</div> | |
| <div class="step-content"> | |
| <div class="step-title">Cumplimiento RGPD</div> | |
| <div class="step-desc"> | |
| El registro horario es <strong>tratamiento de datos personales</strong>. Necesitas: <strong>informar al trabajador</strong> sobre el tratamiento (qué datos, para qué, quién accede), <strong>limitar accesos</strong> según rol, <strong>proteger contra accesos indebidos</strong>, y <strong>no usar el registro para monitorizar comportamiento</strong> más allá del control horario. La geolocalización NO es obligatoria y solo se justifica si el puesto lo requiere. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- TAB 5: SANCIONES --> | |
| <div class="flow-section" id="tab-sanciones"> | |
| <div class="sanctions"> | |
| <div class="sanction leve"> | |
| <div class="level">Leve</div> | |
| <div class="amount">751 € — 1.500 €</div> | |
| <div class="per">por trabajador afectado</div> | |
| </div> | |
| <div class="sanction grave"> | |
| <div class="level">Grave</div> | |
| <div class="amount">1.501 € — 6.250 €</div> | |
| <div class="per">por trabajador afectado</div> | |
| </div> | |
| <div class="sanction muy-grave"> | |
| <div class="level">Muy Grave</div> | |
| <div class="amount">6.251 € — 10.000 €</div> | |
| <div class="per">por trabajador afectado</div> | |
| </div> | |
| </div> | |
| <!-- QAMARERO STATUS PANEL --> | |
| <div class="qamarero-status"> | |
| <div class="qs-header"> | |
| <div class="qs-title"> | |
| <span class="qs-logo">Q</span> | |
| Estado de compliance en Qamarero | |
| </div> | |
| <div class="qs-summary">3 de 4 riesgos cubiertos — <span class="qs-pending">1 pendiente</span></div> | |
| </div> | |
| <div class="qs-grid"> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Registro horario digital</div> | |
| <div class="qs-item-desc">Implementado. Fichaje de entrada/salida desde la app.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Conservación 4 años</div> | |
| <div class="qs-item-desc">Implementado. Los registros se persisten y conservan.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item covered"> | |
| <div class="qs-icon">✓</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Sin papel ni Excel</div> | |
| <div class="qs-item-desc">Implementado. Todo el registro es 100% digital.</div> | |
| </div> | |
| <div class="qs-badge done">Cubierto</div> | |
| </div> | |
| <div class="qs-item pending"> | |
| <div class="qs-icon">⚡</div> | |
| <div class="qs-body"> | |
| <div class="qs-item-title">Traza de auditoría anti-manipulación</div> | |
| <div class="qs-item-desc">Pendiente. Necesitamos audit log inmutable: quién editó, qué cambió, cuándo. Sin esto, cualquier corrección manual invalida el registro ante Inspección.</div> | |
| </div> | |
| <div class="qs-badge todo">Pendiente</div> | |
| </div> | |
| </div> | |
| </div> | |
| <h3 style="font-size:15px; font-weight:700; margin: 28px 0 16px; color: var(--text-dim);">Detalle de riesgos por incumplimiento</h3> | |
| <div class="flow"> | |
| <div class="step"> | |
| <div class="step-marker success">✓</div> | |
| <div class="step-content"> | |
| <div class="step-title">No tener registro horario <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">Se considera <strong>infracción grave</strong> según el Art. 7.5 de la LISOS. Además, si no hay registros válidos, se presume que el trabajador a tiempo parcial ha trabajado a <strong>jornada completa</strong>, lo que puede suponer pagos retroactivos de salarios y cotizaciones a la Seguridad Social.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker alert">⚠</div> | |
| <div class="step-content"> | |
| <div class="step-title">Registro manipulado o falsificado <span class="step-label" style="background:rgba(239,68,68,0.15); color:var(--red);">Pendiente</span></div> | |
| <div class="step-desc">Obligar a los empleados a <strong>falsear el registro</strong> es motivo de condena judicial (hay sentencias). Un sistema que permita editar fichajes sin traza de auditoría puede interpretarse como <strong>facilitación de la manipulación</strong>. Riesgo muy alto ante Inspección.<br><br><strong style="color:var(--amber);">⚡ Acción requerida en Qamarero:</strong> Implementar audit log inmutable. Cada edición de un fichaje debe registrar: usuario que edita, valor anterior, valor nuevo, timestamp y motivo. Sin posibilidad de borrar la traza.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker success">✓</div> | |
| <div class="step-content"> | |
| <div class="step-title">No conservar los registros 4 años <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">Aunque los registros estén correctos, si no se conservan <strong>4 años</strong> o no están disponibles de forma inmediata para Inspección, también es sancionable. La conservación es parte obligatoria de la normativa, no un extra.</div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker success">✓</div> | |
| <div class="step-content"> | |
| <div class="step-title">Usar papel o Excel (desde 2026) <span class="step-label" style="background:rgba(34,197,94,0.15); color:var(--green);">Cubierto</span></div> | |
| <div class="step-desc">Con la entrada en vigor del nuevo decreto, los métodos manuales quedan <strong>prohibidos</strong> como sistema principal. Solo serían válidos temporalmente en caso de <strong>incidencia técnica justificada</strong>. Qamarero ya es 100% digital — este requisito está cubierto.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- TAB 6: ROADMAP --> | |
| <div class="flow-section" id="tab-roadmap"> | |
| <div class="flow"> | |
| <div class="step"> | |
| <div class="step-marker alert" style="font-size:14px; font-weight:800;">P0</div> | |
| <div class="step-content" style="border-color: rgba(239,68,68,0.3);"> | |
| <div class="step-title">Audit log inmutable + soft-delete <span class="step-label" style="background:rgba(239,68,68,0.15); color:var(--red);">Blocker</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P0:</strong> Sin esto, todo el registro de fichaje puede considerarse manipulable ante Inspección y pierde validez legal. Es el único punto que puede invalidar lo que ya tenemos.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Tabla de audit log: fichaje_id, acción (creación/modificación/anulación), valor anterior, valor nuevo, usuario, timestamp, motivo.<br> | |
| — Migrar de hard-delete a soft-delete en fichajes y turnos: campo <code>status</code> (<code>activo</code> | <code>modificado</code> | <code>anulado</code>) + <code>motivo_anulacion</code>.<br> | |
| — Cualquier edición de manager deja traza inmutable. Nunca <code>DELETE FROM</code>.<br> | |
| — UI: fichajes anulados visibles como tachados en vista normal, completos en vista auditoría.<br> | |
| — Notificación al empleado cuando su fichaje es modificado o anulado.<br><br> | |
| <strong>Nota:</strong> Audit log y soft-delete deberían implementarse juntos — son la misma pieza de infraestructura. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker alert" style="font-size:14px; font-weight:800;">P1</div> | |
| <div class="step-content" style="border-color: rgba(245,158,11,0.3);"> | |
| <div class="step-title">Persistencia de horas extra <span class="step-label" style="background:rgba(245,158,11,0.15); color:var(--amber);">Compliance gap</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P1:</strong> El contador visual existe pero no se persiste. Sin registro formal de horas extra, no se puede demostrar compliance en compensación ni ante Inspección ni ante el trabajador.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Persistir las horas extra detectadas como registro vinculado al fichaje diario.<br> | |
| — Campo de tipo de compensación: <code>retribucion_economica</code> | <code>descanso_compensatorio</code>.<br> | |
| — Flujo de aprobación: el manager confirma/justifica las horas extra del día.<br> | |
| — Las horas extra aprobadas deben reflejarse en el resumen semanal/mensual para firma. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker check" style="font-size:14px; font-weight:800;">P2</div> | |
| <div class="step-content" style="border-color: rgba(245,158,11,0.3);"> | |
| <div class="step-title">Persistencia de incidencias <span class="step-label" style="background:rgba(245,158,11,0.15); color:var(--amber);">Compliance gap</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P2:</strong> Hay feedback visual pero sin registro formal. Si un trabajador reclama por un olvido de fichaje, no hay evidencia de que la incidencia existió ni de cómo se resolvió.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Modelo de incidencia: tipo (olvido fichaje, retraso, fichaje fuera de horario, fichaje erróneo), timestamp, estado (<code>abierta</code> | <code>resuelta</code> | <code>rechazada</code>), quién la resolvió y cómo.<br> | |
| — Vincular incidencias al fichaje o día afectado.<br> | |
| — Historial de incidencias accesible para el empleado. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker action" style="font-size:14px; font-weight:800;">P3</div> | |
| <div class="step-content"> | |
| <div class="step-title">Firma semanal/mensual del trabajador <span class="step-label">Feature nueva</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P3:</strong> No es obligatorio por ley, pero el valor probatorio del registro firmado es muy superior al no firmado (jurisprudencia TSJ Madrid). Reduce drásticamente el riesgo en disputas laborales.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Generación automática de resumen periódico (semanal o mensual).<br> | |
| — Notificación push al trabajador para revisión + firma digital.<br> | |
| — Consentimiento explícito tipo "Confirmo que los datos son correctos" con timestamp + dispositivo.<br> | |
| — Opcionalmente, co-firma del manager.<br> | |
| — Resumen firmado inmutable y archivado 4 años. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data" style="font-size:14px; font-weight:800;">P4</div> | |
| <div class="step-content"> | |
| <div class="step-title">Acceso remoto para Inspección de Trabajo <span class="step-label">Decreto 2026</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P4:</strong> Es un requisito del nuevo decreto, pero aún no ha entrado en vigor y hay incertidumbre sobre la fecha exacta. Conviene tenerlo en el radar pero no es urgente hoy.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Endpoint o portal donde Inspección pueda acceder a los registros sin intervención del restaurante.<br> | |
| — Formato y protocolo aún por definir por el Ministerio — pendiente de especificación técnica oficial.<br> | |
| — Se estima plazo de 20 días para adaptación tras publicación en BOE. | |
| </div> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-marker data" style="font-size:14px; font-weight:800;">P5</div> | |
| <div class="step-content"> | |
| <div class="step-title">Vista de auditoría y exportación <span class="step-label">Operacional</span></div> | |
| <div class="step-desc"> | |
| <strong>Por qué es P5:</strong> Una vez implementados P0-P2, toda la data estará ahí. Este punto es la capa de presentación para que los restaurantes (y eventualmente Inspección) puedan visualizar y exportar el historial completo con trazas de auditoría, anulaciones e incidencias de forma clara.<br><br> | |
| <strong>Qué implica:</strong><br> | |
| — Vista de auditoría que muestre fichajes activos + anulados + modificados con su traza.<br> | |
| — Exportación a PDF/CSV compliant para presentar ante Inspección o asesores.<br> | |
| — Filtros por empleado, rango de fechas, tipo de incidencia. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- LEGAL REFERENCES --> | |
| <div class="legal-ref"> | |
| <h3>📖 Base legal aplicable</h3> | |
| <div class="legal-grid"> | |
| <div class="legal-card"> | |
| <div class="tag">Vigente desde 2019</div> | |
| <div class="title">Art. 34.9 Estatuto de los Trabajadores</div> | |
| <div class="desc">Obligación de registro diario con hora de inicio y fin. Conservación 4 años. Acceso para trabajadores, RLT e Inspección.</div> | |
| </div> | |
| <div class="legal-card"> | |
| <div class="tag">Vigente desde 2019</div> | |
| <div class="title">RDL 8/2019, Art. 10</div> | |
| <div class="desc">Introduce la obligatoriedad universal del registro. Infracción grave por incumplimiento.</div> | |
| </div> | |
| <div class="legal-card"> | |
| <div class="tag">Tramitación urgente 2026</div> | |
| <div class="title">Nuevo Decreto Registro Digital</div> | |
| <div class="desc">Digitalización obligatoria, acceso remoto para Inspección, detalle de pausas/horas extra, inmutabilidad, trazabilidad.</div> | |
| </div> | |
| <div class="legal-card"> | |
| <div class="tag">Sanciones</div> | |
| <div class="title">LISOS — Art. 7.5 y Art. 40.1</div> | |
| <div class="desc">Infracciones graves: 751€ a 7.500€ por trabajador. Se multiplican en incumplimientos generalizados.</div> | |
| </div> | |
| <div class="legal-card"> | |
| <div class="tag">Protección de datos</div> | |
| <div class="title">RGPD + Guía AEPD</div> | |
| <div class="desc">Biometría prohibida salvo sin alternativa. Geolocalización solo si justificada. Informar al trabajador del tratamiento.</div> | |
| </div> | |
| <div class="legal-card"> | |
| <div class="tag">Tiempo parcial</div> | |
| <div class="title">Art. 12.4.c ET</div> | |
| <div class="desc">Resumen mensual de horas junto con la nómina. Sin registro, se presume jornada completa.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| function showTab(id) { | |
| document.querySelectorAll('.flow-section').forEach(s => s.classList.remove('active')); | |
| document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); | |
| document.getElementById('tab-' + id).classList.add('active'); | |
| event.target.classList.add('active'); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment