Una sola base de código generada por IA para web, móvil y APIs
Descubre cómo una única base de código generada por IA puede alimentar apps web, móviles y APIs con lógica compartida, modelos de datos consistentes y despliegues más seguros.

Qué significa una sola base de código generada por IA
“Una base de código” rara vez significa una UI que funcione en todas partes. En la práctica, suele significar un repositorio y un conjunto de reglas compartidas, con superficies de entrega separadas (app web, app móvil, API) que dependen de las mismas decisiones de negocio subyacentes.
Lógica compartida vs. UI compartida
Un modelo mental útil es compartir las partes que nunca deberían discrepar:
- Reglas de dominio: cálculos, comprobaciones de elegibilidad, precios, flujos de trabajo, invariantes.
- Casos de uso: “crear pedido”, “cancelar suscripción”, “emitir reembolso”, etc.
- Contratos de datos: formas de request/response, reglas de validación, códigos de error.
Mientras tanto, típicamente no compartes la capa de UI de forma global. Web y móvil tienen patrones de navegación distintos, expectativas de accesibilidad, restricciones de rendimiento y capacidades de plataforma. Compartir UI puede ser ventajoso en algunos casos, pero no es la definición de “una base de código”.
Qué cambia la IA (y qué no)
El código generado por IA puede acelerar drásticamente:
- la generación del andamiaje del proyecto (carpetas, scripts de build, componentes básicos)
- la creación de endpoints CRUD y clientes
- la generación de pruebas y fixtures a partir de ejemplos
Pero la IA no produce automáticamente una arquitectura coherente. Sin límites claros, tiende a duplicar lógica entre apps, mezclar responsabilidades (UI llamando directamente a código de base de datos) y crear validaciones “casi iguales” en varios sitios. La ventaja viene de definir la estructura primero y luego usar la IA para rellenar las partes repetitivas.
Resultados por los que aspirar
Una base de código asistida por IA tiene éxito cuando entrega:
- Consistencia: web, móvil y API hacen cumplir las mismas reglas.
- Velocidad: las nuevas funcionalidades se implementan una vez y emergen en todas las plataformas.
- Mantenibilidad: los cambios están localizados, revisados, probados y liberados de forma predecible.
Objetivos y restricciones para la entrega en Web, Móvil y API
Una sola base de código funciona solo cuando tienes claro qué debe lograr—y qué no debe intentar estandarizar. Web, móvil y APIs sirven a audiencias y patrones de uso diferentes, incluso cuando comparten las mismas reglas de negocio.
A quién sirves (y cómo)
La mayoría de los productos tienen al menos tres “puertas de entrada”:
- Usuarios de la web (clientes, administradores, equipos de soporte) que esperan navegación rápida, accesibilidad y actualizaciones sencillas.
- Usuarios móviles que esperan interacciones nativas, soporte para conectividad intermitente y uso eficiente de batería/red.
- Integraciones de terceros (partners, sistemas internos, herramientas de automatización) que dependen de APIs estables, contratos claros y manejo de errores predecible.
El objetivo es consistencia en el comportamiento (reglas, permisos, cálculos), no experiencias idénticas.
No-objetivos: no fuerces UX idéntica
Un modo de fallo común es tratar “una base de código” como “una UI única”. Eso normalmente produce una app móvil con apariencia web o una web con comportamiento móvil—ambas frustrantes.
En su lugar, apunta a:
- Lógica de dominio y validación compartida
- Modelos de datos y contratos de API compartidos
- Diseño de presentación e interacción específico por plataforma
Restricciones clave a diseñar temprano
Modo offline: el móvil a menudo necesita acceso de lectura (y a veces escrituras) sin red. Eso implica almacenamiento local, estrategias de sincronización, manejo de conflictos y reglas claras sobre la “fuente de la verdad”.
Rendimiento: la web se preocupa por el tamaño del bundle y el time-to-interactive; móvil por el tiempo de arranque y la eficiencia de red; las APIs por latencia y throughput. Compartir código no debe significar enviar módulos innecesarios a cada cliente.
Seguridad y cumplimiento: autenticación, autorización, registros de auditoría, cifrado y retención de datos deben ser consistentes en todas las superficies. Si operas en espacios regulados, incorpora requisitos como logging, consentimiento y acceso con privilegios mínimos desde el inicio, no como parches.
Arquitectura de referencia: capas y responsabilidades
Una sola base de código funciona mejor cuando está organizada en capas claras con responsabilidades estrictas. Esa estructura también facilita que el código generado por IA sea más fácil de revisar, probar y reemplazar sin romper partes no relacionadas.
Flujo de alto nivel
Aquí está la forma básica en la que la mayoría de los equipos converge:
Clients (Web / Mobile / Partners)
↓
API Layer
↓
Domain Layer
↓
Data Sources (DB / Cache / External APIs)
La idea clave: las interfaces de usuario y los detalles de transporte se sitúan en los bordes, mientras que las reglas de negocio permanecen en el centro.
Qué se comparte
El “núcleo compartible” es todo lo que debe comportarse igual en todas partes:
- Dominio (lógica de negocio): reglas de precios, comprobaciones de elegibilidad, transiciones de estado de pedido, etc.
- Validación: reglas de entrada y mensajes de error mapeados a códigos de error consistentes.
- Networking + esquemas: tipos de request/response, serialización y pruebas de contrato.
Cuando la IA genera nuevas funcionalidades, el mejor resultado es: actualiza las reglas de dominio una vez y todos los clientes se benefician automáticamente.
Qué debería seguir siendo diferente
Hay código cuyo forzar a una abstracción compartida resulta costoso (o arriesgado):
- Componentes de UI: sistemas de diseño web vs controles nativos.
- Navegación y flujos de usuario: enrutado del navegador vs pilas móviles.
- Capacidades del dispositivo: notificaciones push, biometría, cámara, almacenamiento offline.
Una regla práctica: si el usuario puede verlo o el SO puede romperlo, mantenlo específico de la app. Si es una decisión de negocio, mantenla en el dominio.
Responsabilidades por capa
- Capa API: autenticación, límites de tasa, mapeo HTTP/GraphQL a comandos de dominio.
- Capa de dominio: reglas puras y casos de uso, con dependencias mínimas.
- Fuentes de datos: bases de datos y servicios terceros detrás de interfaces para que las implementaciones puedan cambiar sin reescribir la lógica de negocio.
Capa de dominio compartida (lógica de negocio)
La capa de dominio compartida es la parte del código que debería sentirse “aburrida” en el mejor sentido: predecible, testeable y reutilizable en todas partes. Si la IA te ayuda a generar el sistema, esta capa es donde anclas el significado del proyecto—para que pantallas web, flujos móviles y endpoints API reflejen las mismas reglas.
Empieza por los sustantivos y verbos
Define los conceptos centrales de tu producto como entidades (cosas con identidad a lo largo del tiempo, como Account, Order, Subscription) y objetos de valor (cosas definidas por su valor, como Money, EmailAddress, DateRange). Luego captura el comportamiento como casos de uso (a veces llamados application services): “Crear pedido”, “Cancelar suscripción”, “Cambiar email”.
Esta estructura mantiene el dominio comprensible para no especialistas: los sustantivos describen qué existe, los verbos describen qué hace el sistema.
Mantén las reglas de negocio agnósticas de UI
La lógica de negocio no debería saber si se activa por un toque en pantalla, un envío de formulario web o una petición API. En la práctica, eso significa:
- No importar frameworks (no controladores web, vistas móviles ni anotaciones ORM en el código de dominio)
- No usar strings de UI (los códigos de error o claves son mejores que mensajes hard-coded)
- No asumir la red (el dominio no debería “llamar a la API”; debe expresar reglas)
Cuando la IA genera código, esta separación es fácil de perder: los modelos introducen preocupaciones de UI. Trátalo como un disparador para refactorizar, no como una preferencia.
Un conjunto de reglas de validación para todas partes
La validación es donde los productos suelen derivar: la web permite algo que la API rechaza, o el móvil valida de forma distinta. Coloca la validación consistente en la capa de dominio (o en un módulo de validación compartido) para que todas las superficies apliquen las mismas reglas.
Ejemplos:
EmailAddressvalida el formato una vez, reutilizado en web/móvil/APIMoneyevita totales negativos, independientemente de dónde provenga el valor- Los casos de uso aplican reglas cross-field (p. ej., “la fecha de fin debe ser posterior a la fecha de inicio”)
Si haces esto bien, la capa API se convierte en un traductor y web/móvil en presentadores—mientras que la capa de dominio sigue siendo la fuente única de la verdad.
Capa API: contratos que impulsan todo lo demás
La capa API es la “cara pública” de tu sistema—y en una base de código generada por IA, debería ser la parte que ancle todo lo demás. Si el contrato es claro, la app web, la app móvil e incluso servicios internos pueden generarse y validarse contra la misma fuente de verdad.
Empieza con un contrato API-first
Define el contrato antes de generar handlers o wiring de UI:
- Endpoints y recursos: sustantivos consistentes (p. ej.,
/users,/orders/{id}), filtrado y orden predictable. - Errores: una forma de error estable (code, message, details), con uso documentado de códigos HTTP.
- Paginación: elige un enfoque (cursor-based suele ser fácil de evolucionar) y estandariza los campos de respuesta.
- Versionado: decide temprano (ruta como
/v1/...o basado en headers) y documenta reglas de deprecación.
Genera tipos y clientes desde un esquema
Usa OpenAPI (o una herramienta schema-first como GraphQL SDL) como artefacto canónico. A partir de eso, genera:
- stubs de servidor (rutas, andamiaje de validación)
- clientes tipados para web y móvil
- modelos de request/response compartidos que reducen la deriva
Esto importa para el código generado por IA: el modelo puede crear mucho código rápido, pero el esquema lo mantiene alineado.
Reglas de consistencia que evitan fallos sutiles
Establece algunos no negociables:
- Nomenclatura:
snake_caseocamelCase, no ambos; que coincida entre JSON y tipos generados. - Códigos de estado: 200/201/204 para éxito, 400 para validación, 401/403 para auth, 409 para conflictos.
- Idempotencia: exige un
Idempotency-Keypara operaciones de riesgo (pagos, creación de pedidos) y define comportamiento de reintento.
Trata el contrato de la API como un producto. Cuando es estable, todo lo demás se vuelve más fácil de generar, probar y liberar.
App web: integrar lógica compartida sin acoplar
Una app web se beneficia mucho de la lógica de negocio compartida y sufre cuando esa lógica se entremezcla con preocupaciones de UI. La clave es tratar la capa de dominio compartida como un motor “headless”: conoce las reglas, validaciones y flujos, pero nada sobre componentes, rutas o APIs del navegador.
Opciones de renderizado: SSR vs CSR (y por qué importa)
Si usas SSR (server-side rendering), el código compartido debe ser seguro para ejecutarse en el servidor: nada de window, document o llamadas al almacenamiento del navegador. Eso es una buena fuerza obligatoria: mantiene el comportamiento dependiente del navegador en una capa adaptadora web delgada.
Con CSR (client-side rendering) tienes más libertad, pero la misma disciplina conviene. Los proyectos solo CSR a menudo “accidentalmente” importan código de UI en módulos de dominio porque todo se ejecuta en el navegador—hasta que añades SSR, edge rendering o pruebas que corren en Node.
Una regla práctica: los módulos compartidos deben ser deterministas y agnósticos al entorno; cualquier cosa que toque cookies, localStorage o la URL pertenece a la capa web.
Límites de estado: estado de dominio vs estado de UI
La lógica compartida puede exponer estado de dominio (p. ej., totales de pedido, elegibilidad, flags derivadas) mediante objetos puros y funciones puras. La app web debe poseer estado de UI: spinners de carga, foco de formularios, animaciones optimistas, visibilidad de modales.
Esto mantiene flexible la gestión de estado en React/Vue: puedes cambiar librerías sin reescribir reglas de negocio.
Preocupaciones web que debes aislar
La capa web debe encargarse de:
- Accesibilidad (marcado semántico, navegación por teclado, ARIA)
- Routing (estructura de URLs, enlaces profundos, redirecciones del servidor)
- Almacenamiento del navegador (cookies/sesión,
localStorage, caching)
Piensa en la app web como un adaptador que traduce interacciones de usuario en comandos de dominio y traduce resultados del dominio en pantallas accesibles.
App móvil: lógica compartida con capacidades nativas
Una app móvil se beneficia más de una capa de dominio compartida: las reglas de precios, elegibilidad, validación y flujos deben comportarse igual que en la web y la API. La UI móvil se convierte entonces en una “cáscara” alrededor de esa lógica compartida—optimizando para touch, conectividad intermitente y funciones de dispositivo.
Patrones de plataforma para diseñar
Incluso con lógica compartida, el móvil tiene patrones que rara vez mapean 1:1 con la web:
- Navegación: modela el estado de navegación en la capa de la app (pantallas, tabs, modales), manteniendo decisiones de dominio (p. ej., “el usuario debe verificar el email antes de pagar”) en código compartido.
- Tareas en segundo plano: trata la sincronización, subidas y refrescos como jobs explícitos con límites de tiempo y resumibilidad.
- Notificaciones push: parsea la carga en la capa de la app y luego delega en la lógica compartida para decidir la acción.
- Deep links: enruta links en la capa de la app, pero usa código compartido para validar permisos y obtener datos requeridos.
Offline-first: cache, sync y estrategia de conflictos
Si esperas uso real en móvil, asume offline:
- Cachea modelos de lectura localmente (key-value o SQLite) con una política clara de estalezza.
- Encola escrituras como intenciones/eventos (p. ej., “crear borrador de pedido”) y sincroniza al estar online.
- Define reglas de conflicto desde el principio (last-write-wins, merge servidor-autoritativo o resolución por usuario).
- Implementa reintentos con backoff y claves de idempotencia para que la API acepte duplicados de forma segura.
Preocupaciones específicas móviles
- Tamaño de la app: mantén la capa compartida modular para que la app incluya solo lo necesario.
- Batería/datos: agrupa llamadas de red y evita polling agresivo.
- Permisos: solicita solo cuando haga falta (cámara, ubicación, contactos) y mantén las comprobaciones de permisos fuera del código de dominio para que las políticas varíen por plataforma.
Modelos de datos, auth y permisos en todas las superficies
Una “sola base de código” se rompe rápidamente si la web, móvil y la API inventan formas de datos y reglas de seguridad distintas. La solución es tratar modelos, autenticación y autorización como decisiones de producto compartidas y codificarlas una sola vez.
Una fuente de la verdad para modelos de datos
Elige un lugar donde vivan los modelos y haz que todo lo demás derive de él. Opciones comunes:
- Schema-first: define entidades y reglas de validación en archivos de esquema (p. ej., OpenAPI/JSON Schema) y genera tipos para API, web y móvil.
- Módulos compartidos: conserva tipos de modelo y validadores en un paquete compartido (a menudo el paquete “dominio”) que todas las apps importan.
- Híbrido: archivos de esquema para contratos externos, módulos compartidos para reglas internas de dominio.
La clave no es la herramienta, sino la consistencia. Si OrderStatus tiene cinco valores en un cliente y seis en otro, el código generado por IA compilará y aún así enviará bugs.
Autenticación: sesiones, tokens y almacenamiento seguro
La autenticación debe sentirse igual para el usuario, pero la mecánica difiere por superficie:
- Web suele preferir sesiones basadas en cookies (buena protección CSRF, almacenamiento sencillo en el navegador).
- Móvil y clientes de terceros suelen necesitar auth basada en tokens (access token + refresh token).
Diseña un flujo único: login → acceso de corta duración → refresco cuando haga falta → logout que invalide estado servidor. En móvil, guarda secretos en almacenamiento seguro (Keychain/Keystore), no en preferencias simples. En web, prioriza cookies httpOnly para que los tokens no estén expuestos a JavaScript.
Autorización: reglas centrales aplicadas en la API
Los permisos deben definirse una sola vez—idealmente cerca de las reglas de negocio—y aplicarse en todas partes.
- Centraliza comprobaciones en la capa de dominio (p. ej.,
canApproveInvoice(user, invoice)). - Hazlas cumplir en la API para seguridad real.
- Reflejalas en la UI solo para ocultar/deshabilitar acciones, no para proteger datos.
Esto evita la deriva “funciona en móvil pero no en web” y da a la generación de código por IA un contrato claro y testeable sobre quién puede hacer qué.
Estrategia de build, release y despliegue
Una base unificada solo permanece así si las builds y releases son predecibles. El objetivo es permitir que los equipos publiquen API, web y móviles de forma independiente—sin bifurcar la lógica ni “hacer excepciones” por entorno.
Monorepo vs multi-repo
Un monorepo (un repo, múltiples paquetes/apps) suele funcionar mejor para una sola base de código porque la lógica de dominio, contratos de API y clientes UI evolucionan juntos. Obtienes cambios atómicos (un PR actualiza un contrato y todos los consumidores) y refactors más sencillos.
Un multi-repo puede seguir estando unificado, pero pagarás en coordinación: versionado de paquetes compartidos, publicación de artefactos y sincronización de cambios breaking. Elige multi-repo solo si límites organizacionales, reglas de seguridad o escala lo hacen imprescindible.
Targets de build y artefactos
Trata cada superficie como un target de build separado que consume paquetes compartidos:
- Artefacto del servicio API: imagen de contenedor o bundle serverless construido desde el paquete de la app API.
- Bundle web: assets estáticos + runtime del servidor (si SSR) construido desde el paquete de la app web.
- Builds móviles: Android (AAB/APK) e iOS (IPA) producidos por pipelines nativos, pero consumiendo lógica compartida como dependencia.
Mantén salidas de build explícitas y reproducibles (lockfiles, toolchains fijados, builds deterministas).
Pipeline CI/CD y separación de entornos
Un pipeline típico es: lint → typecheck → tests unitarios → pruebas de contrato → build → escaneo de seguridad → deploy.
Separa configuración de código: variables de entorno y secretos viven en tu CI/CD y gestor de secretos, no en el repo. Usa overlays por entorno (dev/stage/prod) para que el mismo artefacto pueda promoverse entre entornos sin reconstruirse—especialmente para API y runtime web.
Testing y puertas de calidad para código compartido
Cuando web, móvil y API se publican desde la misma base de código, las pruebas dejan de ser “una casilla más” y se convierten en el mecanismo que evita que un pequeño cambio rompa tres productos a la vez. El objetivo es simple: detectar problemas donde cuesta menos arreglarlos y bloquear cambios riesgosos antes de que lleguen a usuarios.
Pirámide de pruebas práctica para una base compartida
Empieza por el dominio compartido (tu lógica de negocio) porque es lo más reutilizado y el lugar más barato para probar sin infraestructura lenta.
- Tests unitarios (capa de dominio): valida reglas como precios, elegibilidad, decisiones de permisos, transiciones de estado y casos límite. Deben ser rápidos y constituir la mayor parte de la suite.
- Tests de integración (capa API): demuestra que la API funciona end-to-end con serialización real, validación, autenticación y acceso a datos. Manténlos enfocados en flujos críticos, no en cada esquina.
- Tests UI (por cliente): un número pequeño de comprobaciones de alto valor para web y móvil que confirmen journeys clave (login, checkout, enviar formulario) en la UI real. Son más lentos, así que trátalos como “alarmas” y no como prueba exhaustiva.
Esta estructura mantiene la mayor parte de la confianza en la lógica compartida y aún así captura problemas de wiring donde las capas se encuentran.
Pruebas de contrato para mantener clientes y API alineados
Incluso en un monorepo, es fácil que la API cambie de tal forma que compile pero rompa la experiencia. Las pruebas de contrato previenen la deriva silenciosa.
- Contratos API→cliente: bloquea shapes de request/response, formatos de error y códigos de estado. Si la API devuelve un nuevo campo requerido o cambia un enum, las pruebas de contrato fallan antes del merge.
- El esquema como puerta: si publicas esquemas OpenAPI/GraphQL, trata los cambios de esquema como artefactos revisables. Los cambios breaking deben requerir aprobación explícita y un plan de migración.
Puertas de calidad que protegen releases
Tener buenas pruebas importa, pero también importan las reglas alrededor de ellas.
- Gates en PR: exige pasar tests unitarios + integración, linting/formateo y cobertura mínima en la capa de dominio.
- Feature flags: despliega código de forma segura ocultando comportamiento inacabado detrás de flags activables por entorno o por grupo de usuarios.
- Despliegues escalonados: publica primero a usuarios internos, luego a un pequeño porcentaje de tráfico en producción y luego a todos.
- Plan de rollback: haz del rollback un resultado de primera clase—releases versionados, migraciones reversibles (o que se puedan avanzar de forma segura) y criterios claros de “parar la línea”.
Con estas puertas, los cambios asistidos por IA pueden ser frecuentes sin ser frágiles.
Cómo usar IA sin perder el control de la arquitectura
La IA puede acelerar una base de código única, pero solo si se la trata como un ingeniero junior rápido: estupenda produciendo borradores, insegura para merge sin revisión. El objetivo es usar IA para velocidad mientras los humanos siguen siendo responsables de la arquitectura, los contratos y la coherencia a largo plazo.
Dónde ayuda la IA más (y con menos riesgo)
Usa la IA para generar “primeras versiones” que de otro modo escribirías de forma mecánica:
- Andamiaje de proyectos (carpetas, módulos boilerplate, esqueletos de features)
- Docs de API y ejemplos basados en contratos existentes
- Suites de pruebas (tests unitarios sobre reglas de dominio, pruebas de contrato para endpoints)
- Migraciones y scripts de seed
- Refactors repetitivos (renombrar campos, dividir módulos), después de definir el plan
Una buena regla: deja que la IA produzca código fácil de verificar leyendo o ejecutando tests, no código que cambie el significado de negocio en silencio.
Guardrails que protegen la arquitectura
La salida de IA debe estar limitada por reglas explícitas, no por sensaciones. Coloca estas reglas donde está el código:
- Estándares de código: linters/formatters, reglas de nomenclatura y “no acceso directo a BD desde UI” como constraints de estilo.
- Reglas de arquitectura: fronteras de dependencia (p. ej., la capa de dominio no puede importar API/web/móvil), aplicadas vía tooling o cheques de build simples.
- Checklist de PR: “¿Cambié el contrato? Actualiza OpenAPI + tipos de cliente + tests.” “¿Nueva regla de dominio? Añade tests de dominio.”
Si la IA sugiere un atajo que viola fronteras, la respuesta es “no”, aunque compile.
Gobernanza: hacer auditable la IA
El riesgo no es solo código malo—son decisiones no rastreadas. Mantén una traza de auditoría:
- Guarda prompts y respuestas clave junto a tickets (ID) y enlaces de PR.
- Registra decisiones arquitectónicas (ADRs) para cambios de contrato, modelo de auth o conceptos de dominio nuevos.
- Exige que los cambios de API sean explícitos: versionados, documentados y respaldados por pruebas de contrato.
La IA es más valiosa cuando es repetible: el equipo puede ver por qué se generó algo, verificarlo y regenerarlo de forma segura cuando evolucionen los requisitos.
Nota de tooling: IA que respeta fronteras
Si adoptas desarrollo asistido por IA a nivel de sistema (web + API + móvil), la característica más importante no es la velocidad de generación pura, sino la capacidad de mantener las salidas alineadas con tus contratos y capas.
Por ejemplo, Koder.ai es una plataforma de vibe-coding que ayuda a equipos a construir aplicaciones web, servidor y móvil mediante una interfaz de chat—manteniendo la producción de código fuente real y exportable. En la práctica, eso es útil para el flujo descrito en este artículo: puedes definir un contrato de API y reglas de dominio, luego iterar rápidamente en superficies React, backends Go + PostgreSQL y apps Flutter sin perder la capacidad de revisar, probar y aplicar límites de arquitectura. Funciones como modo de planificación, snapshots y rollback encajan bien con la disciplina de “generar → verificar → promover” en una base de código unificada.
Cuándo no usar una sola base de código (y qué hacer en su lugar)
Una sola base de código puede reducir duplicación, pero no es la mejor elección por defecto. En el momento en que el código compartido empieza a forzar UX incómodas, ralentizar releases o esconder diferencias de plataforma, pasarás más tiempo negociando arquitectura que entregando valor.
Casos donde convienen bases separadas
Los repositorios separados (o al menos capas UI separadas) suelen justificarse cuando:
- Las UIs altamente personalizadas son el producto. Si web y móvil necesitan modelos de interacción fundamentalmente distintos (gestos, pantallas offline-first, flujos centrados en cámara, animaciones complejas), la UI compartida suele volverse un compromiso.
- Existen restricciones estrictas de plataforma. Reglas de revisión de App Store, permisos de hardware, límites de ejecución en background y requisitos de accesibilidad pueden exigir implementaciones específicas por plataforma.
- Las cadencias de release difieren. Móvil puede publicar mensualmente mientras la web lo hace a diario. Un monorepo muy ligado puede convertir cada cambio en un evento de coordinación.
Modos de fallo comunes a vigilar
- Sobre-compartir UI: “Una UI para dominar a todas” lleva a experiencias de denominador común más bajas.
- Abstracciones con fugas: un módulo “compartido” expone detalles web/móvil (routing, almacenamiento, tokens) y todos los consumidores se vuelven frágiles.
- Drift de versiones: los equipos copian/pegan código compartido para avanzar rápido y las correcciones aterrizan solo en un lugar.
Checklist de decisión (y qué hacer en su lugar)
Pregúntate antes de comprometerte con una sola base de código:
- ¿Se puede compartir la lógica de dominio de forma limpia manteniendo la UI nativa?
- ¿Necesitan los equipos de plataforma autonomía en tooling, timing de release y experimentación?
- ¿Son las APIs lo bastante estables para que los clientes evolucionen independientemente?
Si ves señales de advertencia, una alternativa práctica es dominio compartido + contratos de API, con apps web y móviles separadas. Mantén el código compartido centrado en reglas de negocio y validación, y deja que cada cliente tenga la propiedad de la UX y las integraciones de plataforma.
Si quieres ayuda para elegir un camino, compara opciones en /pricing o explora patrones de arquitectura relacionados en /blog.
Preguntas frecuentes
¿Significa “una base de código generada por IA” una única UI que funciona en todas partes?
Significa normalmente un repositorio y un conjunto de reglas compartidas, no una aplicación idéntica en todas las plataformas.
En la práctica, web, móvil y API comparten una capa de dominio (reglas de negocio, validación, casos de uso) y, a menudo, un contrato de API único, mientras que cada plataforma mantiene su propia interfaz y sus integraciones específicas.
¿Qué debería compartirse entre web, móvil y API—y qué no?
Comparte lo que no debe diferir nunca:
- Reglas de dominio (precios, elegibilidad, flujos, invariantes)
- Casos de uso (crear pedido, cancelar suscripción, emitir reembolso)
- Validación + códigos de error
- Esquemas/contratos de API (OpenAPI/GraphQL) y tipos generados
Mantén los componentes de UI, la navegación y las integraciones con dispositivo/navegador específicas por plataforma.
¿Qué cambia la IA en la arquitectura y qué permanece igual?
La IA acelera el andamiaje y el trabajo repetitivo (CRUD, clientes, pruebas), pero no creará automáticamente buenas fronteras.
Sin una arquitectura intencional, el código generado por IA suele:
- duplicar lógica entre aplicaciones
- mezclar responsabilidades (UI accediendo directamente a la base de datos)
- crear validaciones ligeramente distintas en varios lugares
Utiliza la IA para rellenar capas bien definidas, no para inventar la división en capas.
¿Cuál es una arquitectura de referencia adecuada para una base de código compartida?
Un flujo simple y fiable es:
- Los clientes (web/móvil/partners) llaman a la capa API
- La capa API traduce las peticiones a casos de uso del dominio
- El dominio llama a interfaces de fuentes de datos (DB/cache/APIs externas)
Esto centraliza las reglas de negocio y facilita las pruebas y las adiciones generadas por IA.
¿Cómo evitamos la deriva de validación entre web, móvil y la API?
Coloca la validación en un solo sitio (el dominio o un módulo de validación compartido) y reutilízala en todas partes.
Patrones prácticos:
- validar objetos de valor como
EmailAddressyMoneyuna sola vez - aplicar reglas cross-field dentro de los casos de uso (p. ej., rangos de fechas)
- devolver códigos de error estables (la UI puede mapear códigos a mensajes)
Esto previene la deriva del tipo “la web lo acepta, la API lo rechaza”.
¿Cómo puede el contrato de la API convertirse en la “fuente de la verdad” para todo el sistema?
Usa un esquema canónico como OpenAPI (o GraphQL SDL) y genera a partir de él:
- stubs del servidor y andamiaje de validación de peticiones
- clientes tipados para web y móvil
- modelos compartidos de request/response
Añade pruebas de contrato para que los cambios que rompen el esquema fallen en CI antes de llegar a producción.
¿Qué significa “offline-first” al compartir lógica con una app móvil?
Diseña el modo offline de forma intencional en lugar de “confiar en que el caché funcione”:
- cachea modelos de lectura localmente con una política clara de obsolescencia
- encola escrituras como intenciones/eventos y sincroniza cuando haya conexión
- define reglas de conflicto (servidor autoritativo, merge, o resolución por el usuario)
- usa reintentos con backoff y idempotency keys
Mantén el almacenamiento offline y la sincronización en la capa de la app móvil; las reglas de negocio permanecen en el código de dominio compartido.
¿Cómo deberían funcionar la autenticación y los permisos entre web, móvil y APIs?
Sigue un flujo conceptual único, implementado apropiadamente por superficie:
- Web: a menudo sesiones basadas en cookies httpOnly (reduce la exposición de tokens a JS)
- Móvil/terceros: access + refresh tokens, guardados en almacenamiento seguro (Keychain/Keystore)
Las reglas de autorización deben definirse centralmente (p. ej., canApproveInvoice) y hacerse cumplir en la API; la UI refleja las comprobaciones solo para ocultar/deshabilitar acciones.
¿Cómo se mantienen manejables los builds y releases en una base de código unificada?
Trata cada superficie como un target de build separado que consume paquetes compartidos:
- API: artefacto de contenedor o bundle serverless
- Web: bundle estático + runtime SSR si es necesario
- Móvil: builds nativos iOS/Android que importan lógica compartida
En CI/CD, ejecuta: lint → typecheck → tests unitarios → pruebas de contrato → build → escaneo de seguridad → deploy, y mantén secretos/config fuera del repositorio.
¿Cómo usamos la IA para acelerar el desarrollo sin perder el control arquitectónico?
Usa la IA como un ingeniero junior veloz: excelente para borradores, insegura para merge sin guardrails.
Buenas medidas:
- reforzar límites de dependencias (el dominio no puede importar web/móvil/API)
- exigir actualización de esquema y clientes cuando cambien contratos
- requerir tests unitarios de dominio para nuevas reglas
- guardar ADRs y prompts clave vinculados a PRs/tickets
Si la salida de IA viola reglas de arquitectura, recházala aunque compile.