SnapReceipt es una aplicación móvil desarrollada con Ionic/Angular que permite capturar fotos de tickets y recibos, extraer datos automáticamente usando inteligencia artificial (Gemini 1.5 Flash), y almacenarlos en una base de datos (Supabase).
- 🔐 Autenticación: Sistema completo de registro e inicio de sesión con Supabase Auth
- 📸 Captura de Recibos: Usa la cámara nativa del dispositivo para capturar fotos de tickets
- 🤖 Extracción Automática: Utiliza Gemini 1.5 Flash AI para extraer datos estructurados (fecha, total, comercio, items, categoría)
- 💰 Soporte Multi-Moneda: Detecta automáticamente la moneda del recibo (EUR, USD, MXN, etc.)
- 🏷️ Categorías por Artículo: Asigna múltiples categorías a cada artículo del recibo con chips visuales
- 📝 Resumen IA: Genera automáticamente un resumen descriptivo de cada recibo
- 📊 Reportes y Estadísticas: Página de reportes con filtros, agrupaciones y análisis de gastos
- 💾 Almacenamiento Seguro: Guarda los datos y las imágenes en Supabase con aislamiento por usuario
- 🔑 API Keys Personales: Cada usuario configura su propia API key de Gemini
- ⚙️ Configuración: Página de ajustes para gestionar preferencias y API keys
- 🛡️ Seguridad: Row Level Security (RLS) garantiza que cada usuario solo acceda a sus propios datos
- 📱 Diseño Responsive: Interfaz moderna y adaptable con componentes Ionic
- ⚡ Rendimiento: Optimizado para procesamiento rápido de imágenes
- 🚀 CI/CD: GitHub Actions para builds automáticos de Angular y APK de Android bajo demanda
- Framework: Ionic 8 + Angular 18
- Lenguaje: TypeScript
- Capacitor: Para acceso a funcionalidades nativas (cámara)
- API de IA: Google Gemini 1.5 Flash
- Base de Datos: Supabase (PostgreSQL + Storage)
Antes de comenzar, asegúrate de tener instalado:
- Node.js (v18 o superior)
- npm (v9 o superior)
- Ionic CLI - Instalar con:
npm install -g @ionic/cli - Una cuenta de Google AI Studio para obtener la API key de Gemini
- Una cuenta de Supabase para la base de datos y almacenamiento
-
Clonar el repositorio
git clone https://github.com/davidnajar/SnapReceipt.git cd SnapReceipt -
Instalar dependencias
npm install
-
Configurar variables de entorno de Supabase
Edita el archivo
src/environments/environment.tsy configura tus credenciales de Supabase:export const environment = { production: false, gemini: { apiKey: 'YOUR_GEMINI_API_KEY_HERE' // No es necesario configurar aquí, cada usuario usará su propia key }, supabase: { url: 'TU_URL_DE_SUPABASE_AQUI', anonKey: 'TU_ANON_KEY_DE_SUPABASE_AQUI' } };
Nota: La API key de Gemini ya no se configura aquí. Cada usuario configurará su propia API key en la aplicación después de registrarse.
-
Configurar Supabase
a. Crea un nuevo proyecto en Supabase
b. Aplica las migraciones de base de datos:
- Ve a la carpeta
supabase/migrations/ - Ejecuta cada archivo SQL en orden (001, 002, 003, 004, 005, 006, 007) en el SQL Editor de Supabase
- Ver instrucciones detalladas en supabase/README.md
- La migración 006 añade soporte para procesamiento asíncrono y moneda
- La migración 007 añade el campo de resumen IA
c. Crea un bucket de Storage llamado
receipts:- Ve a Storage en el dashboard de Supabase
- Crea un nuevo bucket llamado
receipts - Las políticas de acceso se configuran automáticamente mediante las migraciones
d. Habilita la autenticación por email:
- Ve a Authentication > Providers en el dashboard de Supabase
- Asegúrate de que "Email" esté habilitado
- Ve a la carpeta
-
Registro y Configuración de Usuario
a. Registra una cuenta en la aplicación
b. Ve a la página de Settings en la aplicación
c. Obtén tu API Key de Gemini:
- Ve a Google AI Studio
- Crea una nueva API key
- Importante: Cada usuario necesita su propia API key de Gemini
d. Ingresa tu API key en la página de Settings de la aplicación
e. Para instrucciones detalladas, consulta la página "Cómo obtener Gemini API Key" dentro de la aplicación
npm start
# o
ionic serveLa aplicación se abrirá en http://localhost:8100
npm run build
# o
ionic build --prodnpm testnpm run lintiOS (requiere macOS):
ionic cap add ios
ionic cap sync ios
ionic cap open iosAndroid:
ionic cap add android
ionic cap sync android
ionic cap open androidDespués de hacer cambios en el código web:
ionic cap sync# iOS
ionic cap run ios
# Android
ionic cap run androidEste proyecto incluye workflows de GitHub Actions para automatizar builds:
Se ejecuta automáticamente en cada push a las ramas principales (main, master, develop):
- Compila la aplicación Angular
- Ejecuta el linter
- Genera artefactos descargables de la carpeta
www/
Para compilar un APK de Android:
- Ve a la pestaña Actions en GitHub
- Selecciona el workflow "Build Android APK"
- Haz clic en "Run workflow"
- Selecciona el tipo de build (
debugorelease) - Descarga el APK desde los artefactos del workflow
Para más detalles, consulta .github/workflows/README.md
SnapReceipt/
├── src/
│ ├── app/
│ │ ├── guards/ # Guards de autenticación
│ │ ├── home/ # Página principal con FAB y captura
│ │ ├── login/ # Página de inicio de sesión
│ │ ├── register/ # Página de registro
│ │ ├── settings/ # Página de configuración (API key)
│ │ ├── gemini-guide/ # Guía para obtener API key
│ │ ├── models/ # Interfaces TypeScript (Receipt)
│ │ ├── services/ # Servicios (Camera, Gemini, Supabase)
│ │ ├── app.component.* # Componente raíz
│ │ ├── app.module.ts # Módulo principal
│ │ └── app-routing.module.ts
│ ├── assets/ # Recursos estáticos
│ ├── environments/ # Configuración de entornos
│ ├── theme/ # Estilos globales e Ionic
│ ├── global.scss # Estilos globales
│ ├── index.html # HTML principal
│ ├── main.ts # Punto de entrada
│ └── polyfills.ts # Polyfills
├── supabase/
│ ├── migrations/ # Migraciones SQL
│ └── README.md # Documentación de migraciones
├── capacitor.config.ts # Configuración de Capacitor
├── angular.json # Configuración de Angular
├── package.json # Dependencias
└── tsconfig.json # Configuración de TypeScript
- El usuario abre la aplicación y ve la pantalla de login
- Si no tiene cuenta, se registra con email y contraseña
- Después de registrarse/iniciar sesión, accede a la pantalla principal
- Configura su API key de Gemini en la página de Configuración (primer uso)
- Regresa a la pantalla principal y ve un botón FAB (Floating Action Button) en la esquina inferior derecha
- Presiona el botón FAB con el ícono de cámara
- Se abre la cámara nativa del dispositivo
- Captura una foto del ticket/recibo
- La aplicación muestra un indicador de carga mientras procesa
- La imagen se envía a Gemini AI para extraer los datos
- Se muestra un diálogo de confirmación con los datos extraídos
- Si el usuario confirma, la imagen se sube a Supabase Storage
- Los datos se guardan en la tabla de Supabase
- Se muestra un mensaje de éxito
interface Receipt {
id?: string; // UUID generado por Supabase
date: string; // Fecha en formato YYYY-MM-DD
total: number; // Monto total
currency?: string; // Código de moneda (USD, EUR, MXN, etc.)
merchant: string; // Nombre del comercio
items?: ReceiptItem[]; // Array de items (opcional)
category?: string; // Categoría general (groceries, restaurant, etc.)
summary?: string; // Resumen generado por IA
imageUrl?: string; // URL de la imagen en Supabase Storage
status?: 'processing' | 'completed' | 'error'; // Estado del procesamiento
createdAt?: Date; // Fecha de creación
}
interface ReceiptItem {
name: string; // Nombre del producto
price: number; // Precio unitario
quantity: number; // Cantidad
categories?: string[]; // Múltiples categorías por artículo
}Gestiona la captura de fotos usando Capacitor Camera:
capturePhoto(): Abre la cámara y captura una fotocheckCameraPermissions(): Verifica permisos de cámararequestCameraPermissions(): Solicita permisos de cámara
Maneja la comunicación con Google Gemini AI:
extractReceiptData(base64Image): Envía imagen y recibe datos estructurados en JSON- Detecta automáticamente la moneda del recibo
- Asigna múltiples categorías a cada artículo
- Genera un resumen descriptivo del recibo
isConfigured(): Verifica si la API key está configurada
Gestiona el almacenamiento en Supabase:
uploadReceiptImage(base64Image, fileName): Sube imagen a StoragesaveReceipt(receipt): Guarda datos en la tablagetReceipts(): Obtiene todos los recibos guardadosisConfigured(): Verifica si las credenciales están configuradas
Gestiona categorías y su visualización:
getCategoryColor(category): Obtiene el color de una categoría para chipsgetCategoryIcon(category): Obtiene el icono de una categoría
Gestiona el formato de monedas:
getCurrencySymbol(currency): Obtiene el símbolo de una monedaformatAmount(amount, currency): Formatea un monto con su símbolo de moneda- Soporta múltiples monedas: USD, EUR, GBP, MXN, CAD, AUD, CHF, CNY, INR, BRL, ARS, COP, CLP, PEN, UYU
- Verifica que los permisos de cámara estén concedidos
- En iOS, asegúrate de tener la descripción de privacidad en Info.plist
- En Android, verifica los permisos en AndroidManifest.xml
- Verifica que tu API key de Gemini sea válida
- Asegúrate de tener conexión a internet
- Revisa la consola del navegador para mensajes de error detallados
- Verifica que las credenciales de Supabase sean correctas
- Asegúrate de que la tabla
receiptsesté creada - Verifica que el bucket
receiptsexista y sea público - Revisa las políticas de Row Level Security (RLS) si están activas
- Elimina
node_modulesypackage-lock.json, luego ejecutanpm install - Limpia el caché de Ionic:
ionic repair - Verifica que tengas las versiones correctas de Node.js y npm
- Lista de recibos guardados
- Búsqueda y filtrado de recibos
- Estadísticas y gráficos de gastos
- Soporte multi-moneda
- Categorías múltiples por artículo
- Resumen IA de recibos
- Página de reportes con filtros y agrupaciones
- Edición manual de datos extraídos
- Edición de categorías en la UI (añadir/quitar chips)
- Exportación a PDF/CSV
- Modo offline con sincronización
- Soporte para múltiples idiomas
- Compartir recibos con otros usuarios
- Gráficos visuales en reportes (charts)
Las contribuciones son bienvenidas. Por favor:
- Haz fork del proyecto
- Crea una rama para tu feature (
git checkout -b feature/nueva-funcionalidad) - Commit tus cambios (
git commit -am 'Agrega nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Crea un Pull Request
Este proyecto está bajo la Licencia MIT. Ver el archivo LICENSE para más detalles.
- Autor: David Najar
- GitHub: @davidnajar
- Repositorio: SnapReceipt