Bienvenido al repositorio oficial de la aplicación móvil y web del Museo Histórico Padre Suárez. Esta aplicación ha sido desarrollada en Flutter y cuenta con funcionalidades avanzadas como experiencias en Realidad Aumentada (AR), modelos 3D, entornos en 360 grados, tienda de merchandising, gamificación (insignias y trofeos) y gestión de usuarios mediante Firebase.
Este documento explica paso a paso cómo configurar este proyecto desde cero, incluso si no sabes programar, para que puedas compilarlo y hacerlo funcionar en tu propio ordenador o publicarlo en las tiendas de aplicaciones.
Aquí puedes encontrar acceso directo a toda la infraestructura y documentación del proyecto:
- 🌍 Web de Documentación (GDD/TDD): museo-padre-suarez.infinityfreeapp.com
- 🚀 Prototipo Interactivo (Stitch): Ver Diseño en Stitch
- 📋 Gestión del Proyecto (Trello): Consultar Backlog en Trello
- 💻 Repositorio de Código: GitHub Repo
- Museo Histórico Padre Suárez - App 🏛️
- 🌐 Enlaces del Proyecto
- 📋 Índice
- 1. Requisitos Previos
- 2. Configuración del Archivo
.env - 3. Configuración de Firebase (Base de Datos y Usuarios)
- 4. Configuración de EmailJS (Correos Automáticos)
- 5. Configuración de Pagos Reales (Stripe)
- 6. Configuración de Activos Digitales (Cloudinary DAM)
- 7. Códigos QR para las Piezas del Museo
- 8. Lanzar la Aplicación
- 9. 🎮 MODO TESTER (Para Tribunal y Exposiciones sin Gasto)
- 11. 🛒 Ecosistema de Comercio y Producción 3D
- 12. ✨ Características de Pulido Comercial
Para ejecutar este proyecto en tu ordenador, necesitas instalar:
- Flutter SDK: El motor sobre el que está construida la app (Versión 3.24+ recomendada).
- Android Studio / Visual Studio Code: Para abrir el código y compilar la app.
- Java 17+: Necesario para las versiones modernas de Gradle y AndroidX que utiliza el proyecto.
- Git: Para descargar el repositorio.
La app utiliza un archivo secreto llamado .env para almacenar contraseñas y claves de conexión a servicios externos (Firebase, Correos, Pagos). Este archivo NUNCA se sube a internet por seguridad.
- En la carpeta principal del proyecto (donde estás leyendo esto), busca un archivo llamado
.env.example. - Haz una copia de ese archivo y renómbralo a exactamente
.env(con el punto delante y sin nada más). - Abre este nuevo archivo
.envcon el Bloc de notas o tu editor de código. A continuación aprenderemos de dónde sacar cada clave para rellenarlo.
Resumen de todas las variables:
| Variable | Descripción |
|---|---|
FIREBASE_API_KEY |
Clave API Firebase (Web) |
FIREBASE_APP_ID_WEB |
App ID Firebase Web |
FIREBASE_APP_ID_ANDROID |
App ID Firebase Android |
FIREBASE_MEASUREMENT_ID_WEB |
ID Analytics Firebase |
FIREBASE_PROJECT_ID |
ID del proyecto Firebase |
FIREBASE_MESSAGING_SENDER_ID |
Número de remitente Firebase |
FIREBASE_STORAGE_BUCKET |
Bucket de almacenamiento Firebase |
EMAILJS_SERVICE_ID |
ID de servicio EmailJS |
EMAILJS_TEMPLATE_ID |
Plantilla EmailJS para impresiones 3D |
EMAILJS_TICKET_TEMPLATE_ID |
Plantilla EmailJS para entradas digitales |
EMAILJS_USER_ID |
Clave pública de EmailJS |
ADMIN_EMAIL |
Correo(s) del administrador (separados por comas) |
STRIPE_SECRET_KEY |
Clave secreta Stripe (formato sk_test_...) |
GITHUB_RAW_URL |
URL raw de GitHub para modelos 3D (fallback) |
R2_PUBLIC_URL |
URL pública del bucket Cloudflare R2 (opcional) |
TESTER |
1 activa el Modo Tester (ver sección 8) |
GROQ_API_KEY |
Clave de API de Groq para el Asistente de IA |
Firebase es el servidor de Google que guarda los usuarios registrados, la colección de objetos que han desbloqueado y los administradores.
- Ve a Firebase Console e inicia sesión con una cuenta de Google.
- Haz clic en Añadir proyecto (Ej: "Museo App").
- Dentro del proyecto, busca la sección Authentication (Autenticación) en el menú izquierdo y actívala. Activa el proveedor de acceso por Correo electrónico y contraseña.
- Ve a Firestore Database en el menú izquierdo y haz clic en Crear base de datos (modo producción). Dirígete a la pestaña Reglas y pega exactamente el siguiente código para proteger la base de datos permitiendo lectura/escritura a los usuarios registrados:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 🛡️ Función Maestra de Administrador function isAdmin() { return request.auth != null && request.auth.token.email in [ "museosuarez443@gmail.com" ]; } // 👤 Perfiles de Usuario match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } // 🖨️ Solicitudes de Impresión match /print_requests/{document=**} { allow create: if request.auth != null; allow read, update, delete: if request.auth != null && (request.auth.uid == resource.data.userId || isAdmin()); } // 🎫 Tickets y Compras match /tickets/{document=**} { // Creación permitida a usuarios autenticados allow create: if request.auth != null; // Lectura permitida si eres el dueño (UID o Email) o eres Admin allow read: if request.auth != null && ( request.auth.uid == resource.data.userId || request.auth.token.email == resource.data.visitorEmail || isAdmin() ); // Actualización permitida al dueño (para cambiar fecha) o Admin allow update: if request.auth != null && ( request.auth.uid == resource.data.userId || request.auth.token.email == resource.data.visitorEmail || isAdmin() ); } // 🎧 Audio-guías match /audio_guides/{document=**} { allow read: if request.auth != null && ( request.auth.uid == resource.data.userId || request.auth.token.email == resource.data.userEmail || isAdmin() ); allow write: if isAdmin(); } } }
- Haz clic en el icono del engranaje ⚙️ (Configuración del proyecto) arriba a la izquierda.
- En la pestaña general, desplázate hacia abajo y añade dos aplicaciones a tu proyecto haciendo clic en los iconos:
- App Web: Registra una app web. Asegúrate de marcar la casilla "Configurar Firebase Hosting" si te lo pide, pero sobre todo, al terminar te dará un bloque de código al final. Copia el
apiKey, elappIdy elmeasurementId(si aparece) y ponlos en tu archivo.enven los apartadosFIREBASE_API_KEY_WEB,FIREBASE_APP_ID_WEByFIREBASE_MEASUREMENT_ID_WEB. Esto activará las analíticas web. - App Android: Registra una app Android (el nombre del paquete suele ser
com.example.flutter_application_museoo el que aparezca enandroid/app/build.gradle). Al terminar, la web te dará una clave API de Android y un ID de App. Pégalos enFIREBASE_API_KEY_ANDROIDyFIREBASE_APP_ID_ANDROID.
- App Web: Registra una app web. Asegúrate de marcar la casilla "Configurar Firebase Hosting" si te lo pide, pero sobre todo, al terminar te dará un bloque de código al final. Copia el
- En esa misma página de configuración, busca y copia el "ID de proyecto" (
FIREBASE_PROJECT_ID), el "Número de remitente" (FIREBASE_MESSAGING_SENDER_ID) y el "Depósito de almacenamiento" (FIREBASE_STORAGE_BUCKET). Pégalos en tu.env.
La app está preconfigurada de fábrica para enviar estadísticas de uso super completas a la pestaña Analytics de Firebase. Recopila automáticamente de Web, iOS y Android:
- Eventos de Sistema (Automáticos): Firebase rastrea instalaciones (
first_open), desinstalaciones en Android (app_remove), actualizaciones de la app (app_update) y tiempo de uso de la sesión (user_engagement). - Páginas Vistas (Automático): Sabrás qué pantallas se visitan más gracias al rastreador de
GoRouter. - Usuarios (
logLogin/logSignUp): Registra si la gente entra como anónimo o con correo. - AR y Escáner (
ar_scan_...):ar_scan_success: Registra qué pieza exacta ha sido visitada (Check-in físico) para aumentar el rango de explorador del usuario.ar_scan_error: Te avisa si la gente escanea códigos erróneos o ajenos al museo.ar_scan_simulated: Separa los escaneos de prueba que haces desde el simulador de PC.
- Exploración 3D y VR (
view_item_...):view_item_3d: Cuando cargan con éxito un modelo en el visor AR interactivo.view_item_360: Cuando abren un entorno inmersivo VR.
- Conversión y Tienda (
add_to_cart,_success,_error):add_to_cart: Guardará qué reproducciones físicas piden mediante el formulario del apartado Merchandising.donation_..._success/ticket_..._success: Sabrás si el usuario completó el flujo de pago con éxito usando dinero de verdad (stripe) o si fue una demo (mock).ecommerce_error: Se dispara de forma invisible si hay fallos en Firestore guardando un pedido físico.
🔐 Gestión Administrativa, Taquilla y Estadísticas La aplicación incluye un ecosistema de administración dinámico y profesional:
- Taquilla Digital (POS): Permite realizar ventas físicas en el museo integradas con el perfil digital del usuario.
- Sincronización por Email: Al introducir el correo en taquilla, el pedido (Tickets, 3D, Audioguías) aparece automáticamente en el perfil del usuario.
- Registro de Usuarios Express: Permite registrar nuevos usuarios desde la propia taquilla durante la venta.
- Gestión de Audioguías: Genera registros individuales para que cada visitante pueda usar su audioguía en su móvil.
- Panel de Estadísticas Inteligente (Real-time):
- Agregación Dual: Suma automáticamente las ventas web y las ventas de taquilla (integrando colecciones
ticketsypurchases). - Métricas Clave: Visualización en una sola línea de Ingresos Totales, Entradas Vendidas, Audioguías Entregadas e Impresiones 3D.
- Control de Producción: Seguimiento del estado de las impresiones 3D (Pendiente, Imprimiendo, Listo).
- Agregación Dual: Suma automáticamente las ventas web y las ventas de taquilla (integrando colecciones
- Admin Smart Scanner (v2026): Validación inteligente por colores:
- 🟢 Válida: Entrada para hoy, se marca como usada al instante.
- 🟠 Futuro: Detecta tickets para fechas próximas y avisa sin consumirlos.
- 🔴 Error: Alerta visual si el ticket ha caducado o ya fue validado.
- Control de Aforo y Grupos: Gestión de capacidad diaria y validación de reservas masivas con desglose de ítems (General, Estudiante, Audioguía).
- Cierre Maestro: Interruptor para abrir/cerrar el museo globalmente desde los ajustes.
- Seguridad Firestore: Reglas blindadas que solo permiten al administrador (
ADMIN_EMAIL) modificar la configuración.
Para que un usuario sea reconocido como administrador:
- El correo electrónico debe estar incluido en la variable
ADMIN_EMAILdel archivo.env. - La aplicación detectará automáticamente el rango de administrador y habilitará el botón "Gestión del Museo" en los ajustes.
La app envía correos reales (tickets digitales, avisos de impresión 3D) a los usuarios sin necesidad de un servidor complejo. Usamos EmailJS.
- Regístrate gratis en EmailJS.com.
- En la pestaña Email Services, añade tu correo electrónico personal (por ejemplo, Gmail) para que la app envíe correos a través de él. Te dará un
Service ID. Pégalo en el.envenEMAILJS_SERVICE_ID. - En Email Templates, crea dos plantillas:
- Plantilla 1 (Peticiones 3D): Crea una plantilla que reciba variables web. Anota su "Template ID" en
EMAILJS_TEMPLATE_ID.- Ejemplo de contenido de la plantilla:
Asunto: Solicitud de Impresión 3D: {{object_name}} Hola equipo, El usuario {{user_email}} ha solicitado la impresión 3D del objeto: {{object_name}}. Fecha de la solicitud: {{request_date}}
- Ejemplo de contenido de la plantilla:
- Plantilla 2 (Entradas Digitales): Ticket oficial premium con QR.
- Configuración del Asunto: Pon exactamente
{{subject}}en el campo "Subject" de EmailJS. - Código HTML Recomendado (Copiar y Pegar):
<div style="font-family: 'Segoe UI', Arial, sans-serif; background-color: #f4f6f9; padding: 40px 10px; text-align: center;"> <div style="max-width: 500px; margin: 0 auto; background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.05);"> <div style="background-color: #311b92; padding: 30px 20px;"> <h1 style="color: #ffffff; margin: 0; font-size: 24px;">MUSEO PADRE SUÁREZ</h1> <p style="color: #b39ddb; margin: 5px 0 0 0;">Entrada Oficial Digital</p> </div> <div style="padding: 40px 30px;"> <h2 style="color: #2c3e50;">¡Hola, {{name}}!</h2> <p style="color: #607d8b;">Presenta este código QR en el control de entrada:</p> <img src="{{qr_image_url}}" style="width: 200px; height: 200px; border: 4px solid #f4f6f9; padding: 10px; border-radius: 12px;"> <div style="margin-top: 20px; color: #607d8b; font-size: 14px;"> <p>ID: <strong>{{ticket_id}}</strong></p> <p>Fecha Visita: <strong>{{visit_date}}</strong></p> <p>Expedido: <strong>{{purchase_date}}</strong></p> </div> <div style="text-align: left; background-color: #f8f9fa; padding: 20px; border-radius: 12px; margin-top: 30px;"> <h3 style="color: #311b92; font-size: 16px;">Detalle de entradas:</h3> <p style="color: #2c3e50; font-size: 14px; white-space: pre-wrap;">{{tickets_details}}</p> </div> </div> </div> </div>
- Configuración del Asunto: Pon exactamente
- Plantilla 1 (Peticiones 3D): Crea una plantilla que reciba variables web. Anota su "Template ID" en
- Ve a la pestaña Account arriba a la derecha para ver tu "Public Key". Ese es tu
EMAILJS_USER_IDpara el.env.
La aplicación utiliza la API de Stripe para procesar todos los pagos y donaciones de forma unificada en todas las plataformas (Móvil, Web y PC).
- Crea una cuenta gratuita en Stripe.com.
- Accede a tu Panel de Control (Dashboard) y haz clic en la esquina superior derecha donde dice "Desarrolladores" o "Laves API" (API Keys).
- Asegúrate de tener activado el "Modo de Prueba" (un interruptor arriba a la derecha) para poder hacer compras falsas.
- En la pestaña de llaves API, busca tu Clave secreta (Secret Key). Tiene este formato:
sk_test_... - Cópiala y pégala en tu archivo
.envjusto aquí:STRIPE_SECRET_KEY=sk_test_abcd...
¡Y ya está! La aplicación generará una plataforma de pago virtual al vuelo redirigiendo al usuario para proteger sus datos, avisando al éxito para enviarle su Ticket por correo.
La aplicación gestiona automáticamente el catálogo de piezas y entornos inmersivos utilizando Cloudinary como Content Delivery Network (CDN) y sistema de almacenamiento.
- Crea una cuenta gratuita en Cloudinary.
- Obtén tu Cloud Name desde el Dashboard.
- Asegúrate de que los archivos (.glb y .jpg) en tu Media Library tengan nombres coincidentes con el
fileNamedefinido encatalog_metadata.json. - Configura la variable en tu archivo
.env:Nota: Ya no se requieren las claves de Supabase ni R2_PUBLIC_URL.CLOUDINARY_CLOUD_NAME=tu_cloud_name_aqui
La aplicación clasificará automáticamente los archivos: los .glb aparecerán en la sección 3D y las imágenes en la sección de Visitas Virtuales.
Esta sección explica cómo crear los códigos QR físicos que se colocan en cada vitrina. Al escanearlos con la app, el visitante desbloquea la pieza y ve el modelo 3D o el entorno 360° en su móvil.
El escáner de la app acepta dos formatos como contenido del QR:
| Formato | Ejemplo | Cuándo usarlo |
|---|---|---|
| ID de pieza | mandibula_hombre |
Recomendado — más corto |
| Nombre del fichero completo | mandibula_hombre.glb |
También válido |
⚠️ El ID de pieza es el nombre del fichero sin extensión, con espacios convertidos en guiones bajos (_). Si el fichero se llamamandibula hombre.glb, el ID esmandibula_hombre.
Supongamos que tienes estos archivos en tu repositorio o bucket R2:
| Archivo | Texto del QR |
|---|---|
mandibula_hombre.glb |
mandibula_hombre |
fosil_ammonite.glb |
fosil_ammonite |
vasija_romana.glb |
vasija_romana |
sala_paleontologia.jpg |
sala_paleontologia |
modelo_auzoux.glb |
modelo_auzoux |
El QR de la vitrina de la mandíbula humana debe contener exclusivamente el texto:
mandibula_hombre
Sin comillas, sin espacios extra, sin URL. Solo ese texto plano.
QR escaneado
│
├── ¿El texto coincide con alguna pieza del catálogo?
│ │
│ ├── ✅ SÍ → Pieza desbloqueada en la colección
│ │ │
│ │ ├── Es .glb / .gltf → Abre el visor 3D/AR in-app
│ │ └── Es .jpg / .png → Abre el entorno VR 360°
│ │
│ └── ❌ NO → Mensaje de error: "QR no reconocido por el museo"
Una vez desbloqueada, la pieza queda disponible en la pestaña Colección para verla en cualquier momento sin necesidad de volver a escanear.
| Herramienta | URL | Notas |
|---|---|---|
| QR Code Generator | qr-code-generator.com | Más opciones de diseño |
| GoQR | goqr.me | Simple y rápido |
| QRCode Monkey | qrcode-monkey.com | Permite logo / color personalizado |
Pasos:
- Abre cualquiera de los generadores anteriores.
- Selecciona tipo "Texto" (no URL).
- Escribe el ID de la pieza, por ejemplo:
mandibula_hombre - Descarga en PNG o SVG (alta resolución para imprimir).
- Imprime, plastifica y coloca el cartel en la vitrina.
💡 Consejo: Incluye en el cartel el nombre descriptivo de la pieza junto al QR para orientar al visitante aunque no use el móvil.
- Crea o exporta el modelo 3D en formato
.glbo la fotografía panorámica en.jpg. - Súbelo a GitHub Raw o Cloudflare R2 con un nombre sin espacios (usa
_). Ejemplo:hacha_neolitica.glb. - Si usas R2: añade la entrada en
manifest.jsondel bucket (ver sección 6). - Genera el QR con el texto
hacha_neolitica(nombre sin extensión). - Imprime el cartel y colócalo en la vitrina.
- La app mostrará la pieza automáticamente en el próximo arranque, sin ninguna actualización de código.
¡Ya has rellenado todo! Es hora de abrir la app.
- Abre la terminal (
CMDo la terminal de Visual Studio Code) en la carpeta raíz del proyecto. - Descarga todas las librerías necesarias ejecutando:
flutter pub get
- Conecta tu teléfono móvil por cable (con el modo de depuración USB activado) o abre el simulador de Chrome/Android Studio.
- Pulsa en Run (F5) en tu editor, o ejecuta en la terminal:
flutter run
(La primera vez tardará varios minutos en descargar recursos. ¡Ten paciencia!)
Si estás mostrando esta app a un tribunal, amigos o en una feria y no quieres que salten pantallas de tarjetas de crédito reales ni quieres caminar físicamente por un museo para escanear AR, tienes un "Modo Dios" que he programado.
En tu archivo .env, cambia la última línea:
TESTER=1¿Qué hace el modo Tester (TESTER=1)?
- Añade un botón rápido en la cámara AR (
ar_screen.dart) que simula que has escaneado exitosamente un código, para que puedas ver el objeto 3D sin moverte de la silla. - Al donar dinero o comprar merchandising, se simula una compra exitosa (aparece una barra verde) sin tocar Stripe ni tarjetas de crédito. Importante: El sistema sigue guardando el pedido real en Firestore (con el nombre de la pieza y tamaño exacto) para que puedas demostrar todo el flujo de gestión del administrador.
- Desbloquea todos los visores de candados de la Galería 3D.
- Muestra un letrero amarillo de "TESTER" arriba a la derecha.
Cuando vayas a subir la App a Google Play (Producción) para la gente real en la calle, recuerda cambiarlo a TESTER=0 y la app pasará a funcionar con pasarelas de bancos reales y códigos QR obligatorios.
La aplicación integra un flujo completo de venta y fabricación de reproducciones 3D del museo, diseñado para una gestión industrial sin errores:
- Checkout Adaptativo: El sistema detecta si el pedido es solo 3D y oculta campos innecesarios (como la fecha de visita) para agilizar la compra.
- Persistencia de Artefactos: Implementa un sistema de "Caja Fuerte" (
SharedPreferences) que asegura que el nombre de la pieza elegida nunca se pierda, incluso si el usuario refresca la página o vuelve de una pasarela externa. - Unificación de Datos (
pieceName): Estándar de nomenclatura unificado en todo el ecosistema (Tienda, Perfil, Admin y Firestore) para una trazabilidad perfecta.
- Cola de Fabricación: Panel exclusivo donde el administrador ve los pedidos en tiempo real con el nombre exacto del artefacto y el tamaño solicitado.
- Estados de Pedido: Control total sobre el ciclo de vida de la pieza:
- 🕒 Pendiente: Pedido recibido y en espera de impresión.
- 🖨️ Imprimiendo: La pieza está físicamente en la impresora.
- 🧪 En Cura: Proceso de post-procesado y endurecimiento.
- ✅ Listo: Pieza finalizada para entrega o envío.
- Notificaciones Inteligentes: El sistema envía emails automáticos al taller detallando la pieza, la referencia del pedido y la altura exacta en milímetros.
Esta aplicación no es un simple prototipo; incluye funcionalidades de nivel de producción comercial listas para distribuirse en las tiendas de apps:
-
🎨 Icono de Aplicación y Splash Screen: La app cuenta con un icono nativo diseñado específicamente para el museo y una pantalla de carga (Splash Screen) personalizada que se muestra mientras el motor de Flutter se inicializa, dando una impresión instantánea de máxima profesionalidad.
-
📖 Onboarding (Tutorial de Bienvenida): Los nuevos usuarios son recibidos con un tutorial de bienvenida (deslizable) que explica las funciones principales del museo (AR, 3D, Gamificación). Este progreso se guarda en el teléfono para que solo aparezca la primera vez.
-
🔐 Autenticación Premium (Google OAuth): Pantalla de acceso totalmente rediseñada con una estética "Dark Card" minimalista y moderna.
- Diseño de Gala: Cuadro oscuro con bordes suavizados y aura de luz que resalta el logo oficial del museo.
- Lectura Óptima: Campos de texto en color "blanco marfil" con alto contraste para una escritura cómoda.
- Cero Fricción: Integración profesional con Google Sign-In optimizada para Web, Android e iOS, permitiendo el acceso en un solo clic.
- Adaptabilidad: Diseño compacto "anti-scroll" que garantiza una visualización perfecta en cualquier tamaño de pantalla.
-
🌍 Multidioma Reactivo (i18n): La interfaz completa está traducida a Español e Inglés con un sistema de alta fidelidad.
- Persistencia Real: La app recuerda el idioma incluso antes de mostrar la primera pantalla, leyendo directamente de las preferencias del sistema antes del arranque (
runApp). - Cambio en Caliente: El usuario puede cambiar de idioma desde Ajustes y toda la aplicación se redibuja al instante sin parpadeos ni errores de navegación, gracias a una arquitectura reactiva con
riverpodyeasy_localization. - Cobertura: Los archivos
en.jsonyes.jsoncubren más de 150 etiquetas, asegurando que no queden textos sin traducir.
- Persistencia Real: La app recuerda el idioma incluso antes de mostrar la primera pantalla, leyendo directamente de las preferencias del sistema antes del arranque (
-
💰 Gamificación — Sistema de Rangos: A medida que el usuario desbloquea piezas escaneando, sube de rango:
Rango Piezas Color Visitante 0 Gris Explorador 1–2 Bronce Académico 3–5 Plata Conservador Jefe 6+ Oro El rango aparece en la pantalla de perfil y en el inicio. -
📰 Bio-Revista Científica: Sección de noticias con feeds RSS en tiempo real de fuentes científicas (Agencia SINC y otras). Las imágenes se almacenan en caché local con
cached_network_image— la segunda visita carga instantáneamente sin red. -
🗺️ Mapa 3D Interactivo y Multi-Tema: Plano de planta interactivo de alta fidelidad basado en modelos 3D y planos técnicos.
- Adaptación Inteligente: El mapa cambia automáticamente entre el modo Azul Abisal (Oscuro) y Blanco Técnico (Claro) según los ajustes del dispositivo, incluyendo fondos y textos dinámicos.
- Navegación por Salas: Sistema de pines inteligentes para las salas principales (Paleontología, Zoología, Arqueología, Anatomía e Instrumentos). Cada sala incluye una ficha técnica y permite filtrar la galería de piezas 3D al instante.
- Precisión Adaptativa: Implementado con un sistema de coordenadas relativas que garantiza la posición exacta de los puntos de interés en cualquier resolución de pantalla (Web, Tablet o Móvil).
-
📦 Catálogo Dinámico (R2 + GitHub): El catálogo de la galería se descubre automáticamente desde el servidor de assets configurado. Si se usa Cloudflare R2, basta con actualizar
manifest.jsonen el bucket para que la pieza aparezca en la app sin ninguna actualización de código. -
💳 Pagos de Clase Mundial (Stripe Checkout): Implementa una pasarela de pago visualmente impresionante y 100% segura.
- Experiencia de Usuario: Interfaz de Checkout fluida, moderna y optimizada para móviles, idéntica a la utilizada por grandes plataformas globales.
- Confianza Instantánea: El uso de la pasarela oficial de Stripe transmite una seguridad profesional al visitante desde el primer momento.
- Unificado: Una sola lógica de pago para Móvil, Web y PC, garantizando una experiencia consistente en todo el ecosistema del museo.
-
📈 Analíticas Multiplataforma (Firebase): Seguimiento del comportamiento de los usuarios (visitas a pantallas, compras de entradas en Stripe, donaciones simuladas o reales) con soporte total para Android, iOS y Web.
-
🔥 Firebase Crashlytics: Todos los errores y crashes en producción se capturan automáticamente y se envían al panel de Crashlytics. Se integra mediante
runZonedGuarded,FlutterError.onErroryPlatformDispatcher.onErrorpara no perder ningún error. -
📡 Modo Offline (Catálogo Cacheado): El catálogo de piezas 3D se guarda en
SharedPreferencestras cada carga exitosa. Si el usuario abre la app sin conexión, se muestra el último catálogo conocido con un aviso discreto de modo offline. -
🔍 Buscador en la Colección: Campo de búsqueda en tiempo real en la galería que filtra piezas por nombre o sala. Compatible con los filtros de sala del mapa interactivo.
-
❤️ Favoritos: El usuario puede marcar piezas como favoritas pulsando ♥. Los favoritos se guardan en Firestore (usuario autenticado) o
SharedPreferences(invitado) y se visualizan en una tercera tab dedicada en la Colección. -
🏟️ Mis Entradas (QR Digital In-App): Pantalla dedicada dentro de la app donde se muestran todas las entradas digitales del usuario con su código QR generado en tiempo real mediante
qr_flutter. El usuario puede mostrar el QR directamente desde el móvil en la puerta del museo o compartirlo. -
🔗 Deep Links: Se puede abrir la app directamente en una pieza específica mediante el esquema personalizado
museo://pieza/[itemId]. Así, un QR en el cartel físico de la vitrina puede lanzar la app y mostrar el modelo 3D de esa pieza al instante. -
♿ Accesibilidad (a11y): Los elementos interactivos principales incluyen
Semanticscon etiquetas descriptivas yExcludeSemanticsen íconos y elementos decorativos. La app es compatible con lectores de pantalla TalkBack (Android) y VoiceOver (iOS). -
⚙️ GitHub Actions (CI/CD): Pipeline automático en
.github/workflows/flutter_ci.ymlque se ejecuta en cada push amainodev. Pasos:flutter analyze,flutter test,flutter build apk --debug. El APK de debug se sube como artifact de 7 días. -
🤖 Asistente de IA Integrado (Groq): Un asistente virtual flotante accesible desde cualquier pantalla de la app, disponible tanto en Web como en Android.
- Motor: Utiliza la API de Groq con el modelo
openai/gpt-oss-120b(500 T/s), uno de los más rápidos del mercado. - Arquitectura Tool Calling: En lugar de enviar el catálogo completo en cada petición, la IA recibe un índice compacto de las piezas y llama a una herramienta local
get_piece_details(piece_id)cuando necesita información detallada de una pieza concreta. Esto minimiza el uso de tokens y elimina errores de payload. - Conocimiento del Museo: Conoce todas las piezas del catálogo, las salas, la historia y todas las funcionalidades de la app (compra de entradas, AR, rangos, favoritos, etc.).
- Contexto de Conversación: Mantiene memoria de los últimos 5 mensajes para conversaciones coherentes sin disparar el coste en tokens.
- Renderizado Markdown: Las respuestas de la IA se muestran con formato enriquecido: negrita, cursiva, listas y
código. - Adaptativo: La interfaz del chat cambia automáticamente entre Modo Claro y Modo Oscuro.
- Configuración: Requiere añadir
GROQ_API_KEYen el archivoenv_config. La clave se obtiene gratis en console.groq.com.
- Motor: Utiliza la API de Groq con el modelo
Este proyecto ha sido actualizado para cumplir con los estándares de seguridad y rendimiento de 2025/2026:
- Gradle: 8.11.1
- Android Gradle Plugin (AGP): 8.9.1
- Kotlin: 2.1.0
- Seguridad: El archivo
.envestá estrictamente ignorado por Git. Se incluye un.env.examplecomo plantilla. - Optimizaciones: Se han eliminado dependencias obsoletas como
arcore_flutter_pluginpara garantizar la compatibilidad con las últimas versiones de AndroidX y Gradle, delegando la AR de forma más eficiente al visor nativo.