Provisionar una tablet nueva para el kiosk Smiley¶
Esta guía te lleva paso a paso por la puesta en marcha de una tablet nueva como terminal de opinión Smiley. Al terminar, la tablet queda vinculada a un sanitario y opinando: muestra el idle con "Último servicio: hace X min" y encola/sincroniza opiniones contra el backend WorkDone.
La terminal no tiene login de usuario: se autentica como Dispositivo de tipo TERMINAL_SMILEY, vinculado a un único sanitario. La identidad y las credenciales las asigna el backend al vincular. Para el contexto del módulo ver Kiosk Smiley; para los contratos REST, la Referencia de API.
Prerequisitos¶
| Necesitás | Por qué | Cómo lo conseguís |
|---|---|---|
| Acceso ADMIN al BackOffice | Crear la terminal y generar el código de vinculación son operaciones solo-ADMIN (/api/v1/admin/smiley/terminal) |
Tu usuario tiene que tener ROLE_ADMIN |
| El sanitario ya creado en el sistema | La terminal se vincula a un sanitario existente; sin él, el alta devuelve 404 |
Verificá el sanitario en el BackOffice antes de empezar |
| Una tablet Android con la app Smiley instalada | Es la terminal física que vas a vincular | Idealmente con device-owner para Lock Task silencioso (ver más abajo) |
| Conectividad para el primer sync | El código de vinculación se canjea online y el primer sync baja la config remota (textos, logo, PIN-hash) | WiFi o red de datos que alcance el backend |
Device-owner para un kiosko real
Una tablet sin device-owner funciona, pero NO queda confinada con Lock Task: el visitante puede salir de la app. En ese caso la terminal muestra un banner "Terminal no asegurada". Para un kiosko de producción, provisioná la tablet como device-owner antes de empezar (ver Modo kiosko).
El flujo de vinculación de un vistazo¶
sequenceDiagram
actor Admin
participant BO as BackOffice
participant Tablet
participant API as Backend WorkDone
Admin->>BO: Crear terminal POST /admin/smiley/terminal
BO->>API: alta Dispositivo TERMINAL_SMILEY + codigo 24h
API-->>BO: codigo de vinculacion un solo uso
BO-->>Admin: muestra el codigo UNA sola vez
Admin->>Tablet: lleva el codigo a la tablet
Tablet->>API: GET /smiley/ping probar conexion
API-->>Tablet: version + server_time
Tablet->>API: POST /smiley/vincular codigo
API-->>Tablet: device_uuid + api_key en plano + datos del sanitario
Note over Tablet,API: de aca en mas auth por X-Device-Uuid + X-Api-Key
Tablet->>API: POST /smiley/sync primer sync
API-->>Tablet: config remota + ultima_limpieza_hace_min
Note over Tablet: Terminal operando, muestra el idle
Paso 1 — Crear la terminal en el BackOffice¶
Entrá al BackOffice como ADMIN y abrí la pantalla Terminales Smiley desde el menú lateral. Vas a ver la lista de terminales (cada una asociada a un sanitario) con su estado de vinculación y último sync. Si todavía no hay ninguna, la pantalla muestra el estado vacío con el aviso "Sin terminales Smiley registradas. Creá la primera con 'Nueva terminal'.".

