Saltar al contenido
verificaOTP

Documento de requisitos técnicos

Stack, arquitectura del playground, persistencia y despliegue.

Este documento describe las decisiones técnicas detrás de verificaOTP: el stack elegido, cómo se aísla el código que escribe el lector, dónde vive cada dato y cómo se despliega el sitio. Se mantiene deliberadamente corto en cada sección para que siga siendo útil como referencia rápida.

Stack

  • React 19 con TypeScript sobre TanStack Start y Vite.
  • Enrutamiento por archivos con TanStack Router (equivalente funcional a react-router, con rutas tipadas y renderizado en servidor).
  • Tailwind CSS v4 con tokens semánticos en CSS y componentes estilo shadcn/ui; íconos lucide-react.
  • CodeMirror 6 vía @uiw/react-codemirror con soporte JavaScript, cargado de forma perezosa.
  • framer-motion para celebración y widget de diff; sonner para notificaciones.

El editor de código es el paquete más pesado del bundle, así que CodeMirror se importa con React.lazy y solo se monta cuando el lector hace scroll hasta el primer playground del capítulo. Mientras carga, se muestra un textarea simple con el mismo código inicial, para que no haya una pantalla en blanco.

Arquitectura del playground

El código del usuario se ejecuta con un debounce de 450 ms dentro de un Web Worker creado desde un Blob. Antes de ejecutar, el worker elimina fetch, XMLHttpRequest, WebSocket, EventSource e importScripts, de modo que no hay red ni DOM. El código se envuelve en una función asíncrona que recibe mx y un console propio.

El hilo principal mantiene un watchdog de 6 segundos: si el worker no informa término, se termina y se muestra un error en la transcripción. Tras terminar, el worker vive 1,2 s más para emitir los recibos de entrega diferidos, como el cambio de estado de «enviado ✓» a «entregado».

mx.sms.send({ to, text })      // bubble "enviado ✓" -> "entregado" after ~800ms
mx.chat.send({ to, text })     // same, chat channel; reachable:false throws
mx.otp.issue(phone)            // 6-digit CSPRNG code, 5 min TTL
mx.otp.verify(phone, code)     // boolean, single use
mx.did.assign(country)         // CL, MX, CO, PE, AR virtual numbers
mx.webhook.sign(payload, sec)  // real HMAC-SHA256 hex via WebCrypto

Persistencia

Un store mínimo sobre localStorage con useSyncExternalStore sincroniza progreso, comentarios y tema entre componentes sin proveedor global. En servidor devuelve valores por defecto estables para evitar desajustes de hidratación.

Cada mutación escribe de inmediato en localStorage y notifica a los suscriptores en memoria; no hay una cola de escritura ni debounce en esta capa, porque el volumen de escrituras es bajo (clicks de usuario, no eventos de alta frecuencia).

Accesibilidad y rendimiento

La navegación completa del lector, incluyendo el mapa de prerrequisitos y los playgrounds, debe funcionar solo con teclado. El modo atenuado se aplica antes del primer pintado leyendo un script inline en el <head>, para evitar el parpadeo de tema que ocurriría si se aplicara después de la hidratación.

Fuentes y despliegue

Inter, Source Serif 4 y JetBrains Mono se cargan desde Google Fonts con preconnect. El sitio se publica como aplicación en el edge y se sirve bajo el dominio propio verificaotp.cl.