Referencia de aplicación. Esta es una arquitectura ilustrativa y una lista de comprobación del alcance, no un proyecto real de cliente verificado ni una implementación con métricas medidas. Las tecnologías, el alcance de la integración y los elementos de entrega se acuerdan para el briefing real.
Escenario y restricciones
Un producto de servicios en el que iOS y Android comparten los mismos flujos de trabajo y un equipo pequeño debe mantener ambas plataformas. Tres restricciones condicionan el diseño: redes móviles poco fiables, ciclos de revisión de las tiendas de aplicaciones que ralentizan las correcciones urgentes y la necesidad de cambiar las reglas de negocio sin publicar una nueva compilación.
Arquitectura
Capas y responsabilidades
| Capa | Tecnología | Responsabilidad |
|---|---|---|
| Aplicación | Flutter (Dart), estructurado en UI / estado / repositorio | Pantallas e interacción. La capa de repositorio es la única que sabe si los datos proceden de la red o de la caché local, lo que mantiene la gestión del modo sin conexión fuera del código de la UI. |
| Almacenamiento local | SQLite (drift) + almacenamiento seguro de la plataforma | Entidades en caché, una bandeja de salida de escrituras pendientes y tokens en almacenamiento seguro en lugar de preferencias compartidas. |
| API | Go + Gin, rutas versionadas | Reglas de negocio, validación y autorización. Versionada desde el primer día porque las versiones antiguas de la aplicación permanecen en manos de los usuarios mucho después de su lanzamiento. |
| Almacenamiento | PostgreSQL | Datos transaccionales; JSONB se utiliza para atributos realmente variables en lugar de ampliar las tablas indefinidamente. |
| Caché / cola | Redis | Sesiones, limitación de solicitudes, claves de idempotencia y cola de trabajos en segundo plano. |
| Notificaciones push | FCM y APNs detrás de un único servicio de notificaciones | Una única API interna para las notificaciones; las diferencias entre plataformas se gestionan en el servidor, no en la aplicación. |
| Administración | Panel de administración en Vue | Gestión de usuarios, contenido y pedidos, además de los valores de configuración remota que cambian el comportamiento de la aplicación sin un lanzamiento. |
Modelo de datos
Las tablas siguientes contienen las reglas de las que depende todo lo demás. Equivocarse en ellas es lo que convierte una demo funcional en un sistema que no se puede ampliar.
Entidades principales
| Entidad | Campos clave, relaciones y reglas |
|---|---|
| user / auth_identity | Un usuario puede tener varias identidades (teléfono, Apple, Google, WeChat). Separar la identidad del usuario permite añadir posteriormente un método de inicio de sesión sin una migración. |
| device | Token push, plataforma, versión de la aplicación y configuración regional por dispositivo. La segmentación de notificaciones y los lanzamientos graduales consultan estos datos. |
| order / booking | La entidad del dominio con una columna de estado explícita y un registro de transiciones, para poder responder en soporte a «¿cómo llegó a este estado?». |
| outbox (del cliente) | Escrituras locales en cola con un UUID generado por el cliente. Ese UUID se convierte en la clave de idempotencia en el servidor, lo que hace seguros los reintentos tras un tiempo de espera. |
| sync_cursor | Marca de tiempo updated_at por usuario que impulsa la sincronización incremental, de modo que la aplicación obtiene cambios en lugar de volver a solicitar colecciones completas. |
| remote_config | Configuración clave-valor por versión de la aplicación y plataforma, que permite cambiar reglas y indicadores de funcionalidad sin enviar una actualización a la tienda. |
Interfaces clave
Endpoints que contienen las reglas de negocio
| Endpoint | Propósito y notas sobre concurrencia |
|---|---|
| POST /api/v1/auth/token | Emite un token de acceso de corta duración junto con un token de actualización rotatorio. La rotación de tokens de actualización limita el daño de un token robado en un dispositivo al que no se puede acceder. |
| GET /api/v1/sync?since= | Obtención incremental de registros modificados desde un cursor, paginada y con un límite, para que un usuario que vuelve después de semanas sin conexión no pueda obtener una respuesta sin límites. |
| POST /api/v1/orders | Acepta el UUID del cliente como clave de idempotencia; un reintento después de un tiempo de espera de red devuelve el pedido original en lugar de crear un duplicado. |
| POST /api/v1/devices | Registra o actualiza el token push, vinculado al usuario y a la versión de la aplicación para permitir notificaciones segmentadas y graduales. |
| GET /api/v1/config | Devuelve la configuración remota para la versión de la aplicación solicitante: el mecanismo que evita tener que publicar una compilación para cambiar una regla. |
Decisiones técnicas
- Flutter en lugar de dos bases de código nativas. Los flujos de trabajo son compartidos y el equipo es pequeño, por lo que el código de aplicación compartido puede reducir el mantenimiento duplicado cuando los flujos coinciden; las integraciones con plataformas, las comprobaciones del dispositivo y los lanzamientos siguen requiriendo trabajo independiente. Cuando las plataformas realmente difieren —pagos, notificaciones push, biometría— la diferencia se aísla detrás de un canal de plataforma en lugar de permitir que se filtre al código compartido.
- Tolerante a la desconexión, no basado en el modo sin conexión. Las lecturas se almacenan en caché y las escrituras se encolan en una bandeja de salida, pero el servidor sigue siendo la fuente de autoridad. Un modo completamente basado en la operación sin conexión, con resolución de conflictos, cuesta considerablemente más y solo merece la pena cuando los usuarios trabajan realmente desconectados durante largos periodos.
- UUID generados por el cliente como claves de idempotencia. En las redes móviles, las solicitudes suelen agotar el tiempo de espera a mitad de la solicitud. Sin esto, los reintentos tras un tiempo de espera pueden crear un riesgo de pedidos duplicados que debe probarse.
- API versionada desde el primer lanzamiento. Los usuarios posponen las actualizaciones, por lo que el servidor debe seguir sirviendo a las versiones antiguas. Incorporar el versionado después del lanzamiento es mucho más costoso que comenzar con él.
- Configuración remota para las reglas de negocio. Los lanzamientos del cliente dependen de la revisión de las plataformas y de la adopción por parte de los usuarios. Los umbrales compatibles, los textos y los indicadores de funcionalidad pueden gestionarse en el servidor cuando las reglas de la plataforma lo permitan; los cambios que requieran una nueva compilación de la aplicación conservan esa dependencia.
Objetivos de diseño hipotéticos
Las cifras siguientes son ejemplos hipotéticos para la planificación de capacidad, no resultados medidos de clientes, una recomendación de dimensionamiento validada ni un SLA. Defina objetivos de aceptación específicos del proyecto después de establecer la carga de trabajo, los dispositivos, los datos, el hardware y las dependencias de terceros; verifíquelos mediante un piloto y pruebas de carga antes de comprometerse con un objetivo de producción.
Objetivos de capacidad y rendimiento
| Objetivo | Valor y supuesto |
|---|---|
| Inicio en frío hasta la primera pantalla significativa | Menos de 2 segundos en un dispositivo Android de gama media, suponiendo que los datos almacenados en caché se muestran mientras la red se actualiza en segundo plano. |
| Sincronización incremental | Carga diferencial inferior a 200 KB para un usuario habitual que vuelve a la aplicación, con el tamaño de página limitado para que un usuario ausente durante mucho tiempo se degrade correctamente en lugar de agotar el tiempo de espera. |
| Latencia de la API | p95 inferior a 300 ms para lecturas estándar, excluidas las llamadas de terceros cuya latencia no controlamos. |
| Entrega de notificaciones push | Defina y mida los tiempos de encolado de la aplicación y de confirmación del proveedor. El tiempo final de entrega depende de la plataforma y no está garantizado por esta referencia. |
Qué incluye la entrega
- Código fuente de la aplicación Flutter, del backend en Go y del panel de administración en Vue en su repositorio
- Configuración de compilación y firma para ambas plataformas, además de la preparación de las fichas de las tiendas
- Documentación de la API, esquema de la base de datos e historial de migraciones
- Notas de despliegue, acceso a la monitorización y los registros, procedimiento de copia de seguridad y restauración
- Asistencia para el envío a App Store y Google Play; el resultado y los plazos de la revisión corresponden a Apple y Google
Planificación para su empresa
Los módulos anteriores son un punto de partida, no un paquete fijo. Normalmente reducimos la primera versión a un flujo de trabajo principal y uno de administración, y después ampliamos cuando el uso real muestra dónde están realmente la carga y los casos límite. Envíe un briefing acotado y lo contrastaremos con esta arquitectura para indicarle qué partes todavía no necesita.