Pantalla Terminales Smiley: la lista de terminales (acá vacía), el botón + Nueva terminal arriba a la derecha y, abajo, la tarjeta para fijar el PIN técnico del menú oculto por empresa.
Para crear la terminal:
- Hacé clic en + Nueva terminal (arriba a la derecha).
- Elegí el sanitario donde va a ir montada la tablet.
- Confirmá. La terminal aparece en la lista con su número/alias asignados y el estado vinculación pendiente (código pendiente, todavía sin canjear).
Al crearla, el backend genera un código de vinculación de un solo uso con vencimiento a 24 h y te lo muestra.
Bajo el capó
Al confirmar, el BackOffice dispara:
POST /api/v1/admin/smiley/terminal
Content-Type: application/json
{ "sanitario_id": 42, "nombre": "Smiley baño hombres - PB" }
El campo nombre es opcional. El backend da de alta un Dispositivo de tipo TERMINAL_SMILEY vinculado a ese sanitario y devuelve el código de vinculación:
El código se muestra una sola vez — copialo ahora
Copiá el código apenas aparece (la UI lo muestra en un modal de un solo uso). Si lo perdés, no lo recuperás: tenés que regenerarlo (ver Problemas comunes).
Deberías ver la terminal nueva en la lista de Terminales Smiley con estado de vinculación pendiente (código pendiente) y su número/alias asignados.
Errores posibles en este paso
404— elsanitario_idno existe. Verificá el sanitario antes de reintentar.409— ya hay una terminal activa para ese sanitario. El sistema permite una sola terminal activa por sanitario; desvinculá la vieja o elegí otro sanitario.
Paso 2 — Preparar la tablet¶
Antes de tocar la app, dejá la tablet lista como kiosko físico:
- Montaje y alimentación: fijá el soporte antivandálico a la salida del sanitario, a altura de mano, con la pantalla bien visible. La tablet queda siempre enchufada.
- Modo kiosko / device-owner: para un kiosko real, la tablet tiene que estar como device-owner (Lock Task confina la app, sin barras de sistema). Sin device-owner aparece el banner "Terminal no asegurada".
- Orientación horizontal: la app bloquea la orientación en horizontal (
sensorLandscape) — va montada en pared y no debe rotar a vertical. - Autoarranque: la app arranca sola al boot y tiene watchdog de reinicio; no hace falta abrirla a mano tras un corte de luz.
Deberías ver la app Smiley arrancar en horizontal al encender la tablet. En el primer arranque (sin vincular) aparece directo la pantalla de setup — sin gesto ni PIN, porque todavía no hay nada que proteger.
Paso 3 — Setup en la tablet: URL del server y probar conexión¶
En la pantalla de setup:
- Verificá la URL del server. Viene precargada con el default del build; confirmá que apunta al backend correcto.
- Tocá "Probar conexión". Por debajo, la app llama al endpoint público (sin credenciales):
que responde:
Deberías ver una confirmación de conexión OK. Si falla, frená acá y revisá red/URL antes de seguir — el código no se va a poder canjear sin conexión.
La URL bien formada importa
La URL tiene que ser http(s)://host[:puerto] sin ruta ni query. Una URL con path la rechaza la app antes de mutar nada.
Paso 4 — Vincular: canjear el código¶
Ingresá el código de vinculación del Paso 1 en el campo correspondiente y confirmá. La app llama a:
El backend valida el código (un solo uso, no expirado), lo consume y responde con las credenciales y la identidad de la terminal:
{
"device_uuid": "8f3a1c20-...-9e21",
"api_key": "sk_live_3f9a...PLANO_UNA_SOLA_VEZ",
"sanitario_id": 42,
"numero_terminal": 5,
"alias": "Smiley · S-042",
"sanitario_codigo": "S-042",
"sanitario_nombre": "Baño hombres - Planta Baja"
}
La api_key viaja en texto plano UNA sola vez
El backend solo persiste el hash BCrypt de la api_key — el texto plano viaja únicamente en esta respuesta y no se puede volver a pedir. La app la guarda cifrada en reposo (DataStore). Si se pierde, hay que regenerar el código y re-vincular.
De acá en más la terminal se autentica en todos los endpoints /api/v1/smiley/* (salvo /ping y /vincular) con los headers:
El backend valida que el dispositivo exista, esté activo, sea TERMINAL_SMILEY y que el hash BCrypt coincida; falla cerrado si no. El sanitario_id nunca viaja en el body del sync: lo determina el server por el vínculo del dispositivo, así una terminal no puede opinar por otro sanitario.
Deberías ver la app pasar del setup a la pantalla operativa (idle / caritas). Los campos numero_terminal, alias, sanitario_codigo y sanitario_nombre alimentan la línea de diagnóstico y el menú técnico.
Paso 5 — Verificar que quedó andando¶
Cerrá el lazo con tres chequeos:
-
Pantalla idle: en reposo, la terminal muestra "Último servicio: hace X min" (sin nombre del operario). Si no hay limpieza registrada o el dato es viejo, la línea se oculta — es el comportamiento correcto, no un error.
-
Menú técnico → identidad: hacé 10 toques sobre el logo Lubeca (máx. ~2,5 s entre toques) → ingresá el PIN técnico (el de la empresa o el default global; verifica offline). En la sección Info/diagnóstico deberías ver: Terminal Nº, alias, sanitario, uuid corto, versión, última sync y opiniones pendientes en cola. Tienen que coincidir con lo que muestra el BackOffice para ese device.
-
Primer sync OK: desde el menú técnico tocá "sincronizar ahora" (o esperá el ciclo automático). El sync (
POST /api/v1/smiley/sync) baja la config remota (textos, sonido, logo,pin_tecnico_hash,ultima_limpieza_hace_min).
Confirmá contra el tablero de equipos
En el BackOffice, Estado de equipos (GET /api/v1/admin/dispositivo/estado) la terminal debería aparecer EN LÍNEA, con su número/alias y el sanitario correcto. Una tablet con device-owner aparece como confinada (lock_task_activo: true).
Problemas comunes¶
El código venció o ya se usó → 410¶
El código de vinculación es de un solo uso y vence a las 24 h. Si está expirado o ya consumido, POST /api/v1/smiley/vincular devuelve 410. Regenerá uno nuevo desde el BackOffice:
y repetí el Paso 4 con el código nuevo.
El código es inválido / mal formado → 400¶
Un código mal tipeado o con formato incorrecto devuelve 400. Volvé a copiarlo del BackOffice (cuidado con confundir caracteres) y reintentá.
Cómo colapsa la app los errores de vinculación
La app agrupa los rechazos del backend (400 mal formado, 404 inexistente, 409 ya usado, 410 expirado) en un único estado "código inválido/expirado/usado" para mostrarte un mensaje claro. Si ves ese error, lo más probable es código expirado o ya canjeado → regeneralo.
Banner "Terminal no asegurada"¶
Aparece cuando la tablet no tiene device-owner: la app no puede confinarse con Lock Task y el visitante podría salir. La terminal igual opina, pero para producción provisioná la tablet como device-owner y reabrí la app. En builds debug/DEMO_MODE el banner nunca aparece (no es un kiosko real).
Necesito mover la terminal o anular la vinculación¶
Para desvincular una terminal (la deja inactiva, liberando el sanitario para una terminal nueva):
Para mover la terminal a otro sanitario: creá una terminal nueva en el otro sanitario (Paso 1) y desvinculá esta. Recordá que solo puede haber una terminal activa por sanitario (409 si intentás duplicar).
Cambié la URL del server y se desvinculó sola¶
Es por diseño: editar la URL del server desde el menú técnico borra las credenciales y vuelve la terminal al estado no-vinculado. La api_key jamás viaja a un server distinto del que la emitió, así que un cambio de URL exige un código nuevo del BackOffice y volver a vincular (Paso 4).
La tablet se quedó sin conexión¶
Opera igual: la terminal es offline-first. Las opiniones se encolan localmente (idempotentes por client_uuid) y suben cuando vuelve la red. Lo único que pierde frescura es el "Último servicio: hace X min" del idle.
Regla de oro: la terminal NO se configura en el lugar
Textos, sonido, logo y reglas se administran remoto desde el BackOffice y bajan en el próximo sync. El menú técnico es solo para diagnóstico, conexión y re-vinculación — nunca configuración funcional.