Files
FarmaFinder/docs/superpowers/specs/2026-07-06-farmafinder-mobile-design.md
T
2026-07-06 10:16:51 +02:00

12 KiB

FarmaFinder Mobile - Especificación de Diseño

Fecha: 2026-07-06 Estado: Aprobado Versión: 1.0


1. Resumen

Crear un segundo frontend en React Native (Expo) para FarmaFinder, manteniendo el frontend actual (React + Vite) para Desktop/PWA. El objetivo es lograr una experiencia móvil nativa que permita publicar en App Store y Google Play con mejor rendimiento, UX y mantenibilidad.


2. Arquitectura

2.1 Estructura del Proyecto

FarmaFinder/
├── frontend/                  ← React + Vite (Desktop/PWA, mantiene Capacitor)
├── frontend-mobile/           ← Expo + React Native (NUEVO)
│   ├── app/                   ← Expo Router (file-based routing)
│   │   ├── _layout.tsx        ← Layout raíz
│   │   ├── (tabs)/            ← Bottom tabs
│   │   │   ├── _layout.tsx    ← Tab navigator
│   │   │   ├── index.tsx      ← Home (búsqueda)
│   │   │   ├── map.tsx        ← Mapa de farmacias
│   │   │   └── profile.tsx    ← Perfil de usuario
│   │   ├── medicine/[id].tsx  ← Detalle de medicamento
│   │   ├── pharmacy/[id].tsx  ← Detalle de farmacia
│   │   └── auth/              ← Auth flow
│   ├── components/            ← Componentes React Native
│   ├── services/              ← Lógica de negocio y llamadas API
│   ├── hooks/                 ← Custom hooks
│   ├── constants/             ← Colores, tipos, config
│   └── assets/                ← Imágenes, fuentes
├── backend/                   ← API compartida (sin cambios)
└── package.json               ← Scripts para ambos frontends

2.2 Stack Tecnológico

Componente Tecnología Justificación
Framework Expo SDK 52+ Setup rápido, OTA updates, fácil publicación
Routing Expo Router v4 File-based routing, similar a Next.js
Navegación React Navigation Bottom tabs + stack navigation
State Zustand Ligero, sin boilerplate, fácil de usar
HTTP Client Axios Interceptors, cancelación de requests
Cache TanStack Query Cache automático, optimistic updates
Mapas react-native-maps Google Maps provider nativo
Barcode expo-camera Escaneo de código de barras nativo
Storage AsyncStorage + expo-secure-store Datos offline + tokens seguros
Animaciones React Native Reanimated 3 Animaciones fluidas en 60fps

3. Estructura de Navegación

3.1 Navegación Principal

Bottom Tabs
├── Home (🔍)        → Búsqueda de medicamentos
├── Mapa (📍)        → Mapa de farmacias
└── Perfil (👤)      → Perfil de usuario + Admin

3.2 Navegación Detallada

Home Tab (Stack)
├── index.tsx         ← Lista de resultados de búsqueda
└── medicine/[id].tsx ← Detalle de medicamento

Mapa Tab (Stack)
├── map.tsx           ← Mapa con marcadores de farmacias
└── pharmacy/[id].tsx ← Detalle de farmacia

Perfil Tab (Stack)
├── profile.tsx       ← Info de usuario + opciones
├── auth/login.tsx    ← Login (si no autenticado)
├── auth/register.tsx ← Registro
└── admin/            ← Panel admin (solo si auth + admin)

3.3 Flujos de Navegación

  • Auth Flow: Si no hay token → redirigir a login
  • Admin Flow: Si usuario es admin → mostrar acceso a admin
  • Deep Linking: URLs como farmafinder://medicine/123 abren pantalla específica

4. Funcionalidades

4.1 MVP (Paridad con Web)

Funcionalidad Descripción
Búsqueda Búsqueda en tiempo real de medicamentos vía API CIMA
Resultados Lista de resultados con nombre, principio activo
Detalle medicamento Precio, stock, farmacias que lo tienen
Mapa farmacias Marcadores en mapa con ubicación
Detalle farmacia Dirección, teléfono, medicamentos disponibles
Auth Login/registro de usuarios

