[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"technologies":3,"\u002Fportfolio\u002Fcashback-loyalty-platform":167,"glossary":525},[4,10,15,21,26,32,38,43,48,53,58,63,68,73,77,82,87,92,97,103,108,113,118,123,128,133,138,143,147,152,157,162],{"title":5,"description":6,"slug":7,"category":8,"icon":9},"Android","Todas las apps que entregamos llegan a Android: APIs de plataforma, ejecución en segundo plano, permisos y los requisitos de tienda que traen consigo.","android","framework","logos:android-icon",{"title":11,"description":12,"slug":13,"category":8,"icon":14},"Angular","El framework de frontend en el que trabajamos cuando un producto ya es Angular: una estructura con todo incluido que encaja en apps grandes y de vida larga.","angular","logos:angular-icon",{"title":16,"description":17,"slug":18,"category":19,"icon":20},"Dart","El lenguaje en el que está escrita cada app Flutter que entregamos: null safety robusto, pattern matching de verdad y un compilador que apunta a nativo y a la web.","dart","language","logos:dart",{"title":22,"description":23,"slug":24,"category":8,"icon":25},"Django","El framework de Python que usamos cuando un producto necesita administración, autenticación y un modelo de datos real desde el primer día.","django","logos:django-icon",{"title":27,"description":28,"slug":29,"category":30,"icon":31},"Docker","Cada servicio que construimos se publica como contenedor, así que lo que corre en un portátil, en CI y en producción es un solo artefacto y no tres.","docker","infrastructure","logos:docker-icon",{"title":33,"description":34,"slug":35,"category":36,"icon":37},"Fastlane","La automatización de releases móviles: firma, builds y subidas a las tiendas desde CI, no desde el portátil de un ingeniero el día del lanzamiento.","fastlane","tools","logos:fastlane",{"title":39,"description":40,"slug":41,"category":8,"icon":42},"Flutter","Nuestro stack móvil principal desde 2018: una base de código Dart que llega a iOS, Android, web y escritorio sin un equipo por plataforma.","flutter","logos:flutter",{"title":44,"description":45,"slug":46,"category":36,"icon":47},"Git","Todos los proyectos que tocamos viven en Git: pull requests revisadas, CI en cada rama y un historial que sigue teniendo sentido meses después.","git","logos:git-icon",{"title":49,"description":50,"slug":51,"category":19,"icon":52},"Go","Nuestro lenguaje de backend para APIs en tiempo real y servicios bajo carga: binarios pequeños, compilaciones rápidas y concurrencia que sigue siendo legible.","go","logos:gopher",{"title":54,"description":55,"slug":56,"category":30,"icon":57},"Google Cloud","La nube donde corren nuestras cargas de producción: Kubernetes gestionado, almacenamiento y red, sin servidores hechos a mano que nadie quiere mantener.","gcp","logos:google-cloud",{"title":59,"description":60,"slug":61,"category":36,"icon":62},"Gradle","El sistema de build por el que pasa cada release de Android: product flavours, configuraciones de firma y el cableado de dependencias bajo una app Flutter.","gradle","logos:gradle",{"title":64,"description":65,"slug":66,"category":30,"icon":67},"Helm","Cómo empaquetamos un despliegue de Kubernetes: servicio, configuración, secretos e ingress como una unidad versionada que se puede promover y revertir.","helm","logos:helm",{"title":69,"description":70,"slug":71,"category":19,"icon":72},"Kotlin","A lo que recurrimos cuando una app Flutter necesita Android de verdad por debajo: platform channels, trabajo en segundo plano e integraciones con SDK nativos.","kotlin","logos:kotlin-icon",{"title":74,"description":75,"slug":76,"category":8,"icon":72},"Kotlin Multiplatform","Compartir la lógica de negocio entre iOS y Android mientras cada plataforma conserva su UI nativa: la alternativa cuando Flutter no encaja.","kmp",{"title":78,"description":79,"slug":80,"category":30,"icon":81},"Kubernetes","Cómo ejecutamos servicios en producción: despliegues con Helm, rollouts reversibles y escalado que no necesita a nadie a las 3 de la mañana.","kubernetes","logos:kubernetes",{"title":83,"description":84,"slug":85,"category":30,"icon":86},"NATS","Mensajería ligera entre servicios: publicación\u002Fsuscripción y petición\u002Frespuesta sin el peso operativo de un clúster de broker completo.","nats","logos:nats-icon",{"title":88,"description":89,"slug":90,"category":8,"icon":91},"Nuxt","Vue con renderizado en servidor, enrutado y SEO resueltos: así hacemos sitios y apps web que deben ser rápidas e indexables en la primera carga.","nuxt","logos:nuxt-icon",{"title":93,"description":94,"slug":95,"category":19,"icon":96},"PHP","Donde trabajamos con un backend PHP ya existente: extenderlo, integrarse con él y construir los clientes móviles y web a los que tiene que servir.","php","logos:php",{"title":98,"description":99,"slug":100,"category":101,"icon":102},"PostgreSQL","Nuestra base de datos por defecto, salvo que un producto dé una razón concreta para no usarla: del diseño del esquema al ajuste de índices.","postgres","database","logos:postgresql",{"title":104,"description":105,"slug":106,"category":19,"icon":107},"Python","Nuestro lenguaje para backends, trabajo con datos e integraciones de IA, incluidos los bindings de Python que publicamos para nuestras propias herramientas en Rust.","python","logos:python",{"title":109,"description":110,"slug":111,"category":8,"icon":112},"React","La librería de frontend en la que trabajamos cuando un producto ya es React: componentes, hooks y el ecosistema que ha crecido a su alrededor.","react","logos:react",{"title":114,"description":115,"slug":116,"category":101,"icon":117},"Redis","Donde ponemos los datos que tienen que ser rápidos y se pueden reconstruir: cachés, sesiones, límites de tasa y las colas tras las rutas lentas de un producto.","redis","logos:redis",{"title":119,"description":120,"slug":121,"category":19,"icon":122},"Ruby","El lenguaje de nuestra automatización de releases móviles: lanes de Fastlane, acciones a medida y el pegamento de CI que sube builds a las tiendas.","ruby","logos:ruby",{"title":124,"description":125,"slug":126,"category":19,"icon":127},"Rust","A donde vamos cuando importan tanto el rendimiento como la corrección: renderizado de documentos, herramientas de CLI y servicios que tienen que ser rápidos y predecibles.","rust","simple-icons:rust",{"title":129,"description":130,"slug":131,"category":101,"icon":132},"SQLite","La base de datos que viaja dentro de la app: cachés locales, almacenamiento offline-first y todo lo que tiene que seguir funcionando sin red.","sqlite","logos:sqlite",{"title":134,"description":135,"slug":136,"category":8,"icon":137},"Strapi","Un CMS headless para cuando los editores necesitan ser dueños del contenido: una administración de verdad y una API limpia, sin construirlas desde cero.","strapi","logos:strapi-icon",{"title":139,"description":140,"slug":141,"category":19,"icon":142},"Swift","A lo que recurrimos cuando una app Flutter necesita iOS de verdad por debajo: platform channels, integraciones con SDK nativos, widgets y App Clips.","swift","logos:swift",{"title":144,"description":145,"slug":146,"category":8,"icon":142},"SwiftUI","El framework de UI de Apple, donde construimos las superficies nativas que una app Flutter no puede tener: widgets, App Clips y extensiones.","swiftui",{"title":148,"description":149,"slug":150,"category":8,"icon":151},"Tailwind CSS","Cómo damos estilo a cada frontend que construimos: clases de utilidad y design tokens en lugar de una hoja de estilos que solo crece y nunca se borra.","tailwind","logos:tailwindcss-icon",{"title":153,"description":154,"slug":155,"category":19,"icon":156},"TypeScript","Lo predeterminado para todo lo que escribimos para el navegador y para servicios Node: tipos que detectan errores de integración antes de llegar a una revisión.","typescript","logos:typescript-icon",{"title":158,"description":159,"slug":160,"category":8,"icon":161},"Vue","Nuestro framework de frontend para paneles de administración, cuadros de mando y apps web que deben seguir siendo mantenibles durante años.","vue","logos:vue",{"title":163,"description":164,"slug":165,"category":36,"icon":166},"Whisper","El modelo de reconocimiento de voz de código abierto de OpenAI: el motor de transcripción detrás de la entrada por voz, que funciona como servicio de backend y también en el propio dispositivo.","whisper","simple-icons:openai",{"id":168,"title":169,"body":170,"categories":501,"client":505,"date":506,"description":507,"duration":508,"extension":509,"image":510,"links":513,"meta":514,"metaDescription":515,"navigation":516,"ogDescription":517,"path":518,"seo":519,"slug":520,"stem":521,"technologies":522,"updated":523,"__hash__":524},"projects_es\u002Fportfolio\u002Fcashback-loyalty-platform.md","Plataforma de apps de cashback y fidelización",{"type":171,"value":172,"toc":486},"minimark",[173,178,182,196,204,207,213,217,221,228,231,242,245,249,257,268,272,275,279,286,308,311,315,318,321,327,337,343,347,369,372,375,379,386,390,406,417,425,429,432,435,461,478,482],[174,175,177],"h2",{"id":176},"resumen-del-proyecto","Resumen del proyecto",[179,180,181],"p",{},"Nuestro cliente opera una plataforma de cashback que permite a comercios físicos —cafeterías, salones, boutiques, comercio de barrio— recompensar a sus clientes y, no menos importante, por fin llegar a conocerlos. Los negocios de calle rara vez tienen los datos de cliente que las tiendas online dan por sentados: quiénes son sus habituales, cuándo vinieron por última vez, qué les hace volver. La plataforma cierra esa brecha poniendo un programa de cashback y fidelización en manos de cada comercio participante, y una app de marca en el bolsillo de cada cliente.",[179,183,184,185,189,190,195],{},"En lugar de publicar una sola app, el modelo de negocio pide una ",[186,187,188],"em",{},"familia"," de aplicaciones: una app de consumo insignia donde los compradores descubren comercios participantes y siguen su cashback, una app específica para que los comercios se conecten y gestionen sus propias recompensas, y un catálogo creciente de apps de ",[191,192,194],"term",{"slug":193},"white-label","marca blanca",", cada una de ellas una app de cashback completamente personalizada y publicada de forma independiente para una marca socia o una cadena, todas movidas por el mismo producto.",[179,197,198,199,203],{},"Cuando el proyecto maduró, el ecosistema abarcaba ",[200,201,202],"strong",{},"más de 15 aplicaciones móviles en producción",". El reto de ingeniería nunca fue construir bien una app: fue construir una base de código que pudiera convertirse en cualquier número de apps de cashback de marca sin que el coste de mantenimiento creciera linealmente con cada nuevo socio.",[179,205,206],{},"Fuimos responsables del sistema completo de principio a fin: la app de consumo compartida, la app de comercios, la flota de marca blanca, el motor de reglas de cashback y los servicios de backend, y las herramientas internas de administración que convirtieron «lanzar una nueva app de marca» de una tarea de ingeniería de varios días en un formulario autogestionado.",[208,209,210],"nda-notice",{},[179,211,212],{},"Este proyecto está cubierto por un acuerdo de confidencialidad. No se nombran ni el cliente, ni las marcas socias que hay detrás de las apps de marca blanca, ni las fichas publicadas en las tiendas: las capturas de abajo muestran el producto funcionando con datos de prueba.",[214,215],"gallery",{":images":216},"[{\"url\": \"\u002Fprojects\u002Fcashback-loyalty-platform\u002Fimages\u002F01.webp\", \"alt\": \"Inicio de la app de consumo con saldo de cashback y bonus por invitar amigos\"}, {\"url\": \"\u002Fprojects\u002Fcashback-loyalty-platform\u002Fimages\u002F02.webp\", \"alt\": \"Detalle de comercio con porcentaje de cashback por compra\"}, {\"url\": \"\u002Fprojects\u002Fcashback-loyalty-platform\u002Fimages\u002F03.webp\", \"alt\": \"Cupones y novedades del comercio\"}, {\"url\": \"\u002Fprojects\u002Fcashback-loyalty-platform\u002Fimages\u002F05.webp\", \"alt\": \"Configuración de una aplicación de marca blanca\"}, {\"url\": \"\u002Fprojects\u002Fcashback-loyalty-platform\u002Fimages\u002F06.webp\", \"alt\": \"Lista de aplicaciones de marca blanca en la administración\"}]",[174,218,220],{"id":219},"una-base-de-código-muchas-apps","Una base de código, muchas apps",[179,222,223,224,227],{},"La app de consumo insignia y todas las variantes de marca blanca corren sobre una ",[200,225,226],{},"única base de código",". No hay forks, ni ramas por marca, ni proyectos copiados y pegados que mantener sincronizados. Lo que difiere entre apps —marca, tema, identidad, feature flags, configuración de recompensas y metadatos de la ficha de tienda— se expresa enteramente como configuración que vive fuera del código.",[179,229,230],{},"Construimos el cliente en torno a un sistema de flavours y configuración: un binario único que actúa como plantilla y resuelve su identidad de marca en tiempo de compilación a partir de un paquete de configuración por app. Colores, tipografía, logos, pantallas de inicio, iconos de app, identificadores de paquete y conjuntos de funciones activas se inyectan por flavour. Un bug arreglado una vez, o una funcionalidad entregada una vez, aterriza en todas las apps de la flota en la siguiente release: no hay divergencia por marca que mantener.",[179,232,233,234,237,238,241],{},"Lo decisivo es que las palancas que definen cada marca las manejan ",[200,235,236],{},"responsables sin conocimientos de programación",". A través de la interfaz de administración, una persona no técnica define los ",[200,239,240],{},"iconos, colores, luminosidad (tema claro u oscuro) y determinados textos"," de una app nueva, y esas decisiones fluyen directamente a la compilación sin intervención de un desarrollador. Quienes son dueños del aspecto de una marca pueden cambiarlo directamente, en lugar de abrir un ticket y esperar a ingeniería.",[179,243,244],{},"Esta es la palanca económica central del proyecto: el coste marginal de la decimosexta app es casi cero, porque es el mismo código que la primera, con una configuración distinta.",[174,246,248],{"id":247},"configuración-de-build-nativa-en-dart","Configuración de build nativa en Dart",[179,250,251,252,256],{},"Una flota de marca blanca vive o muere por la configuración de build nativa: los ajustes de Android e iOS que a las tiendas realmente les importan. Los application ID y los identificadores de paquete, los nombres visibles, los números de versión y de build, la configuración de firma, los iconos y recursos de splash y las entradas por flavour en ",[253,254,255],"code",{},"build.gradle"," y en el proyecto de Xcode tienen que ser correctos para cada app y cada build.",[179,258,259,260,263,264,267],{},"En vez de mantener eso a mano, escribimos ",[200,261,262],{},"herramientas propias en Dart que gestionan programáticamente la configuración de build de Android e iOS",". Dado el paquete de configuración de una marca, la herramienta reescribe las entradas correspondientes de Gradle, del manifiesto, del ",[253,265,266],{},"Info.plist"," y del catálogo de recursos para que encajen con el flavour objetivo antes de que se ejecute la compilación. Mantener esta lógica en Dart hace que comparta la misma fuente de verdad que el cliente Flutter y que se ejecute como un paso de primera clase de nuestro proceso de build, así que la configuración nativa de una marca se genera de forma determinista a partir de su configuración y nunca se edita a mano.",[174,269,271],{"id":270},"la-app-de-comercios","La app de comercios",[179,273,274],{},"Los comercios físicos necesitaban su propia herramienta, no una versión recortada de la vista de consumo, sino una app pensada para gestionar un programa de recompensas y entender a sus clientes. Desde la app de comercios, un dueño de tienda se conecta a la plataforma en minutos, define sus reglas de cashback y descuentos, confirma las compras de los clientes para otorgar cashback y, por fin, ve quiénes son sus clientes: nuevos frente a recurrentes, con qué frecuencia visitan y cómo funciona cada promoción. Para muchos de estos negocios es la primera visión estructurada de su base de clientes que han tenido nunca. La construimos sobre la misma base de Flutter y la misma librería de componentes compartida que las apps de consumo, así que las actualizaciones del sistema de diseño y las correcciones de plataforma se propagan a ambos públicos, mientras que los flujos específicos de comercio viven en sus propios módulos.",[174,276,278],{"id":277},"reglas-configurables-de-cashback-y-descuentos","Reglas configurables de cashback y descuentos",[179,280,281,282,285],{},"El corazón de la plataforma es un ",[200,283,284],{},"motor de reglas"," flexible que permite a cada comercio diseñar sus propias recompensas sin nuestra ayuda. A través de la app de comercios, una tienda compone reglas como:",[287,288,289,296,302],"ul",{},[290,291,292,295],"li",{},[200,293,294],{},"Cashback por compra",": un porcentaje o cantidad fija devuelta al saldo del cliente en cada compra que cumpla los requisitos.",[290,297,298,301],{},[200,299,300],{},"Bonus de cumpleaños",": una recompensa acreditada automáticamente en torno al cumpleaños del cliente para hacerle volver a cruzar la puerta.",[290,303,304,307],{},[200,305,306],{},"Bonus por invitación",": una recompensa por recomendación que se paga cuando un cliente existente invita a un amigo que se registra y hace su primera compra.",[179,309,310],{},"Las reglas son datos, no código: cada comercio elige su combinación, fija los importes, los topes y las ventanas de validez, y el motor las evalúa en el momento de la compra. Como las reglas viven en la configuración, un comercio puede lanzar una campaña de cumpleaños o cambiar un porcentaje de cashback por sí mismo, al instante, en toda su app, y nosotros no publicamos ninguna release para permitirlo.",[174,312,314],{"id":313},"la-administración-y-el-pipeline-de-build-automatizado","La administración y el pipeline de build automatizado",[179,316,317],{},"La pieza más destacada del sistema es la interfaz interna de administración. Incorporar una nueva marca de marca blanca solía ser un recado de ingeniería: crear la configuración, registrar los identificadores de paquete, generar los recursos de firma, montar las fichas de tienda y añadir el nuevo target a CI. Comprimimos todo eso en una única aplicación web que los responsables manejan sin escribir código.",[179,319,320],{},"Un responsable rellena un formulario —nombre de marca, tema, recursos, metadatos de tienda, selección de funciones— y el sistema hace el resto:",[179,322,323,326],{},[200,324,325],{},"Generación de configuración",": la administración persiste la configuración y los recursos de la nueva marca y produce el paquete de configuración por flavour que consume el cliente Flutter.",[179,328,329,332,333,336],{},[200,330,331],{},"Registro en el pipeline",": el nuevo target de app se registra automáticamente en el pipeline de ",[191,334],{"slug":335},"ci-cd",". El sistema de build recoge el nuevo flavour, ejecuta nuestras herramientas en Dart para aplicar la configuración nativa de Android e iOS y produce artefactos firmados para ambas plataformas.",[179,338,339,342],{},[200,340,341],{},"Lanzamientos autogestionados",": lo que antes requería un desarrollador en el circuito para cada marca nueva pasó a ser un proceso repetible guiado por un formulario. El negocio puede escalar el número de apps publicadas sin escalar el tamaño del equipo de ingeniería.",[174,344,346],{"id":345},"automatización-de-build-y-despliegue-con-fastlane","Automatización de build y despliegue con Fastlane",[179,348,349,350,356,357,362,363,368],{},"Todo el proceso de compilación y publicación está automatizado de principio a fin con ",[351,352,33],"a",{"href":353,"rel":354},"https:\u002F\u002Ffastlane.tools",[355],"nofollow",", la cadena de herramientas de código abierto para automatizar build y despliegue móvil. La usamos para estandarizar cada paso que si no sería manual y propenso a errores en más de 15 apps: gestionar la firma y el aprovisionamiento, compilar y firmar los binarios de iOS y Android, y enviar cada app a la ",[351,358,361],{"href":359,"rel":360},"https:\u002F\u002Fdocs.fastlane.tools\u002Fgetting-started\u002Fios\u002Fappstore-deployment\u002F",[355],"App Store"," y a ",[351,364,367],{"href":365,"rel":366},"https:\u002F\u002Fdocs.fastlane.tools\u002Fgetting-started\u002Fandroid\u002Frelease-deployment\u002F",[355],"Google Play"," junto con sus metadatos y capturas.",[179,370,371],{},"Como todas las apps comparten una única configuración de Fastlane parametrizada por flavour, publicar la flota entera es una operación única y repetible. Una nueva marca de marca blanca hereda exactamente el mismo camino de despliegue sobradamente probado que la app insignia, sin necesidad de scripts de release a medida.",[179,373,374],{},"La administración es una aplicación Nuxt respaldada por nuestros servicios en PHP y un almacén de datos PostgreSQL, con las herramientas de Ruby y Fastlane orquestando la automatización de build y publicación.",[174,376,378],{"id":377},"backend-y-servicios","Backend y servicios",[179,380,381,382,385],{},"Bajo todas las apps hay un backend compartido que ejecuta el ",[200,383,384],{},"libro mayor de cashback",", el motor de reglas, los perfiles de cliente y la configuración por marca. Un único conjunto de servicios sostiene la flota entera, con el contexto de marca resuelto en cada petición, de modo que un cliente en cualquier app de marca blanca, en la app insignia o un comercio que usa la app de comercios está hablando con la misma superficie de API probada, acotada a su marca. El libro mayor registra cada acumulación y cada canje para que los saldos sean siempre auditables, y los perfiles de cliente dan a cada comercio esa visión sobre su público de la que el comercio físico suele carecer.",[174,387,389],{"id":388},"deep-linking-diferido-y-el-bonus-por-invitación","Deep linking diferido y el bonus por invitación",[179,391,392,393,396,397,401,402,405],{},"La funcionalidad que esto desbloqueó fue el ",[200,394,395],{},"bonus por invitación",". Las recomendaciones son la forma en que crece la plataforma: un cliente satisfecho invita a un amigo, que toca el enlace de invitación, pero que casi nunca tiene todavía la app instalada. Con un ",[191,398,400],{"slug":399},"deep-linking","deep link"," corriente, ese contexto de invitación se perdía en el momento en que el amigo llegaba a la tienda: instalaba, abría la app, aterrizaba en una pantalla de inicio genérica y la conexión entre quien invita y quien es invitado desaparecía, y con ella el bonus por invitación prometido a ambos. El momento más viral del producto estaba roto en su paso más importante. Lo arreglamos con ",[200,403,404],{},"deep linking diferido"," para que la invitación sobreviva a la instalación.",[179,407,408,409,412,413,416],{},"Como toda la flota comparte una base de código, la funcionalidad se construyó una vez y todas las apps de marca —insignia, comercios y todas las variantes de marca blanca— la heredaron automáticamente. La implementamos con mecanismos de primera parte en lugar de con un servicio de terceros: un ",[200,410,411],{},"App Clip de iOS"," ligero captura el enlace de invitación antes de que exista la app completa y lo traspasa mediante un contenedor de App Group compartido, mientras que la ",[200,414,415],{},"API Install Referrer de Google Play"," lleva la carga útil en Android. Una cola de enlaces pendientes retiene la invitación hasta que la app está lista y el nuevo cliente se ha registrado e iniciado sesión; solo entonces se atribuye la recomendación y se acredita el bonus por invitación tanto a quien invitó como al nuevo cliente, de modo que la recompensa se resuelve correctamente aunque abarque una instalación y un inicio de sesión nuevo en un arranque en frío.",[179,418,419,420,424],{},"Escribimos el enfoque técnico completo —incluido por qué la solución habitual dejó de funcionar— en ",[351,421,423],{"href":422},"\u002Fblog\u002Fdeferred-deep-linking-app-clips-install-referrer","Deep linking diferido después de Firebase Dynamic Links: App Clips + Play Install Referrer",".",[174,426,428],{"id":427},"resultados","Resultados",[179,430,431],{},"El cliente puede lanzar ahora una app de cashback completamente personalizada y lista para tienda para un socio nuevo en una fracción del tiempo que antes costaba, sin apartar ingenieros del trabajo de producto en cada lanzamiento. La arquitectura de base de código compartida mantiene más de 15 apps al mismo paso: una corrección, una funcionalidad, una release llega a todas. La administración convirtió un cuello de botella recurrente de ingeniería en una capacidad autogestionada, y el pipeline automatizado hizo de cada nuevo lanzamiento un evento predecible y repetible en vez de un proyecto a medida. Y los comercios físicos que antes iban a ciegas gestionan ahora sus propias campañas de cashback y descuentos y, por primera vez, saben quiénes son sus clientes.",[179,433,434],{},"La economía en cifras:",[287,436,437,443,449,455],{},[290,438,439,442],{},[200,440,441],{},"Más de 15 apps en producción desde una única base de código",": sin forks, sin ramas por marca, sin divergencias que reconciliar en el momento de la release.",[290,444,445,448],{},[200,446,447],{},"El coste marginal de la siguiente app de marca es casi cero",": una marca nueva es un paquete de configuración más los metadatos de tienda, no un nuevo proyecto de ingeniería.",[290,450,451,454],{},[200,452,453],{},"Lanzar una marca pasó de ser una tarea de ingeniería de varios días a un formulario autogestionado",", manejado por responsables sin conocimientos de programación.",[290,456,457,460],{},[200,458,459],{},"La base de código única en Flutter cuesta en torno a un 30–40 % menos de lo que costarían dos apps nativas",", y como toda la flota la comparte, ese ahorro se obtiene una vez por cada marca y se acumula en el conjunto de las más de 15 apps.",[179,462,463,464,468,469,473,474,424],{},"Este es el tipo de plataforma que construimos en un encargo de ",[351,465,467],{"href":466},"\u002Fservices\u002Fwhitelabel-app-development","desarrollo de apps de marca blanca"," —una base de código Flutter moviendo una flota entera de apps de marca—, y ancla la vertiente de fidelización y cashback de nuestra práctica de ",[351,470,472],{"href":471},"\u002Fservices\u002Fflutter-app-development\u002Fe-commerce","desarrollo de apps de e-commerce",". La interfaz de administración que lanza cada marca es el tipo de back office interno que describe nuestra página de ",[351,475,477],{"href":476},"\u002Fservices\u002Fweb-development\u002Fadmin-dashboards","paneles de administración y cuadros de mando",[174,479,481],{"id":480},"preguntas-frecuentes","Preguntas frecuentes",[483,484],"questions",{":items":485},"[{\"title\":\"¿Qué es una plataforma de apps de marca blanca?\",\"text\":\"Una única base de código que puede rebrandearse y republicarse como cualquier número de apps separadas, cada una con su propia marca. En esta plataforma, la app de cashback insignia y todas las apps de socios comparten el mismo código Flutter; lo que difiere —colores, logos, iconos de app, identificadores de paquete, feature flags, configuración de recompensas, metadatos de tienda— se expresa enteramente como configuración por marca que vive fuera del código.\"},{\"title\":\"¿Cómo puede una sola base de código Flutter mover más de 15 apps distintas?\",\"text\":\"Mediante un sistema de flavours y configuración: un binario único que actúa como plantilla resuelve su identidad de marca en tiempo de compilación a partir de un paquete de configuración por app, y unas herramientas propias en Dart reescriben la configuración de build nativa de Android e iOS —entradas de Gradle, manifiestos, Info.plist, catálogos de recursos— para que encajen con la marca objetivo antes de cada build. Un bug arreglado una vez, o una funcionalidad entregada una vez, aterriza en todas las apps de la flota en la siguiente release.\"},{\"title\":\"¿Cómo se lanza una nueva app de marca sin desarrolladores?\",\"text\":\"A través de una interfaz interna de administración. Un responsable rellena un formulario —nombre de marca, tema, iconos, colores, metadatos de tienda, selección de funciones— y el sistema genera el paquete de configuración, registra la nueva app en el pipeline de CI y produce artefactos firmados de iOS y Android. Después, Fastlane envía cada app a la App Store y a Google Play con sus metadatos y capturas, así que publicar la flota entera es una única operación repetible.\"},{\"title\":\"¿Rechazan las tiendas de aplicaciones las apps de marca blanca?\",\"text\":\"Rechazan flotas de reskins finos y casi idénticos: exactamente para eso existe la directriz 4.2.6 de Apple. Una plataforma de marca blanca tiene que diseñarse desde el principio para pasar la revisión: cada app de esta flota es un producto completamente personalizado, con su propia identidad, su ficha de tienda y su configuración de funciones y recompensas por marca, no una plantilla con el logo cambiado. El pipeline de publicación también admite cuentas de desarrollador separadas por marca cuando los acuerdos con los socios o las políticas de las tiendas lo exigen.\"},{\"title\":\"¿Cuánto cuesta una flota de marca blanca frente a apps separadas?\",\"text\":\"La primera app carga con el coste de la plataforma: la base de código compartida, el sistema de temas y feature flags, el motor de reglas, el panel de administración y el pipeline automatizado. Cada app posterior es drásticamente más barata, porque una marca nueva es configuración y no un proyecto. Además, la base de código única en Flutter cuesta en torno a un 30–40 % menos que mantener apps nativas separadas de iOS y Android, un ahorro que se acumula en toda la flota.\"},{\"title\":\"¿Cómo sobrevive el bonus por invitación a que la app aún no esté instalada?\",\"text\":\"Mediante deep linking diferido construido sobre mecanismos de primera parte: un App Clip de iOS ligero captura el enlace de invitación antes de que exista la app completa y lo traspasa mediante un contenedor de App Group compartido, mientras que la API Install Referrer de Google Play lleva la carga útil en Android. Una cola de enlaces pendientes retiene la invitación hasta que el nuevo cliente ha instalado la app, se ha registrado y ha iniciado sesión; solo entonces se atribuye la recomendación y se acredita el bonus a ambas partes.\"}]",{"title":487,"searchDepth":488,"depth":488,"links":489},"",2,[490,491,492,493,494,495,496,497,498,499,500],{"id":176,"depth":488,"text":177},{"id":219,"depth":488,"text":220},{"id":247,"depth":488,"text":248},{"id":270,"depth":488,"text":271},{"id":277,"depth":488,"text":278},{"id":313,"depth":488,"text":314},{"id":345,"depth":488,"text":346},{"id":377,"depth":488,"text":378},{"id":388,"depth":488,"text":389},{"id":427,"depth":488,"text":428},{"id":480,"depth":488,"text":481},[502,503,504],"mobile","backend","web","nda","2025-08-01","Una plataforma de cashback y fidelización de marca blanca para comercios físicos: más de 15 apps móviles de marca desde una base de código Flutter, una app para comercios donde configurar reglas de cashback a medida (cumpleaños, invitación, por compra) y una interfaz de administración que lanza nuevas apps de marca automáticamente.","8 meses","md",{"alt":511,"url":512},"Plataforma de apps de cashback y fidelización: material visual reservado por NDA","\u002Fprojects\u002Fcashback-loyalty-platform\u002Fhero.webp",null,{},"Plataforma de cashback y fidelización de marca blanca: 15+ apps de marca desde una base de código Flutter, app de comercios y administración autogestionada.",true,"Un solo código Flutter, más de 15 apps de marca y un panel que lanza una nueva por su cuenta. Y una app de comercio para las reglas de cashback.","\u002Fportfolio\u002Fcashback-loyalty-platform",{"title":169,"description":507},"cashback-loyalty-platform","portfolio\u002Fcashback-loyalty-platform",[41,18,155,90,160,95,100,121,35],"2026-09-05","xJfojK18_q6XwOCy7QdmK6ePxUHv0N_BNC7GzNEbFW0",[526,541,558,573,585,597,610,625,638,653,666,681,693,706,718,730,747,760,773,786,799,813,825,836,850,862,875,886,895,908,920,934,941,953,964,975,987,1002,1015,1028,1040,1051,1065,1079,1091,1102,1114,1125,1138,1150,1161,1175,1184],{"slug":527,"term":528,"definition":529,"category":530,"aliases":531,"links":533,"related":537,"readMore":-1,"target":539,"hasArticle":540},"aosp","AOSP","El Android Open Source Project: Android sin la capa de Google encima, que cualquiera puede forkear. Los terminales de punto de venta, los kioscos y los sistemas de a bordo funcionan sobre forks suyos, y trabajar a ese nivel expone partes del SO que un desarrollador de apps nunca ve.","platform",[532],"Android Open Source Project",[534],{"kind":535,"url":536},"website","https:\u002F\u002Fsource.android.com\u002F",[538],"host-card-emulation","\u002Fglossary#aosp",false,{"slug":542,"term":543,"definition":544,"category":545,"aliases":546,"links":551,"related":555,"readMore":-1,"target":557,"hasArticle":540},"object-storage","Almacenamiento de objetos","Almacenamiento que guarda un archivo entero bajo una clave en vez de en un árbol de directorios: Amazon S3 y los muchos servicios que hablan su API. Barato, casi ilimitado y el hogar habitual de eventos en bruto, backups y multimedia: se escriben una vez, se leen poco y se guardan para siempre.","architecture",[547,548,549,550],"S3","almacenamiento compatible con S3","object storage","blob storage",[552],{"kind":553,"url":554},"wikipedia","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FObject_storage",[556],"bigquery","\u002Fglossary#object-storage",{"slug":559,"term":560,"definition":561,"category":562,"aliases":563,"links":568,"related":569,"readMore":-1,"target":572,"hasArticle":540},"staff-augmentation","Ampliación de equipo","Un modelo de contratación en el que ingenieros de un socio externo se suman a tu equipo y trabajan bajo tu gestión —en tu repositorio, tus sprints, tu proceso— en vez de entregar un proyecto propio. Compras capacidad; el código y el contexto se quedan contigo.","business",[564,565,566,567],"staff augmentation","team augmentation","desarrolladores dedicados","outstaffing",[],[570,571],"total-cost-of-ownership","time-to-market","\u002Fglossary#staff-augmentation",{"slug":574,"term":575,"definition":576,"category":530,"aliases":577,"links":578,"related":582,"readMore":-1,"target":584,"hasArticle":540},"app-clips","App Clips","Una función de Apple que ejecuta una porción pequeña de una app de iOS —menos de 15 MB— sin instalarla entera. Se invoca desde un código QR, una etiqueta NFC o un enlace, para cuando lo primero que hace un usuario no debería exigir pasar por la tienda.",[],[579],{"kind":580,"url":581},"documentation","https:\u002F\u002Fdeveloper.apple.com\u002Fapp-clips\u002F",[399,583],"install-referrer","\u002Fglossary#app-clips",{"slug":556,"term":586,"definition":587,"category":530,"aliases":588,"links":589,"related":594,"readMore":-1,"target":596,"hasArticle":540},"BigQuery","El almacén analítico de Google Cloud. Le lanzas SQL a miles de millones de filas y las recorre en segundos, sobre un almacenamiento separado de las máquinas que consultan, que es lo que mantiene los informes y la exploración fuera de la base de datos que sirve tráfico real.",[],[590,592],{"kind":535,"url":591},"https:\u002F\u002Fcloud.google.com\u002Fbigquery",{"kind":553,"url":593},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBigQuery",[542,595],"elasticsearch","\u002Fglossary#bigquery",{"slug":335,"term":598,"definition":599,"category":600,"aliases":601,"links":605,"related":608,"readMore":-1,"target":609,"hasArticle":540},"CI\u002FCD","Automatización que compila, testea y publica cada cambio sin que nadie ejecute comandos a mano. En móvil es lo que convierte una release en pulsar un botón en lugar de en una tarde esperando a que alguien esté disponible.","practice",[602,603,604],"CI","integración continua","entrega continua",[606],{"kind":553,"url":607},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCI\u002FCD",[],"\u002Fglossary#ci-cd",{"slug":611,"term":612,"definition":613,"category":545,"aliases":614,"links":618,"related":621,"readMore":-1,"target":624,"hasArticle":540},"headless-cms","CMS headless","Un sistema de contenidos con editor y API pero sin frontend propio. Los editores publican en un solo sitio y el sitio web o la app renderizan ese contenido por su cuenta, así que la capa de presentación es tuya y no del proveedor del CMS.",[615,616,617],"headless CMS","gestor de contenidos headless","API de contenidos",[619],{"kind":553,"url":620},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHeadless_content_management_system",[622,623],"server-side-rendering","rest","\u002Fglossary#headless-cms",{"slug":626,"term":627,"definition":628,"category":545,"aliases":629,"links":632,"related":635,"readMore":-1,"target":637,"hasArticle":540},"crud","CRUD","Create, read, update, delete: las cuatro operaciones detrás de casi todo formulario y pantalla de administración. Nombre corto para la mitad rutinaria de una app, la que gestiona datos, frente a la que lleva la lógica de dominio.",[630,631],"Create, Read, Update, Delete","crear, leer, actualizar, borrar",[633],{"kind":553,"url":634},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCreate,_read,_update_and_delete",[623,636],"graphql","\u002Fglossary#crud",{"slug":639,"term":640,"definition":641,"category":545,"aliases":642,"links":646,"related":649,"readMore":-1,"target":652,"hasArticle":540},"end-to-end-encryption","Cifrado de extremo a extremo","Cifrado aplicado en el dispositivo que envía y deshecho solo en el que recibe, de modo que el servicio que transporta el mensaje no puede leerlo: ni por orden judicial ni tras una brecha. Protege el contenido y nunca los metadatos.",[643,644,645],"E2EE","cifrado extremo a extremo","end-to-end encryption",[647],{"kind":553,"url":648},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FEnd-to-end_encryption",[650,651],"tls","jwt","\u002Fglossary#end-to-end-encryption",{"slug":654,"term":655,"definition":656,"category":545,"aliases":657,"links":661,"related":664,"readMore":-1,"target":665,"hasArticle":540},"floating-point","Coma flotante","El formato binario IEEE 754 detrás de double y float. No puede representar 0,1 de forma exacta, así que 0,1 + 0,2 da 0,30000000000000004: invisible en gráficos y fatal en dinero, que va en unidades menores enteras o en un tipo decimal.",[658,659,660],"IEEE 754","double","aritmética de coma flotante",[662],{"kind":553,"url":663},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIEEE_754",[],"\u002Fglossary#floating-point",{"slug":667,"term":668,"definition":669,"category":562,"aliases":670,"links":675,"related":678,"readMore":-1,"target":680,"hasArticle":540},"in-app-purchase","Compra dentro de la app","Vender bienes digitales o una suscripción a través de la facturación de Apple o Google, obligatoria para contenido digital en ambas tiendas y sujeta a comisión. Lo difícil nunca es la compra: es restaurarla en un dispositivo nuevo y mantener honesto el estado de los derechos.",[671,672,673,674],"IAP","in-app purchase","compras integradas","suscripción in-app",[676],{"kind":580,"url":677},"https:\u002F\u002Fdeveloper.apple.com\u002Fin-app-purchase\u002F",[679],"product-market-fit","\u002Fglossary#in-app-purchase",{"slug":570,"term":682,"definition":683,"category":562,"aliases":684,"links":688,"related":691,"readMore":-1,"target":692,"hasArticle":540},"Coste total de propiedad","Lo que cuesta un producto a lo largo de toda su vida, no solo construirlo: mantenimiento, actualizaciones, migraciones anuales de SO y de tiendas, y el segundo equipo que contratas para mantener dos bases de código alineadas. Suele superar al presupuesto de desarrollo, y casi nunca va dentro.",[685,686,687],"TCO","total cost of ownership","coste de propiedad",[689],{"kind":553,"url":690},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTotal_cost_of_ownership",[571],"\u002Fglossary#total-cost-of-ownership",{"slug":694,"term":695,"definition":696,"category":697,"aliases":698,"links":701,"related":704,"readMore":-1,"target":705,"hasArticle":540},"post-quantum-cryptography","Criptografía poscuántica","Algoritmos de cifrado pensados para resistir a un futuro ordenador cuántico, ya estandarizados por el NIST. La migración urge antes que el hardware: el tráfico capturado hoy puede descifrarse cuando esa máquina exista.","protocol",[699,700],"PQC","cifrado poscuántico",[702],{"kind":553,"url":703},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPost-quantum_cryptography",[650,639],"\u002Fglossary#post-quantum-cryptography",{"slug":399,"term":707,"definition":708,"category":530,"aliases":709,"links":713,"related":716,"readMore":717,"target":717,"hasArticle":516},"Deep linking","Un enlace que abre una pantalla concreta dentro de una app instalada en vez de su pantalla de inicio o una página web. El deep linking diferido sobrevive a la instalación, así que un toque que pasa por la tienda acaba igualmente en la pantalla correcta.",[404,710,711,712],"enlaces profundos","universal links","Android App Links",[714],{"kind":553,"url":715},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMobile_deep_linking",[574,583],"\u002Fglossary\u002Fdeep-linking",{"slug":719,"term":720,"definition":721,"category":600,"aliases":722,"links":726,"related":727,"readMore":-1,"target":729,"hasArticle":540},"staged-rollout","Despliegue escalonado","Publicar una build primero a un porcentaje pequeño de usuarios y ampliarlo solo cuando la tasa sin fallos aguanta. Una build mala detectada al diez por ciento es una tarde mala; esa misma build al cien por cien es una semana mala.",[723,724,725],"staged rollout","lanzamiento por fases","release canaria",[],[728,335],"feature-flags","\u002Fglossary#staged-rollout",{"slug":731,"term":732,"definition":733,"category":600,"aliases":734,"links":739,"related":744,"readMore":-1,"target":746,"hasArticle":540},"dev-container","Dev Container","Un entorno de desarrollo descrito una sola vez en devcontainer.json —el SO, las herramientas y las versiones de runtime que un proyecto necesita— y abierto de forma idéntica en un contenedor por el editor de cada colaborador, en vez de una guía que cada quien interpreta a su manera.",[735,736,737,738],"devcontainer.json","Dev Containers","VS Code Dev Containers","contenedor de desarrollo",[740,742],{"kind":535,"url":741},"https:\u002F\u002Fcontainers.dev\u002F",{"kind":580,"url":743},"https:\u002F\u002Fcode.visualstudio.com\u002Fdocs\u002Fdevcontainers\u002Fcontainers",[745],"container-registry","\u002Fglossary#dev-container",{"slug":595,"term":748,"definition":749,"category":530,"aliases":750,"links":753,"related":758,"readMore":-1,"target":759,"hasArticle":540},"Elasticsearch","Un motor de búsqueda y analítica que indexa registros para poder filtrarlos y buscarlos de forma interactiva en vez de recorrerlos. Lo que usas cuando la pregunta es «enséñame estas sesiones concretas, filtradas de seis maneras» y no «suma esta columna».",[751,752],"Elastic","ELK",[754,756],{"kind":535,"url":755},"https:\u002F\u002Fwww.elastic.co\u002Felasticsearch",{"kind":553,"url":757},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FElasticsearch",[556],"\u002Fglossary#elasticsearch",{"slug":679,"term":761,"definition":762,"category":562,"aliases":763,"links":767,"related":770,"readMore":-1,"target":772,"hasArticle":540},"Encaje producto-mercado","El punto en el que un producto ha encontrado de forma demostrable a gente que lo quiere: lo usa, vuelve y paga. Antes de eso la ingeniería responde a una pregunta; después, responde a la demanda.",[764,765,766],"PMF","product-market fit","product\u002Fmarket fit",[768],{"kind":553,"url":769},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FProduct-market_fit",[771,571],"mvp","\u002Fglossary#product-market-fit",{"slug":774,"term":775,"definition":776,"category":545,"aliases":777,"links":780,"related":781,"readMore":-1,"target":785,"hasArticle":540},"fan-out","Fan-out","Leer una fuente una sola vez y entregar cada actualización a todos los clientes suscritos. La versión ingenua escribe a los suscriptores en un bucle y se atasca en cuanto un socket va lento; una real usa un búfer por cliente y descarta a quien no siga el ritmo.",[778,779],"fanout","difusión",[],[782,783,784],"websocket","pub-sub","server-sent-events","\u002Fglossary#fan-out",{"slug":728,"term":787,"definition":788,"category":600,"aliases":789,"links":793,"related":796,"readMore":-1,"target":798,"hasArticle":540},"Feature flags","Interruptores que activan o desactivan funcionalidad desde la configuración y no desde una release. Permiten que un mismo binario se comporte distinto por marca, mercado o usuario, y apagar una función arriesgada sin pasar una build nueva por revisión.",[790,791,792],"feature flag","feature toggle","banderas de funcionalidad",[794],{"kind":553,"url":795},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFeature_toggle",[719,193,797],"multi-tenancy","\u002Fglossary#feature-flags",{"slug":800,"term":801,"definition":802,"category":545,"aliases":803,"links":807,"related":810,"readMore":-1,"target":812,"hasArticle":540},"state-management","Gestión de estado","Cómo decide una app dónde vive un valor, quién puede cambiarlo y qué partes de la pantalla se redibujan cuando lo hace. En Flutter, elegir entre Riverpod, BLoC y Provider es de las primeras decisiones arquitectónicas y de las más difíciles de revisar.",[804,805,806],"state management","BLoC","Riverpod",[808],{"kind":580,"url":809},"https:\u002F\u002Fdocs.flutter.dev\u002Fdata-and-backend\u002Fstate-mgmt\u002Foptions",[811],"golden-test","\u002Fglossary#state-management",{"slug":811,"term":814,"definition":815,"category":600,"aliases":816,"links":820,"related":823,"readMore":-1,"target":824,"hasArticle":540},"Golden test","Un test que renderiza un widget y compara el resultado píxel a píxel con una imagen de referencia guardada. En Flutter es la forma más barata de saber si un rediseño rompió el estado vacío a 320 pt, en modo oscuro y con el texto al 200 %.",[817,818,819],"golden tests","test de captura","snapshot test",[821],{"kind":580,"url":822},"https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fflutter_test\u002FmatchesGoldenFile.html",[335],"\u002Fglossary#golden-test",{"slug":636,"term":826,"definition":827,"category":545,"aliases":828,"links":829,"related":834,"readMore":-1,"target":835,"hasArticle":540},"GraphQL","Un lenguaje de consulta para APIs donde el cliente nombra exactamente los campos que quiere y recibe una única respuesta con esa forma. Elimina el exceso de datos al que derivan los endpoints REST y añade un fallo propio: una consulta sin límites que recorre todo el modelo.",[],[830,832],{"kind":535,"url":831},"https:\u002F\u002Fgraphql.org\u002F",{"kind":553,"url":833},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGraphQL",[623],"\u002Fglossary#graphql",{"slug":837,"term":838,"definition":839,"category":600,"aliases":840,"links":842,"related":845,"readMore":-1,"target":849,"hasArticle":540},"hipaa","HIPAA","La ley estadounidense que regula la información sanitaria protegida: cómo puede almacenarse, transmitirse, registrarse y divulgarse. Como PCI-DSS, es una restricción arquitectónica que se elige al principio, no un documento de políticas que se añade antes del lanzamiento.",[841],"Health Insurance Portability and Accountability Act",[843],{"kind":553,"url":844},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHealth_Insurance_Portability_and_Accountability_Act",[846,847,848],"pci-dss","gdpr","soc-2","\u002Fglossary#hipaa",{"slug":538,"term":851,"definition":852,"category":530,"aliases":853,"links":857,"related":860,"readMore":-1,"target":861,"hasArticle":540},"Host Card Emulation","Permitir que un móvil Android actúe por software como una tarjeta contactless sobre NFC, sin elemento seguro por hardware. Es así como paga una app de wallet en un terminal: el teléfono habla el mismo protocolo EMV contactless que habría hablado la tarjeta de plástico.",[854,855,856],"HCE","EMV Contactless","pagos contactless",[858],{"kind":580,"url":859},"https:\u002F\u002Fdeveloper.android.com\u002Fdevelop\u002Fconnectivity\u002Fnfc\u002Fhce",[846,527],"\u002Fglossary#host-card-emulation",{"slug":863,"term":864,"definition":865,"category":545,"aliases":866,"links":870,"related":873,"readMore":-1,"target":874,"hasArticle":540},"multi-arch-image","Imagen multiarquitectura","Una única etiqueta de imagen que resuelve a binarios distintos según la arquitectura de CPU —linux\u002Famd64 y linux\u002Farm64 son el par habitual—, de modo que el mismo docker pull funciona sin cambios tanto en servidores Intel\u002FAMD como en portátiles con Apple Silicon.",[867,868,869],"build multiarquitectura","multi-arch build","linux\u002Famd64 + linux\u002Farm64",[871],{"kind":580,"url":872},"https:\u002F\u002Fdocs.docker.com\u002Fbuild\u002Fbuilding\u002Fmulti-platform\u002F",[745],"\u002Fglossary#multi-arch-image",{"slug":876,"term":877,"definition":878,"category":530,"aliases":879,"links":880,"related":883,"readMore":-1,"target":885,"hasArticle":540},"impeller","Impeller","El motor de renderizado que usa Flutter hoy, por defecto en iOS desde 2023 y en Android desde 2024. Compila sus shaders por adelantado en lugar de durante la primera animación, lo que eliminó el jank de shaders, el problema más visible de Flutter en producción.",[],[881],{"kind":580,"url":882},"https:\u002F\u002Fdocs.flutter.dev\u002Fperf\u002Fimpeller",[884],"skia","\u002Fglossary#impeller",{"slug":583,"term":887,"definition":888,"category":530,"aliases":889,"links":890,"related":893,"readMore":-1,"target":894,"hasArticle":540},"Install Referrer","Una API de Google Play que entrega a una app Android recién instalada los parámetros de campaña del enlace que llevó a la instalación. La mitad Android del deep linking diferido y la forma fiable de atribuir de dónde viene un usuario.",[],[891],{"kind":580,"url":892},"https:\u002F\u002Fdeveloper.android.com\u002Fgoogle\u002Fplay\u002Finstallreferrer",[399,574],"\u002Fglossary#install-referrer",{"slug":896,"term":897,"definition":898,"category":600,"aliases":899,"links":902,"related":905,"readMore":-1,"target":907,"hasArticle":540},"prompt-injection","Inyección de prompts","Un ataque en el que el texto que aporta un usuario lo lee un modelo de lenguaje como instrucciones y no como datos, desviándolo de sus propias reglas. El hermano de la inyección SQL en la era de los LLM, y aparece donde se concatena entrada de usuario en un prompt.",[900,901],"prompt injection","ataque de inyección",[903],{"kind":553,"url":904},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPrompt_injection",[906],"rate-limiting","\u002Fglossary#prompt-injection",{"slug":651,"term":909,"definition":910,"category":697,"aliases":911,"links":913,"related":918,"readMore":-1,"target":919,"hasArticle":540},"JWT","Un token firmado que lleva sus propios claims, de modo que un servidor puede saber a quién pertenece una petición sin consultar una sesión. Estándar para la autenticación móvil. La firma prueba que no se alteró; no oculta lo que hay dentro.",[912],"JSON Web Token",[914,916],{"kind":535,"url":915},"https:\u002F\u002Fjwt.io\u002F",{"kind":553,"url":917},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJSON_Web_Token",[846],"\u002Fglossary#jwt",{"slug":921,"term":922,"definition":923,"category":600,"aliases":924,"links":929,"related":932,"readMore":-1,"target":933,"hasArticle":540},"kyc","KYC","Know Your Customer: las verificaciones de identidad que hace un producto financiero regulado antes de dejar mover dinero —captura de documentos, prueba de vida, listas de sanciones y control antiblanqueo—. Condiciona el onboarding más que cualquier decisión de diseño.",[925,926,927,928],"Know Your Customer","AML","KYC\u002FAML","conocimiento del cliente",[930],{"kind":553,"url":931},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FKnow_your_customer",[846,847],"\u002Fglossary#kyc",{"slug":76,"term":74,"definition":935,"category":530,"aliases":936,"links":938,"related":939,"readMore":940,"target":940,"hasArticle":540},"Compartir lógica de negocio escrita en Kotlin entre Android, iOS y el servidor mientras cada plataforma conserva su UI nativa. La alternativa a Flutter cuando la interfaz tiene que ser nativa pero las reglas que hay detrás no.",[937],"KMP",[],[],"\u002Ftechnologies\u002Fkmp",{"slug":906,"term":942,"definition":943,"category":600,"aliases":944,"links":948,"related":951,"readMore":-1,"target":952,"hasArticle":540},"Limitación de tasa","Un tope de cuántas peticiones puede hacer un mismo cliente en una ventana de tiempo. Es lo que impide que un usuario entusiasta, un scraper o un bot se gaste en una tarde un mes de presupuesto de API, y tiene que vivir en tu lado de la integración.",[945,946,947],"rate limiting","rate limit","throttling",[949],{"kind":553,"url":950},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRate_limiting",[896],"\u002Fglossary#rate-limiting",{"slug":771,"term":954,"definition":955,"category":562,"aliases":956,"links":959,"related":962,"readMore":-1,"target":963,"hasArticle":540},"MVP","La versión más pequeña de un producto que puede ponerse delante de usuarios reales y aun así responder la pregunta por la que lo construiste. Una decisión sobre alcance, no sobre calidad: un MVP también tiene que funcionar.",[957,958],"producto mínimo viable","minimum viable product",[960],{"kind":553,"url":961},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMinimum_viable_product",[193],"\u002Fglossary#mvp",{"slug":193,"term":965,"definition":966,"category":562,"aliases":967,"links":970,"related":973,"readMore":974,"target":974,"hasArticle":516},"Marca blanca","Un mismo producto publicado bajo muchas marcas. Una plataforma móvil de marca blanca construye para cada cliente una app lista para la tienda con su nombre, su diseño y su contenido desde una única base de código compartida, en vez de forkear el proyecto por cliente.",[193,968,969],"white label","app multiinquilino",[971],{"kind":553,"url":972},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWhite-label_product",[771],"\u002Fglossary\u002Fwhite-label",{"slug":797,"term":976,"definition":977,"category":545,"aliases":978,"links":982,"related":985,"readMore":-1,"target":986,"hasArticle":540},"Multi-tenancy","Un solo despliegue que sirve a muchos clientes, cada uno viendo solo sus datos, su configuración y sus funciones activas porque el contexto de tenant se resuelve en cada petición. Es lo que hace que una flota de apps de marca sea un producto y no muchos forks.",[979,980,981],"multi-tenant","multiinquilino","tenant",[983],{"kind":553,"url":984},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMultitenancy",[193,728],"\u002Fglossary#multi-tenancy",{"slug":988,"term":989,"definition":990,"category":697,"aliases":991,"links":995,"related":1000,"readMore":-1,"target":1001,"hasArticle":540},"oauth","OAuth","El estándar detrás de Iniciar sesión con Apple, con Google y demás: el usuario autoriza tu app en un proveedor en el que ya confía y tu app recibe un token en lugar de su contraseña. Nadie inventa una credencial nueva y tú nunca almacenas ninguna.",[992,993,994],"OAuth 2.0","login social","Iniciar sesión con Apple",[996,998],{"kind":535,"url":997},"https:\u002F\u002Foauth.net\u002F2\u002F",{"kind":553,"url":999},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FOAuth",[651],"\u002Fglossary#oauth",{"slug":846,"term":1003,"definition":1004,"category":600,"aliases":1005,"links":1008,"related":1013,"readMore":-1,"target":1014,"hasArticle":540},"PCI-DSS","El estándar de seguridad del sector de tarjetas que obliga a quien almacena, procesa o transmite datos de tarjeta. La mayoría de las apps se mantienen fuera de su alcance a propósito, delegando la introducción de la tarjeta en un proveedor de pagos certificado.",[1006,1007],"PCI DSS","Payment Card Industry Data Security Standard",[1009,1011],{"kind":535,"url":1010},"https:\u002F\u002Fwww.pcisecuritystandards.org\u002F",{"kind":553,"url":1012},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPayment_Card_Industry_Data_Security_Standard",[651],"\u002Fglossary#pci-dss",{"slug":1016,"term":1017,"definition":1018,"category":530,"aliases":1019,"links":1023,"related":1026,"readMore":-1,"target":1027,"hasArticle":540},"platform-channels","Platform channels","El puente que usa una app Flutter para llamar a código nativo de iOS y Android: Keychain y Keystore, biometría, hojas de pago, cualquier SDK sin paquete de Dart. Trabajo rutinario pero real, y lo primero donde encalla quien nunca salió de Dart.",[1020,1021,1022],"platform channel","method channel","canales de plataforma",[1024],{"kind":580,"url":1025},"https:\u002F\u002Fdocs.flutter.dev\u002Fplatform-integration\u002Fplatform-channels",[76],"\u002Fglossary#platform-channels",{"slug":783,"term":1029,"definition":1030,"category":545,"aliases":1031,"links":1035,"related":1038,"readMore":-1,"target":1039,"hasArticle":540},"Pub\u002FSub","Un patrón de mensajería donde un productor publica un evento y cualquier número de consumidores lo lee de forma independiente, con un broker en medio. El productor nunca los espera, y así la ruta de la petición sigue siendo rápida mientras el trabajo lento ocurre detrás.",[1032,1033,1034],"publicación\u002Fsuscripción","publish\u002Fsubscribe","Google Cloud Pub\u002FSub",[1036],{"kind":553,"url":1037},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPublish%E2%80%93subscribe_pattern",[],"\u002Fglossary#pub-sub",{"slug":623,"term":1041,"definition":1042,"category":545,"aliases":1043,"links":1046,"related":1049,"readMore":-1,"target":1050,"hasArticle":540},"REST","El estilo convencional de las APIs HTTP: una URL nombra un recurso y el verbo HTTP dice qué hacer con él. La forma por defecto en que una app habla con un backend, y lo que esperan encontrar la mayoría de integraciones de terceros.",[1044,1045],"API REST","Representational State Transfer",[1047],{"kind":553,"url":1048},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FREST",[782,784],"\u002Fglossary#rest",{"slug":847,"term":1052,"definition":1053,"category":600,"aliases":1054,"links":1058,"related":1063,"readMore":-1,"target":1064,"hasArticle":540},"RGPD","El reglamento de la UE sobre los datos personales de las personas en la UE: una base legal para recogerlos, consentimiento real para el rastreo y derechos de acceso y supresión. Sigue a tus usuarios, no a tus servidores, así que se aplica esté donde esté la empresa.",[1055,1056,1057],"GDPR","Reglamento General de Protección de Datos","protección de datos",[1059,1061],{"kind":535,"url":1060},"https:\u002F\u002Fgdpr.eu\u002F",{"kind":553,"url":1062},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGeneral_Data_Protection_Regulation",[846,848,837],"\u002Fglossary#gdpr",{"slug":745,"term":1066,"definition":1067,"category":545,"aliases":1068,"links":1074,"related":1077,"readMore":-1,"target":1078,"hasArticle":540},"Registro de contenedores","Almacenamiento alojado para imágenes de contenedores, direccionadas por nombre y etiqueta: Docker Hub, GitHub Container Registry o el propio de un proveedor cloud. Publicar una build ahí convierte 'funciona en mi máquina' en una imagen que cualquiera puede descargar y ejecutar sin cambios.",[1069,1070,1071,1072,1073],"registro de imágenes","Docker registry","GHCR","ghcr.io","container registry",[1075],{"kind":580,"url":1076},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fpackages\u002Fworking-with-a-github-packages-registry\u002Fworking-with-the-container-registry",[731,863],"\u002Fglossary#container-registry",{"slug":622,"term":1080,"definition":1081,"category":545,"aliases":1082,"links":1086,"related":1089,"readMore":-1,"target":1090,"hasArticle":540},"Renderizado en servidor","Construir una página como HTML terminado en el servidor, de modo que la primera respuesta ya lleva el contenido, los encabezados, las metaetiquetas y los datos estructurados. Los rastreadores, las vistas previas de enlaces y los dispositivos lentos lo leen sin ejecutar JavaScript.",[1083,1084,1085],"SSR","server-side rendering","renderizado del lado del servidor",[1087],{"kind":553,"url":1088},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FServer-side_scripting",[611],"\u002Fglossary#server-side-rendering",{"slug":848,"term":1092,"definition":1093,"category":600,"aliases":1094,"links":1097,"related":1100,"readMore":-1,"target":1101,"hasArticle":540},"SOC 2","Un informe de auditoría externa sobre cómo trata una organización los datos de clientes —seguridad, disponibilidad, confidencialidad— y no un certificado que se compra. Los clientes empresariales lo piden, y condiciona la arquitectura mucho antes que la propia auditoría.",[1095,1096],"SOC2","System and Organization Controls",[1098],{"kind":553,"url":1099},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSystem_and_Organization_Controls",[846,847,837],"\u002Fglossary#soc-2",{"slug":1103,"term":1104,"definition":1105,"category":562,"aliases":1106,"links":1109,"related":1112,"readMore":-1,"target":1113,"hasArticle":540},"saas","SaaS","Software vendido como suscripción continua a un producto alojado, en lugar de como una licencia única que el cliente instala y opera. El proveedor mantiene los servidores, publica actualizaciones sin parar y cobra por usuario o por uso.",[1107,1108],"Software as a Service","software como servicio",[1110],{"kind":553,"url":1111},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSoftware_as_a_service",[797,193],"\u002Fglossary#saas",{"slug":784,"term":1115,"definition":1116,"category":697,"aliases":1117,"links":1120,"related":1123,"readMore":-1,"target":1124,"hasArticle":540},"Server-Sent Events","Un flujo unidireccional del servidor al cliente sobre una conexión HTTP corriente. Más simple que un WebSocket y suficiente allí donde solo el servidor tiene algo que decir: un feed de progreso, o una respuesta de IA que llega token a token.",[1118,1119],"SSE","eventos enviados por el servidor",[1121],{"kind":553,"url":1122},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FServer-sent_events",[782,623],"\u002Fglossary#server-sent-events",{"slug":884,"term":1126,"definition":1127,"category":530,"aliases":1128,"links":1131,"related":1136,"readMore":-1,"target":1137,"hasArticle":540},"Skia","La librería gráfica 2D de código abierto de Google que dibuja Chrome, Android y —hasta Impeller— cada fotograma de Flutter. Renderiza tanto a PDF como a pantalla, que es lo que hace la función de imprimir a PDF de Chrome.",[1129,1130],"Skia Graphics Engine","skia-safe",[1132,1134],{"kind":535,"url":1133},"https:\u002F\u002Fskia.org\u002F",{"kind":553,"url":1135},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSkia_Graphics_Engine",[876],"\u002Fglossary#skia",{"slug":650,"term":1139,"definition":1140,"category":697,"aliases":1141,"links":1145,"related":1148,"readMore":-1,"target":1149,"hasArticle":540},"TLS","La capa de cifrado bajo HTTPS. Demuestra que el servidor es quien dice su certificado, acuerda una clave nueva para la sesión y cifra todo lo demás, de modo que la red intermedia solo ve texto cifrado que no puede alterar sin que se note.",[1142,1143,1144],"SSL","HTTPS","Transport Layer Security",[1146],{"kind":553,"url":1147},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTransport_Layer_Security",[639,651],"\u002Fglossary#tls",{"slug":571,"term":1151,"definition":1152,"category":562,"aliases":1153,"links":1156,"related":1159,"readMore":-1,"target":1160,"hasArticle":540},"Time to market","Cuánto se tarda en llevar un producto desde la decisión hasta usuarios reales. Casi todas las discusiones sobre stack y alcance son en realidad discusiones sobre este número, porque cada semana ahorrada es una semana de ingresos, feedback y posición competitiva.",[1154,1155],"TTM","tiempo de salida al mercado",[1157],{"kind":553,"url":1158},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTime_to_market",[771,570],"\u002Fglossary#time-to-market",{"slug":1162,"term":1163,"definition":1164,"category":697,"aliases":1165,"links":1167,"related":1172,"readMore":-1,"target":1174,"hasArticle":540},"webrtc","WebRTC","El estándar de navegador y móvil para enviar audio, vídeo y datos directamente entre dos dispositivos, con los servidores implicados solo en presentarlos entre sí. Es sobre lo que se construye una videollamada dentro de una app cuando no es un SDK alquilado.",[1166],"Web Real-Time Communication",[1168,1170],{"kind":535,"url":1169},"https:\u002F\u002Fwebrtc.org\u002F",{"kind":553,"url":1171},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWebRTC",[1173,782],"xmpp","\u002Fglossary#webrtc",{"slug":782,"term":1176,"definition":1177,"category":697,"aliases":1178,"links":1179,"related":1182,"readMore":-1,"target":1183,"hasArticle":540},"WebSocket","Un protocolo que mantiene una conexión abierta entre cliente y servidor para que cualquiera de los dos pueda enviar en cualquier momento, en vez de que el cliente pregunte una y otra vez. Sobre esto funcionan los precios en vivo, el chat y los indicadores de presencia.",[],[1180],{"kind":553,"url":1181},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWebSocket",[784,623],"\u002Fglossary#websocket",{"slug":1173,"term":1185,"definition":1186,"category":697,"aliases":1187,"links":1190,"related":1195,"readMore":-1,"target":1196,"hasArticle":540},"XMPP","Un protocolo de mensajería abierto y federado, y la alternativa de siempre a escribir un backend de chat o alquilarlo. Se extiende a presencia, indicadores de escritura y transferencia de archivos, y es lo bastante antiguo como para que cada plataforma tenga una librería madura.",[1188,1189],"Jabber","Extensible Messaging and Presence Protocol",[1191,1193],{"kind":535,"url":1192},"https:\u002F\u002Fxmpp.org\u002F",{"kind":553,"url":1194},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FXMPP",[1162,782],"\u002Fglossary#xmpp"]