Qiiub POS · Task 11 · B1 — Mockup para revisión

Login identify-first — dos modos, configurable por terminal

Created: 2026-06-22 | Last Updated: 2026-06-22

El modo se elige por terminal vía el knob identifyMode (sembrado identify-by-number por defecto para terminales de mostrador público). Ambos terminan en el mismo paso de PIN. Pantalla de superficie de auth → revisión de seguridad + fidelidad antes de escribir JSX.

identify-list Roster visible

Terminales de trastienda / staff-only. Paso 1: elige tu nombre del roster cargado (PH2a listLoginableEmployees). Paso 2: PIN.

QQiiub POS Terminal 01 · Farmacia Centro
Buenas tardes
Inicia tu turno
Selecciona tu nombre para identificarte
Empleados que pueden iniciar sesión
MG
MaríaCajero
CM
CarlosGerente
LR
LucíaCajero
JM
JavierCajero
AP
AnaCajero
RC
RamónCajero
PIN de María García
1
2
3
4
5
6
7
8
9
Limpiar
0
¿Olvidaste tu PIN? Pregunta al gerente

identify-by-number Cero enumeración

Default en terminales de mostrador público. Paso 1: teclea tu número de empleado (sin roster). Paso 2: PIN. Nadie ve la nómina.

QQiiub POS Terminal 01 · Farmacia Centro
Buenas tardes
Inicia tu turno
Ingresa tu número de empleado
Verificación facial
Esperando cámara…
Seguro
Número de empleado
•••
1
2
3
4
5
6
7
8
9
Limpiar
0
¿Olvidaste tu número? Pregunta al gerente Continuar →

Fallo de PIN — copy uniforme (ambos modos)

Un solo mensaje. No distingue PIN incorrecto, cuenta bloqueada, ni empleado inexistente. Sin contador de intentos restantes.

No pudimos verificarte
Revisa tu PIN e intenta de nuevo. ¿Problemas? Pregunta al gerente.
1
2
3
4
5
6
7
8
9
Limpiar
0

Lo que NO se muestra (por seguridad)

Ausencias deliberadas — el contraste con el fallo uniforme de la izquierda.

«Cuenta bloqueada» — el fallo nunca revela estado de lockeo (lo maneja el modelo de PH2a en silencio).
«PIN incorrecto» vs «empleado no existe» — un solo mensaje; no es un oráculo de sondeo.
«2 intentos restantes» — sin contador de intentos.
«Último acceso: María, 14:32» — ningún dato de sesión previa (el SessionStore es memory-only; no hay nada que mostrar).
En identify-by-number: ninguna lista, ningún nombre, ningún autocompletado de números — cero enumeración del roster.

Mapa de revisión de seguridad (lo que pediste auditar)

aby-number NO renderiza roster. El modo derecho no tiene lista ni nombres — solo el campo de número + numpad. Cero enumeración. ✓
a+El campo by-number NO revela el formato del código. Dots enmascarados solo de los dígitos tecleados (sin placeholder de longitud fija, sin prefijo). NUNCA renderizar 00••• ni patrón con longitud/prefijo visible — el formato del employee code es información del roster (enumeración indirecta). Requisito heredado por el JSX. ✓
bFallo de PIN uniforme. «No pudimos verificarte / Revisa tu PIN e intenta de nuevo» — idéntico para PIN incorrecto, bloqueado, o inexistente. ✓
cidentify-list expone solo la lista deliberada. Cada empleado muestra nombre + rol + avatar. Sin badge de lockeo, sin intentos restantes, sin estado de sesión. ✓
dNingún dato de sesión previa. No hay «último acceso», ni nombre cacheado, ni sesión recordada — coherente con el invariante memory-only (BUG-010). ✓
Notas de implementación (no son UI): el roster viene de listLoginableEmployees(); el login llama PinAuthService.login(employeeRef, pin)useSessionStore.login(session)sessionManager.dispatch('login') (IdentifyGate→Active). Verificación facial = el componente SelfieCapture existente (reusado, no nuevo). Todo el copy va por i18next (ES mostrado; EN espejo). Tokens: brand #930EA5, gold POS #FFD700, Poppins/Inter/JetBrains Mono.