4.2 Extras Nativos (NUEVO)

Funcionalidad Descripción
Push Notifications Alertas de disponibilidad de medicamentos favoritos
Escáner código barras Escanear medicamentos directamente con cámara
Biometría Face ID / Touch ID para login rápido
Deep Links Compartir medicamentos/farmacias via URL
Offline Cache Medicamentos favoritos accesibles sin conexión

5. Integración con la API

5.1 Cliente API

// frontend-mobile/services/api.ts
import axios from 'axios';

const API_BASE = __DEV__ 
  ? 'http://localhost:3001/api' 
  : 'https://tu-dominio.com/api';

export const api = axios.create({
  baseURL: API_BASE,
  timeout: 10000,
  headers: { 'Content-Type': 'application/json' }
});

// Request interceptor para auth token
api.interceptors.request.use((config) => {
  const token = getToken();
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

5.2 Endpoints

Públicos:

  • GET /api/medicines/search?q=<query> - Búsqueda de medicamentos
  • GET /api/medicines/:nregistro - Detalle de medicamento
  • GET /api/medicines/:nregistro/pharmacies - Farmacias con medicamento
  • GET /api/pharmacies - Todas las farmacias

Autenticados:

  • POST /api/auth/login - Login
  • POST /api/auth/logout - Logout
  • GET /api/auth/check - Verificar auth

Admin:

  • CRUD de farmacias
  • Búsqueda de medicamentos para admin
  • Vincular medicamentos a farmacias

5.3 Estrategia de Cache

// Con TanStack Query
const { data, isLoading } = useQuery({
  queryKey: ['medicines', searchQuery],
  queryFn: () => searchMedicines(searchQuery),
  staleTime: 5 * 60 * 1000, // 5 minutos
  cacheTime: 30 * 60 * 1000, // 30 minutos
});

Persistencia offline:

  • AsyncStorage para datos no sensibles
  • expo-secure-store para tokens y credenciales
  • React Query persistor para cache de queries

6. Diseño Visual

6.1 Design Tokens

// frontend-mobile/constants/theme.ts
export const colors = {
  // Primary
  primary: '#007AFF',
  primaryLight: '#4DA3FF',
  
  // Semantic
  success: '#34C759',    // Disponible
  danger: '#FF3B30',     // Sin stock
  warning: '#FF9500',    // Stock bajo
  
  // Neutral
  background: '#F2F2F7',
  card: '#FFFFFF',
  border: '#E5E5EA',
  
  // Text
  text: '#1C1C1E',
  textSecondary: '#8E8E93',
  textInverse: '#FFFFFF',
};

export const spacing = {
  xs: 4,
  sm: 8,
  md: 16,
  lg: 24,
  xl: 32,
};

export const borderRadius = {
  sm: 8,
  md: 12,
  lg: 16,
};

6.2 Componentes Principales

Componente Descripción
SearchBar Input con debounce (300ms) + dropdown de resultados
MedicineCard Card con nombre, principio activo, precio, badge de stock
PharmacyMarker Marcador personalizado en mapa con info window
StockBadge Badge verde (disponible) / rojo (sin stock)
LoadingSpinner Spinner nativo durante cargas
ErrorToast Toast de error con retry

6.3 Patrones de Diseño

  • Cards: Sombra sutil, border-radius 12px
  • Tipografía: Sistema nativo (SF Pro en iOS, Roboto en Android)
  • Espaciado: Escala de 4px base (4, 8, 12, 16, 24, 32)
  • Animaciones: Reanimated 3 para transiciones y gestos

7. Extras Nativos (Detalles)

7.1 Push Notifications

// Expo Notifications
import * as Notifications from 'expo-notifications';

// Registrar para notificaciones
const registerForPushNotifications = async () => {
  const { status } = await Notifications.requestPermissionsAsync();
  if (status !== 'granted') return;
  
  const token = await Notifications.getExpoPushToken();
  return token.data;
};

// Escuchar notificaciones
Notifications.addNotificationReceivedListener((notification) => {
  // Mostrar alerta de disponibilidad
});

7.2 Escáner de Código de Barras

// expo-camera + barcode scanning
import { CameraView } from 'expo-camera';

<CameraView
  onBarcodeScanned={(data) => {
    // Buscar medicamento por código de barras
    searchMedicineByBarcode(data.data);
  }}
/>

7.3 Biometría

// expo-local-authentication
import * as LocalAuthentication from 'expo-local-authentication';

const authenticateWithBiometrics = async () => {
  const hasHardware = await LocalAuthentication.hasHardwareAsync();
  const isEnrolled = await LocalAuthentication.isEnrolledAsync();
  
  if (hasHardware && isEnrolled) {
    return await LocalAuthentication.authenticateAsync();
  }
  return false;
};

8. Workflow de Desarrollo

8.1 Scripts

{
  "scripts": {
    "dev:mobile": "cd frontend-mobile && npx expo start",
    "dev:mobile:android": "cd frontend-mobile && npx expo start --android",
    "dev:mobile:ios": "cd frontend-mobile && npx expo start --ios",
    "build:mobile:dev": "cd frontend-mobile && eas build --profile development",
    "build:mobile:preview": "cd frontend-mobile && eas build --profile preview",
    "build:mobile:prod": "cd frontend-mobile && eas build --profile production",
    "submit:android": "cd frontend-mobile && eas submit --platform android",
    "submit:ios": "cd frontend-mobile && eas submit --platform ios"
  }
}

8.2 EAS Build Profiles

// frontend-mobile/eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}

8.3 CI/CD

  • Desarrollo: Expo Go + hot reload
  • Testing: EAS Build (preview) → APK/IPA para testing
  • Producción: EAS Build (production) → Submit a tiendas
  • OTA Updates: Expo Updates para fixes sin pasar por tienda

9. Dependencias Principales

{
  "dependencies": {
    "expo": "~52.0.0",
    "expo-router": "~4.0.0",
    "expo-camera": "~16.0.0",
    "expo-notifications": "~0.29.0",
    "expo-local-authentication": "~15.0.0",
    "expo-secure-store": "~14.0.0",
    "react-native": "0.76.0",
    "react-native-maps": "1.18.0",
    "react-native-reanimated": "~3.16.0",
    "react-native-gesture-handler": "~2.20.0",
    "@react-navigation/native": "^7.0.0",
    "@react-navigation/bottom-tabs": "^7.0.0",
    "zustand": "^5.0.0",
    "axios": "^1.7.0",
    "@tanstack/react-query": "^5.0.0",
    "@react-native-async-storage/async-storage": "^2.0.0"
  }
}

10. Criterios de Aceptación

MVP

  • Búsqueda de medicamentos funcional
  • Mapa con farmacias mostrando marcadores
  • Detalle de medicamento con precio y stock
  • Detalle de farmacia con ubicación
  • Login/registro funcional
  • Navegación entre pantallas fluida
  • Build de desarrollo funcionando en Expo Go

Extras Nativos

  • Push notifications configuradas
  • Escáner de código de barras funcional
  • Biometría para login rápido
  • Deep links configurados
  • Offline cache para favoritos

Publicación

  • Build de producción optimizado
  • App Store listing configurado
  • Google Play listing configurado
  • Screenshots y descripción preparados

11. Riesgos y Mitigaciones

Riesgo Mitigación
API del backend no preparada para móvil Revisar endpoints, agregar si es necesario
Performance en dispositivos antiguos Testing en dispositivos低端, optimizar renders
Diferencias iOS/Android Usar componentes nativos, testing en ambas plataformas
Mantenimiento de dos frontends Documentar bien, compartir types cuando sea posible

12. Próximos Pasos

  1. Crear estructura del proyecto Expo
  2. Configurar routing con Expo Router
  3. Implementar cliente API
  4. Crear pantallas MVP
  5. Implementar extras nativos
  6. Testing y optimización
  7. Build y publicación en tiendas