data /
domain / presentation. El dominio no
conoce el backend ni un solo widget.
Either<Failure, T>, así que el compilador obliga
a tratar el fallo. Nada de excepciones sueltas llegando a la UI.
La idea
Toda app seria repite el mismo trabajo antes de resolver su problema: entrar, roles, avisos, ajustes remotos, errores, idiomas, tests. Aquí eso ya está hecho, tipado y con pruebas, para empezar por lo tuyo.
Una regla atraviesa todo lo demás: lo que protege datos vive en la base de datos, no en el cliente. Cada tabla tiene reglas de acceso por fila y cada escritura pasa por una función con sus guardas. La app puede equivocarse; el backend no la deja.
El camino de un dato
Siempre el mismo, en todas las features, y por eso se lee igual la primera vez que la número treinta:
datasource habla con Supabase y lanza excepciones
técnicas → repositorio las convierte en un
Failure tipado → caso de uso aplica la regla
→ cubit emite un estado → la pantalla pinta ese
estado. Nada se salta un escalón.
Por dentro
- Cuando el backend rechaza algo por una regla de negocio —"espera la respuesta de soporte", "no puedes quitarte tu propio rol"— devuelve un código, no un texto. La app lo traduce al idioma de quien mira; el mensaje de la base de datos nunca se enseña tal cual.
- Los cubits que no deben recordar nada entre pantallas se crean nuevos cada vez; los que comparten estado (sesión, avisos, contadores) viven una sola vez para toda la app.
- Las pantallas de carga imitan la forma de lo que va a aparecer, así que al llegar los datos nada salta de sitio.
Entrar
Correo y contraseña, Google y Apple, recuperación de contraseña y un registro extendido para pedir el resto del perfil. Verificación en dos pasos opcional, y obligatoria para quien reparte roles.
Como invitado
Se puede entrar sin registrarse: es una sesión anónima real, con su usuario, su rol y sus reglas de acceso. Antes de crearla se pide el nombre — un invitado sin nombre aparece como "Invitado" en soporte y en el panel, y no hay forma de saber con quién hablas.
Por dentro
- Un trabajo automático borra cada hora las sesiones de invitado inactivas más tiempo del configurado (se cambia desde el panel, sin publicar versión).
- La purga respeta a quien tenga un ticket de soporte abierto: borrarlo se llevaría por delante la conversación a mitad.
- Su perfil esconde lo que no aplica a una sesión temporal —foto, fecha de nacimiento, avisos, dos pasos, eliminar cuenta— y ofrece pasar a cuenta de verdad.
Soporte dentro de la app
El usuario abre una consulta y lo que escribe queda como primer mensaje de un hilo tipo chat. Quien atiende lo ve en la bandeja del panel, con buscador y filtro por estado, responde y cambia el estado. En pantalla ancha, lista y conversación lado a lado.
Por dentro
- "Sin leer" no significa lo mismo para cada lado: para ti es que soporte respondió; para soporte, que el usuario escribió. Cada persona del equipo lleva su propia marca de lectura, así que leer la bandeja no apaga el aviso de nadie.
- El número del badge cuenta exactamente lo mismo que resalta las tarjetas, así que no pueden discrepar.
- Al abrir un ticket no se pueden encadenar mensajes hasta la primera respuesta, para que no llegue un monólogo antes de que nadie lo haya leído. Lo valida la base de datos; la app además esconde la caja de texto, para que no llegues a chocar con el error.
- Quién escribe lo decide la vista, no los permisos: si quien responde a su propio ticket resulta ser del equipo, su mensaje sigue siendo suyo, no de "Soporte".
- Todo en tiempo real: contadores, bandeja y la conversación abierta.
Avisos
Buzón dentro de la app, con las no leídas en vivo y la campana en el inicio. Se borran de una en una o se vacía el buzón entero.
Por dentro
- Los mensajes pueden ser texto libre o referirse a un código con sus traducciones: el mismo aviso se lee en el idioma de cada persona, aunque se enviara hace meses.
- El envío masivo llega por push y además escribe en el buzón, para que no se pierda si se descarta la notificación del sistema.
- El borrado es optimista con marcha atrás: la fila desaparece al momento y, si el servidor la rechaza, vuelve a su sitio y se avisa.
Panel de administración
Tres roles —usuario, admin y owner— con una jerarquía que también se respeta en la base de datos. Dentro: usuarios, avisos, ajustes remotos, registro de auditoría y la bandeja de soporte.
Por dentro
- Solo el owner reparte roles, el último owner no se puede degradar y un admin no puede desactivarlo. Y no vale tocar la tabla directamente: hay un guardián que bloquea cualquier cambio de rol que no pase por la función correcta.
- Cada acción sensible queda en un registro que no se puede editar ni borrar, ni siquiera por quien la hizo.
- La lista de usuarios sale ordenada por rol (owner, admins y luego el resto) y se puede filtrar. El orden y el filtro los hace el servidor, porque la lista va paginada: hacerlo en la app solo ordenaría la página cargada.
Ajustes sin recompilar
Modo mantenimiento, versión mínima obligatoria, registro abierto o cerrado y las banderas que quieras: se cambian desde el panel y la app reacciona en tiempo real, sin publicar una versión nueva. Un admin nunca se queda fuera por el modo mantenimiento, y el mantenimiento no expulsa: se muestra dentro, dejando el perfil accesible.
Diseño
Espaciados, radios, colores y tipografía son tokens: cambias el color de marca en un sitio y se adapta toda la app. Hay una galería navegable con cada widget del sistema, y tema claro y oscuro pensados los dos — no uno "y luego el otro".
La navegación se adapta: barra inferior flotante en móvil y navegación superior en pantalla ancha, con el contenido acotado a un ancho legible.
Que no se rompa
- Tests unitarios, de widget y visuales, con cobertura bloqueante en cada cambio.
- Entornos separados con sus credenciales, y una franja fina que te dice en cuál estás.
- Arranque a prueba de fallos: si el backend no responde, la app no se cae — enseña una pantalla con reintento.
- Sin conexión: aviso propio y recuperación al reconectar.
- Actualización forzada cuando una versión se queda demasiado atrás, sin dejar fuera a quien administra.
¿Te sirve? Puedes probar la app o escribirnos.