Skip to content

TeamProjectsDev/flutter_application_museo

Repository files navigation

Museo Histórico Padre Suárez - App 🏛️

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.


🌐 Enlaces del Proyecto

Aquí puedes encontrar acceso directo a toda la infraestructura y documentación del proyecto:


📋 Índice


1. Requisitos Previos

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.

2. Configuración del Archivo .env

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.

  1. En la carpeta principal del proyecto (donde estás leyendo esto), busca un archivo llamado .env.example.
  2. Haz una copia de ese archivo y renómbralo a exactamente .env (con el punto delante y sin nada más).
  3. Abre este nuevo archivo .env con 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

3. Configuración de Firebase (Base de Datos y Usuarios)

Firebase es el servidor de Google que guarda los usuarios registrados, la colección de objetos que han desbloqueado y los administradores.

  1. Ve a Firebase Console e inicia sesión con una cuenta de Google.
  2. Haz clic en Añadir proyecto (Ej: "Museo App").
  3. 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.
  4. 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();
        }
      }
    }
  5. Haz clic en el icono del engranaje ⚙️ (Configuración del proyecto) arriba a la izquierda.
  6. 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, el appId y el measurementId (si aparece) y ponlos en tu archivo .env en los apartados FIREBASE_API_KEY_WEB, FIREBASE_APP_ID_WEB y FIREBASE_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_museo o el que aparezca en android/app/build.gradle). Al terminar, la web te dará una clave API de Android y un ID de App. Pégalos en FIREBASE_API_KEY_ANDROID y FIREBASE_APP_ID_ANDROID.
  7. 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.

📊 Eventos de Analíticas Integrados

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 tickets y purchases).
    • 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).
  • 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:

  1. El correo electrónico debe estar incluido en la variable ADMIN_EMAIL del archivo .env.
  2. La aplicación detectará automáticamente el rango de administrador y habilitará el botón "Gestión del Museo" en los ajustes.

4. Configuración de EmailJS (Correos Automáticos)

La app envía correos reales (tickets digitales, avisos de impresión 3D) a los usuarios sin necesidad de un servidor complejo. Usamos EmailJS.

  1. Regístrate gratis en EmailJS.com.
  2. 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 .env en EMAILJS_SERVICE_ID.
  3. 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}}
    • 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>
  4. Ve a la pestaña Account arriba a la derecha para ver tu "Public Key". Ese es tu EMAILJS_USER_ID para el .env.

5. Configuración de Pagos Reales (Stripe)

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).

  1. Crea una cuenta gratuita en Stripe.com.
  2. Accede a tu Panel de Control (Dashboard) y haz clic en la esquina superior derecha donde dice "Desarrolladores" o "Laves API" (API Keys).
  3. Asegúrate de tener activado el "Modo de Prueba" (un interruptor arriba a la derecha) para poder hacer compras falsas.
  4. En la pestaña de llaves API, busca tu Clave secreta (Secret Key). Tiene este formato: sk_test_...
  5. Cópiala y pégala en tu archivo .env justo 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.

6. Configuración de Activos Digitales (Cloudinary DAM)

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.

  1. Crea una cuenta gratuita en Cloudinary.
  2. Obtén tu Cloud Name desde el Dashboard.
  3. Asegúrate de que los archivos (.glb y .jpg) en tu Media Library tengan nombres coincidentes con el fileName definido en catalog_metadata.json.
  4. Configura la variable en tu archivo .env:
    CLOUDINARY_CLOUD_NAME=tu_cloud_name_aqui
    Nota: Ya no se requieren las claves de Supabase ni R2_PUBLIC_URL.

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.


7. Códigos QR para las Piezas del Museo

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.


¿Qué texto debe contener el QR?

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 llama mandibula hombre.glb, el ID es mandibula_hombre.


Ejemplos reales

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.


Comportamiento en la app al escanear

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.


Cómo generar los QR físicos (gratis)

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:

  1. Abre cualquiera de los generadores anteriores.
  2. Selecciona tipo "Texto" (no URL).
  3. Escribe el ID de la pieza, por ejemplo: mandibula_hombre
  4. Descarga en PNG o SVG (alta resolución para imprimir).
  5. 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.


Añadir una nueva pieza al museo (proceso completo)

  1. Crea o exporta el modelo 3D en formato .glb o la fotografía panorámica en .jpg.
  2. Súbelo a GitHub Raw o Cloudflare R2 con un nombre sin espacios (usa _). Ejemplo: hacha_neolitica.glb.
  3. Si usas R2: añade la entrada en manifest.json del bucket (ver sección 6).
  4. Genera el QR con el texto hacha_neolitica (nombre sin extensión).
  5. Imprime el cartel y colócalo en la vitrina.
  6. La app mostrará la pieza automáticamente en el próximo arranque, sin ninguna actualización de código.

8. Lanzar la Aplicación

¡Ya has rellenado todo! Es hora de abrir la app.

  1. Abre la terminal (CMD o la terminal de Visual Studio Code) en la carpeta raíz del proyecto.
  2. Descarga todas las librerías necesarias ejecutando:
    flutter pub get
  3. Conecta tu teléfono móvil por cable (con el modo de depuración USB activado) o abre el simulador de Chrome/Android Studio.
  4. 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!)


9. 🎮 MODO TESTER (Para Tribunal y Exposiciones sin Gasto)

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.


11. 🛒 Ecosistema de Comercio y Producción 3D

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:

💳 Flujo de Compra Blindado

  • 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.

🏭 Gestión de Producción para el Administrador

  • 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.

12. ✨ Características de Pulido Comercial

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 riverpod y easy_localization.
    • Cobertura: Los archivos en.json y es.json cubren más de 150 etiquetas, asegurando que no queden textos sin traducir.
  • 💰 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.json en 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.onError y PlatformDispatcher.onError para no perder ningún error.

  • 📡 Modo Offline (Catálogo Cacheado): El catálogo de piezas 3D se guarda en SharedPreferences tras 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 Semantics con etiquetas descriptivas y ExcludeSemantics en í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.yml que se ejecuta en cada push a main o dev. 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_KEY en el archivo env_config. La clave se obtiene gratis en console.groq.com.

🛠️ Nota Técnica: Entorno de Compilación

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 .env está estrictamente ignorado por Git. Se incluye un .env.example como plantilla.
  • Optimizaciones: Se han eliminado dependencias obsoletas como arcore_flutter_plugin para garantizar la compatibilidad con las últimas versiones de AndroidX y Gradle, delegando la AR de forma más eficiente al visor nativo.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors