Skip to content

RodrigoSanchezDev/vetcare-android-kotlin-compose-mvvm

VetCare Header

Kotlin Jetpack Compose Room Material 3 Android Architecture License

Aplicación Android nativa para la gestión integral de clínicas veterinarias

CaracterísticasArquitecturaInstalaciónDemoDocumentación


📋 Tabla de Contenidos


🎯 Descripción General

VetCare es una solución móvil completa diseñada para digitalizar y optimizar las operaciones diarias de clínicas veterinarias. La aplicación permite gestionar pacientes (mascotas), registrar consultas médicas, administrar la agenda de veterinarios y automatizar recordatorios de citas y vacunas para los propietarios de mascotas.

Problema que Resuelve

Desafío Solución VetCare
Gestión manual de expedientes Sistema digital centralizado de mascotas
Agendamiento desorganizado Calendario integrado con filtros avanzados
Falta de seguimiento médico Historial completo de consultas y tratamientos
Olvido de citas/vacunas Notificaciones automáticas programadas
Acceso limitado para dueños Portal dedicado para propietarios

✨ Características

Módulo Funcionalidades
🔐 Autenticación Login seguro, recuperación de contraseña, roles diferenciados
🐾 Gestión de Mascotas CRUD completo, historial médico, registro de vacunas
📅 Agenda de Citas Programación, filtros por estado, asignación de veterinarios
👨‍⚕️ Staff Veterinario Directorio, especialidades, agenda por profesional
🔔 Notificaciones Recordatorios automáticos de citas y vacunas
📊 Dashboard Admin Métricas en tiempo real, accesos rápidos
💾 Persistencia Local Room Database (SQLite), datos offline, sincronización automática
📝 Registro de Actividad Auditoría completa de acciones del sistema
🔍 Debug & Profiling Diagnóstico, métricas de rendimiento, manejo de errores
🧠 Memory Profiling LeakCanary, análisis de heap, detección de memory leaks
🎨 Temas y Apariencia Modo Claro, Oscuro y Automático (según sistema)
Accesibilidad Alto contraste, reducción de animaciones, TalkBack
🎯 UI/UX Premium Material 3, animaciones fluidas, diseño adaptativo

Características Técnicas Destacadas

✅ Arquitectura MVVM con StateFlow reactivo
✅ Persistencia local con Room Database (SQLite)
✅ Operaciones CRUD completas sin conexión a internet
✅ TypeConverters para LocalDateTime y Enums
✅ Navegación declarativa con Compose Navigation
✅ Notificaciones con WorkManager
✅ Animaciones con AnimatedVisibility y animateContentSize
✅ Sistema de temas dinámico (Claro/Oscuro/Sistema)
✅ Soporte de accesibilidad (TalkBack, alto contraste)
✅ Componentes UI reutilizables
✅ Validación de formularios en tiempo real
✅ Manejo estructurado de excepciones con try-catch
✅ Sistema de logging avanzado con tags personalizados
✅ Excepciones personalizadas del dominio
✅ Métricas de rendimiento en tiempo real
✅ Herramientas de diagnóstico y profiling
✅ Detección de memory leaks con LeakCanary
✅ Análisis de memoria con Android Profiler
✅ Búsqueda con debounce optimizado (300ms)
✅ Localización completa en Español (ES-CL)
✅ Procesamiento asincrónico con Kotlin Coroutines
✅ Carga paralela de datos con async/await
✅ Dispatchers optimizados (IO, Default, Main)
✅ Pull-to-refresh sin bloqueo de UI
✅ Pruebas unitarias con JUnit y MockK (90+ tests)
✅ Pruebas funcionales instrumentadas con Compose UI Testing
✅ APK firmado (release) listo para distribución
✅ Ícono personalizado de Play Store (ic_launcher-playstore.png)

🛠 Stack Tecnológico

Core

Tecnología Versión Propósito
Kotlin 2.0.21 Lenguaje principal
Jetpack Compose BOM 2024.09 UI declarativa
Material 3 Latest Sistema de diseño

Persistencia de Datos

Tecnología Versión Propósito
Room 2.7.0 Base de datos SQLite
SharedPreferences - Configuración de usuario
KSP 2.0.21-1.0.28 Procesador de anotaciones

Arquitectura & Datos

Tecnología Propósito
MVVM Patrón de arquitectura
StateFlow Gestión de estado reactivo
ViewModel Persistencia de UI state
Repository Pattern Abstracción de datos

Funcionalidades

Tecnología Propósito
Navigation Compose Navegación entre pantallas
WorkManager Programación de notificaciones
Kotlin Coroutines Procesamiento asincrónico optimizado

Networking & API REST

Tecnología Versión Propósito
Retrofit 2.9.0 Cliente HTTP para API REST
OkHttp 4.12.0 Cliente HTTP subyacente + Interceptors
Gson 2.10.1 Serialización JSON ↔ Objetos Kotlin

Procesamiento Asincrónico

Componente Propósito
viewModelScope Coroutines lifecycle-aware
Dispatchers.IO Operaciones de base de datos
Dispatchers.Default Procesamiento CPU-intensive
async/await Carga paralela de datos
Flow Streams reactivos de Room

Testing & Profiling

Tecnología Versión Propósito
JUnit 4.13.2 Framework de pruebas unitarias
MockK 1.13.8 Mocking para Kotlin
Compose Testing BOM 2024.09 Pruebas funcionales de UI
Espresso 3.5.1 Framework de pruebas instrumentadas
Coroutines Test 1.7.3 Testing de operaciones asincrónicas
LeakCanary 2.14 Detección de memory leaks
Android Profiler - Análisis de heap y memoria

🏗 Arquitectura

El proyecto implementa Clean Architecture con el patrón MVVM (Model-View-ViewModel), garantizando separación de responsabilidades, testabilidad y mantenibilidad.

┌─────────────────────────────────────────────────────────────────┐
│                        PRESENTATION LAYER                        │
│  ┌─────────────────┐    ┌─────────────────┐    ┌──────────────┐ │
│  │    Screens      │◄───│   ViewModels    │◄───│   UiState    │ │
│  │   (Compose)     │    │  (StateFlow)    │    │ (Data Class) │ │
│  └─────────────────┘    └─────────────────┘    └──────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│                         DOMAIN LAYER                             │
│  ┌─────────────────┐    ┌─────────────────┐                     │
│  │     Models      │    │   Use Cases     │                     │
│  │  (Data Class)   │    │   (Business)    │                     │
│  └─────────────────┘    └─────────────────┘                     │
├─────────────────────────────────────────────────────────────────┤
│                          DATA LAYER                              │
│  ┌─────────────────┐    ┌─────────────────┐    ┌──────────────┐ │
│  │   Repository    │◄───│      DAOs       │◄───│   Entities   │ │
│  │   (Singleton)   │    │  (Room/SQLite)  │    │   (@Entity)  │ │
│  └─────────────────┘    └─────────────────┘    └──────────────┘ │
│                               │                                  │
│                    ┌──────────▼──────────┐                      │
│                    │   Room Database     │                      │
│                    │  (vetcare_database) │                      │
│                    └─────────────────────┘                      │
└─────────────────────────────────────────────────────────────────┘

Flujo de Datos

User Action → Screen → ViewModel → Repository → DAO → Room Database (SQLite)
                ↑                                              │
                └──────────── StateFlow/Flow ◄────────────────┘

Análisis de Arquitectura MVVM

La aplicación implementa correctamente el patrón MVVM (Model-View-ViewModel) con separación clara de responsabilidades:

Capas de la Arquitectura

Capa Responsabilidad Componentes
View (UI) Renderizar UI, capturar eventos *Screen.kt, *Components.kt (Jetpack Compose)
ViewModel Estado de UI, lógica de presentación *ViewModel.kt con StateFlow
Model (Data) Datos y lógica de negocio Repository, DAOs, Entities, Models

Verificación de Separación de Responsabilidades

┌─────────────────────────────────────────────────────────────────┐
│                        UI LAYER                                  │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ screens/        components/       navigation/               ││
│  │ - PetListScreen - Cards.kt        - AppNavGraph.kt          ││
│  │ - PetDetail...  - Buttons.kt      - NavRoutes.kt            ││
│  │ - AdminHome...  - InputFields.kt                            ││
│  │                                                              ││
│  │ ✅ Solo UI declarativa, sin lógica de negocio               ││
│  └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│                     VIEWMODEL LAYER                              │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ *ViewModel.kt                                               ││
│  │ - PetListViewModel     - AdminHomeViewModel                 ││
│  │ - PetDetailViewModel   - AuthViewModel                      ││
│  │ - AppointmentViewModel - ActivityLogViewModel               ││
│  │                                                              ││
│  │ ✅ StateFlow para estado reactivo                           ││
│  │ ✅ viewModelScope para coroutines lifecycle-aware           ││
│  │ ✅ Sin referencias a Context/Activity                       ││
│  └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│                       DATA LAYER                                 │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ data/                                                       ││
│  │ ├── model/          # Modelos de dominio (Pet, Owner...)    ││
│  │ ├── local/          # Room Database, DAOs, Entities         ││
│  │ ├── remote/         # Retrofit, DTOs, Mappers               ││
│  │ ├── repository/     # VetCareRepository (singleton)         ││
│  │ └── session/        # SessionManager                        ││
│  │                                                              ││
│  │ ✅ Repository Pattern implementado                          ││
│  │ ✅ Separación Entity (Room) vs Model (Domain)               ││
│  │ ✅ DTOs separados para API REST                             ││
│  └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Estado de la Arquitectura

Principio MVVM Estado Evidencia
Single Source of Truth ✅ Implementado Room Database como fuente única
Unidirectional Data Flow ✅ Implementado UI → ViewModel → Repository → DB
Separation of Concerns ✅ Implementado 3 capas claramente separadas
Testability ✅ Preparado ViewModels sin dependencias de Android
Lifecycle Awareness ✅ Implementado viewModelScope, StateFlow

Conclusión: La arquitectura MVVM está correctamente implementada y optimizada. No se requieren modificaciones estructurales.

Persistencia Local

La aplicación utiliza Room Database como capa de abstracción sobre SQLite, proporcionando:

  • Operaciones offline: Todos los datos persisten localmente sin necesidad de conexión
  • Type Safety: Verificación en tiempo de compilación de consultas SQL
  • Reactive Streams: Integración nativa con Kotlin Coroutines y Flow
  • Migrations: Soporte para actualizaciones de esquema de base de datos

Optimización de Rendimiento con Kotlin Coroutines

La aplicación implementa procesamiento asincrónico avanzado para garantizar una experiencia de usuario fluida sin bloqueos ni congelamientos.

Estrategia de Dispatchers

// Operaciones de Base de Datos → Dispatchers.IO
val pet = withContext(Dispatchers.IO) {
    repository.getPetById(petId)
}

// Procesamiento de listas → Dispatchers.Default
val filteredList = withContext(Dispatchers.Default) {
    appointments.filter { it.dateTime.isAfter(now) }.sortedBy { it.dateTime }
}

// Actualizaciones de UI → Dispatchers.Main (automático en viewModelScope)
_uiState.value = newState

Carga Paralela con async/await

// Antes: Carga secuencial (~400ms con 4 operaciones de 100ms)
val owner = repository.getOwnerById(ownerId)      // 100ms
val consultations = repository.getConsultations() // 100ms  
val appointments = repository.getAppointments()   // 100ms
val vaccines = repository.getVaccines()           // 100ms

// Después: Carga paralela (~100ms total)
val ownerDeferred = async(Dispatchers.IO) { repository.getOwnerById(ownerId) }
val consultationsDeferred = async(Dispatchers.IO) { repository.getConsultations() }
val appointmentsDeferred = async(Dispatchers.IO) { repository.getAppointments() }
val vaccinesDeferred = async(Dispatchers.IO) { repository.getVaccines() }

// Todas las operaciones ejecutan simultáneamente
val owner = ownerDeferred.await()
val consultations = consultationsDeferred.await()

Flujos Optimizados

Pantalla Optimización Implementada
PetDetailScreen Carga paralela de owner, consultas, citas y vacunas
AdminDashboard Cálculo de estadísticas en parallel con async/await
VeterinariansScreen Carga paralela de estadísticas por veterinario
ActivityLog Flow reactivo con procesamiento en Default dispatcher
Formularios Guardado asincrónico sin bloqueo de UI

Comparación: Coroutines vs RxJava

Aspecto Kotlin Coroutines RxJava
Sintaxis Código secuencial natural Cadenas de operadores
Curva de aprendizaje Más suave Más pronunciada
Integración Jetpack Nativa (viewModelScope) Requiere adaptadores
Manejo de errores try/catch estándar Operadores específicos
Tamaño de dependencia Incluido en Kotlin Biblioteca adicional
Cancelación Structured concurrency Disposables manuales

Decisión: Se eligió Kotlin Coroutines por su integración nativa con Jetpack Compose, Room y ViewModel, además de proporcionar código más legible y mantenible.


📁 Estructura del Proyecto

app/
├── src/main/
│   ├── java/com/example/vetcare/
│   │   ├── VetCareApplication.kt            # Application class (inicializa Room)
│   │   │
│   │   ├── data/
│   │   │   ├── local/
│   │   │   │   ├── VetCareDatabase.kt       # Room Database principal
│   │   │   │   ├── Converters.kt            # TypeConverters (DateTime, Enums)
│   │   │   │   │
│   │   │   │   ├── dao/                     # Data Access Objects
│   │   │   │   │   ├── UserDao.kt
│   │   │   │   │   ├── OwnerDao.kt
│   │   │   │   │   ├── PetDao.kt
│   │   │   │   │   ├── VeterinarianDao.kt
│   │   │   │   │   ├── AppointmentDao.kt
│   │   │   │   │   ├── ConsultationDao.kt
│   │   │   │   │   ├── VaccineRecordDao.kt
│   │   │   │   │   └── ActivityEventDao.kt
│   │   │   │   │
│   │   │   │   ├── entity/                  # Room Entities (@Entity)
│   │   │   │   │   ├── UserEntity.kt
│   │   │   │   │   ├── OwnerEntity.kt
│   │   │   │   │   ├── PetEntity.kt
│   │   │   │   │   ├── VeterinarianEntity.kt
│   │   │   │   │   ├── AppointmentEntity.kt
│   │   │   │   │   ├── ConsultationEntity.kt
│   │   │   │   │   ├── VaccineRecordEntity.kt
│   │   │   │   │   └── ActivityEventEntity.kt
│   │   │   │   │
│   │   │   │   └── mapper/
│   │   │   │       └── EntityMappers.kt     # Conversión Entity ↔ Model
│   │   │   │
│   │   │   ├── remote/                      # 🆕 Capa de Red (Retrofit)
│   │   │   │   ├── api/
│   │   │   │   │   └── VetCareApiService.kt # Interfaz Retrofit
│   │   │   │   ├── dto/
│   │   │   │   │   └── ApiDtos.kt           # Data Transfer Objects
│   │   │   │   ├── mapper/
│   │   │   │   │   └── DtoMappers.kt        # DTO ↔ Domain Mappers
│   │   │   │   ├── RetrofitClient.kt        # Configuración Retrofit
│   │   │   │   ├── RemoteDataSource.kt      # API Calls encapsuladas
│   │   │   │   └── NetworkResult.kt         # Sealed class resultados
│   │   │   │
│   │   │   ├── logging/
│   │   │   │   └── ActivityLogger.kt        # Sistema de auditoría
│   │   │   │
│   │   │   ├── model/                       # Modelos de dominio
│   │   │   │   ├── User.kt
│   │   │   │   ├── Owner.kt
│   │   │   │   ├── Pet.kt
│   │   │   │   ├── Appointment.kt
│   │   │   │   ├── Veterinarian.kt
│   │   │   │   ├── Consultation.kt
│   │   │   │   ├── VaccineRecord.kt
│   │   │   │   └── ActivityEvent.kt
│   │   │   │
│   │   │   ├── repository/
│   │   │   │   └── VetCareRepository.kt     # Repositorio unificado (Room)
│   │   │   │
│   │   │   └── session/
│   │   │       └── SessionManager.kt        # Gestión de sesión
│   │   │
│   │   ├── debug/                           # Herramientas de Debug & Profiling
│   │   │   ├── DebugLogger.kt               # Sistema de logging avanzado
│   │   │   ├── VetCareExceptions.kt         # Excepciones personalizadas
│   │   │   ├── DebugPetDetailViewModel.kt   # ViewModel con métricas
│   │   │   └── DebugProfilingScreen.kt      # Pantalla de diagnóstico
│   │   │
│   │   ├── notifications/
│   │   │   ├── ReminderScheduler.kt         # Programador de recordatorios
│   │   │   └── ReminderWorkers.kt           # Workers de citas y vacunas
│   │   │
│   │   ├── ui/
│   │   │   ├── accessibility/
│   │   │   │   └── AccessibilityUtils.kt    # Utilidades de accesibilidad
│   │   │   │
│   │   │   ├── components/
│   │   │   │   ├── BottomNavigation.kt      # Navegación inferior
│   │   │   │   ├── Cards.kt                 # Tarjetas personalizadas
│   │   │   │   ├── Buttons.kt               # Botones con estilos
│   │   │   │   ├── InputFields.kt           # Campos de entrada
│   │   │   │   ├── TopBars.kt               # Barras superiores
│   │   │   │   └── Tabs.kt                  # Pestañas de filtro
│   │   │   │
│   │   │   ├── navigation/
│   │   │   │   ├── NavRoutes.kt             # Definición de rutas
│   │   │   │   └── AppNavGraph.kt           # Grafo de navegación
│   │   │   │
│   │   │   ├── screens/
│   │   │   │   ├── auth/                    # Autenticación
│   │   │   │   ├── admin/                   # Panel administrador
│   │   │   │   ├── owner/                   # Panel propietario
│   │   │   │   ├── pets/                    # Gestión de mascotas
│   │   │   │   ├── appointments/            # Gestión de citas
│   │   │   │   ├── veterinarians/           # Gestión de veterinarios
│   │   │   │   ├── consultations/           # Consultas médicas
│   │   │   │   ├── activity/                # Registro de actividad
│   │   │   │   ├── settings/                # Configuración
│   │   │   │   └── discover/                # Descubrir servicios
│   │   │   │
│   │   │   └── theme/
│   │   │       ├── Color.kt                 # Paletas de colores
│   │   │       ├── Theme.kt                 # Configuración del tema
│   │   │       ├── ThemeSettings.kt         # Preferencias (SharedPreferences)
│   │   │       └── Typography.kt            # Tipografía del sistema
│   │   │
│   │   └── MainActivity.kt
│   │
│   └── res/
│       ├── drawable/                         # Assets de imágenes
│       └── values/                           # Recursos (strings, colors)
│
├── build.gradle.kts                          # Configuración del módulo
└── gradle/
    └── libs.versions.toml                    # Catálogo de versiones

🚀 Instalación

Prerrequisitos

  • Android Studio Hedgehog | 2023.1.1 o superior
  • JDK 17 o superior
  • Android SDK API 26+ (Android 8.0)
  • Gradle 8.0+

Pasos de Instalación

# 1. Clonar el repositorio
git clone https://github.com/yourusername/vetcare-android.git

# 2. Abrir en Android Studio
cd vetcare-android

# 3. Sincronizar dependencias
./gradlew build

# 4. Ejecutar en emulador o dispositivo
./gradlew installDebug

Build Variants

Variante Uso
debug Desarrollo y testing
release Producción (requiere signing)

⚙️ Configuración

Usuarios de Prueba

Rol Email Contraseña
Administrador admin@vet.cl 123456
Propietario owner@vet.cl 123456

Permisos Requeridos

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

🎬 Demo

🎥 Videos Demostrativos

Interfaz Administrador Interfaz Cliente
Ver Demo Admin Ver Demo Cliente
Gestión completa: Dashboard, Mascotas, Citas, Staff y Auditoría Experiencia del dueño: Mis Mascotas, Citas y Configuración

Flujo de Administrador

Login → Dashboard → Gestión de Mascotas → Agenda de Citas → Staff → Registro de Actividad

Flujo de Propietario

Login → Mi Dashboard → Mis Mascotas → Mis Citas → Descubrir → Configuración

Capturas de Pantalla

Onboarding Login Dashboard Admin
Onboarding Login Dashboard
Mascotas Detalle Citas
Pets Detail Appointments

Temas y Accesibilidad

Modo Claro Modo Oscuro Configuración
Interfaz clara optimizada para uso diurno Interfaz oscura que reduce fatiga visual Ajustes de tema y accesibilidad

Las opciones de tema y accesibilidad están disponibles en Configuración → Apariencia/Accesibilidad


📦 Módulos del Sistema

🔐 Módulo de Autenticación

  • Login con validación de credenciales
  • Validación de email (patrón estándar)
  • Validación de contraseña (mínimo 6 caracteres)
  • Recuperación de contraseña con clave temporal
  • Gestión de sesión persistente
  • Logout con limpieza de estado

🐾 Módulo de Mascotas

  • Listado con filtros (especie, dueño, búsqueda)
  • Ordenamiento múltiple
  • CRUD completo (crear, leer, actualizar, eliminar)
  • Perfil detallado con historial médico
  • Registro de vacunas con fechas de aplicación
  • Fotos de perfil con fallback visual

📅 Módulo de Citas

  • Listado filtrable por estado (próximas, hoy, completadas, canceladas)
  • Búsqueda por mascota o veterinario
  • Creación con selección de fecha/hora
  • Asignación de veterinario
  • Cambio de estado
  • Cancelación con confirmación

👨‍⚕️ Módulo de Veterinarios

  • Directorio completo del staff
  • Información de especialidad y contacto
  • Estadísticas por veterinario
  • CRUD para administradores
  • Agenda de citas por profesional

🔔 Sistema de Notificaciones

  • Recordatorios automáticos de citas
  • Alertas de vacunas próximas
  • Implementación con WorkManager
  • Cancelación automática al logout

🎨 Sistema de Temas

La aplicación implementa un sistema de temas completo que se adapta a las preferencias del usuario:

Modo Descripción
☀️ Claro Fondo claro con texto oscuro, ideal para uso diurno
🌙 Oscuro Fondo oscuro que reduce fatiga visual en ambientes con poca luz
🔄 Automático Se adapta automáticamente según la configuración del sistema

Implementación técnica:

  • Persistencia de preferencias con SharedPreferences
  • Colores dinámicos usando CompositionLocal
  • Transición suave entre temas sin reiniciar la app
  • Respeto por la configuración del sistema operativo

♿ Accesibilidad

VetCare está diseñado siguiendo las pautas de accesibilidad de Android para garantizar una experiencia inclusiva:

Característica Descripción
Alto Contraste Modo con colores más intensos para mejor legibilidad
Reducir Animaciones Minimiza el movimiento para usuarios sensibles
TalkBack Compatible contentDescription en todos los elementos interactivos
Áreas Táctiles Mínimo 48dp en elementos clickeables
Jerarquía Visual Tipografía diferenciada y espaciado consistente

Ratios de contraste implementados:

Modo Background Text Ratio WCAG
Claro #EEF1F7 #12131A 13.5:1 ✅
Oscuro #0F1117 #E8E9ED 14.2:1 ✅
Alto Contraste #FFFFFF #000000 21:1 ✅

📊 Registro de Actividad

  • Logging centralizado de acciones
  • Filtros avanzados (fecha, pantalla, acción, usuario)
  • Búsqueda en tiempo real
  • Exportación de registros
  • Visualización para auditoría

🔍 Debug & Profiling

Módulo completo de herramientas de diagnóstico y monitoreo de rendimiento, accesible desde Configuración → Desarrollo → Debug & Profiling.

Sistema de Logging Avanzado

Tag Propósito
VETCARE_DEBUG Logs generales de debugging
VETCARE_PERF Métricas de rendimiento
VETCARE_ERROR Errores y excepciones
VETCARE_DB Operaciones de base de datos
VETCARE_COROUTINE Flujos de coroutines
VETCARE_VIEWMODEL Operaciones del ViewModel

Niveles de Log

Nivel Uso
🔍 DEBUG Información detallada de desarrollo
ℹ️ INFO Eventos importantes del flujo normal
⚠️ WARN Situaciones potencialmente problemáticas
❌ ERROR Errores que no detienen la ejecución
💀 FATAL Errores críticos

Excepciones Personalizadas

VetCareException (base)
├── DatabaseException         // Errores de Room Database
├── EntityNotFoundException   // Entidad no encontrada
├── TimeoutException          // Operación excedió tiempo límite
├── ValidationException       // Error de validación
├── AuthenticationException   // Error de autenticación
├── SessionException          // Sesión expirada
└── BusinessLogicException    // Error de lógica de negocio

Métricas de Rendimiento

La pantalla de Debug & Profiling permite:

  • Ejecutar flujos críticos con medición de tiempo
  • Visualizar métricas de cada operación de BD
  • Comparar rendimiento paralelo vs secuencial
  • Detectar operaciones lentas (>500ms)
  • Monitorear uso de memoria
  • Simular errores para probar el manejo de excepciones

Análisis de Memoria y Detección de Memory Leaks

La aplicación ha sido sometida a un diagnóstico exhaustivo de gestión de memoria utilizando herramientas profesionales de profiling.

Android Profiler - Análisis de Heap
Métrica Valor Estado
Total Memory 156.1 MB ✅ Normal
Java Heap 16.7 MB ✅ Óptimo
Native Memory 19.8 MB ✅ Normal
Objects in Memory 118,228 ✅ Controlado
Retained Size ~2.7 MB ✅ Saludable
Leaks Detected 0 ✅ Sin fugas
Duplicates 0 ✅ Sin duplicados
Heap Dump Analysis Live Memory Monitoring
Profiler Live Memory

Observaciones técnicas:

  • El gráfico de memoria presenta comportamiento estable sin patrones de "escalera" (memoria que incrementa sin liberarse)
  • No se detectó fragmentación de heap ni allocations excesivas durante la navegación
  • El Garbage Collector (GC) ejecuta ciclos de recolección normales sin pausas prolongadas
  • Las clases con mayor consumo (EmojiCompat: 353 KB, Bitmap: 211 KB) están dentro de rangos normales para aplicaciones con UI
LeakCanary - Detección Automatizada

Se integró LeakCanary v2.14 como dependencia de debug para detección automática de fugas de memoria:

// app/build.gradle.kts
debugImplementation(libs.leakcanary.android)
LeakCanary Monitoring
LeakCanary

Flujos de prueba ejecutados:

  • Navegación repetitiva: Dashboard → Mascotas → Detalle → Back (×10 iteraciones)
  • Rotación de pantalla en múltiples Activities
  • Apertura/cierre de diálogos y BottomSheets
  • Ejecución de operaciones asíncronas con coroutines
  • Destrucción de Activities y Fragments mediante navegación hacia atrás

Resultado del análisis: Los logs de LeakCanary (tag:LeakCanary) no reportaron instancias de APPLICATION LEAK ni ACTIVITY LEAK, confirmando:

Componente Estado Verificación
ViewModels ✅ Correcto Se liberan al invocar onCleared()
Coroutines ✅ Correcto Cancelación automática con viewModelScope
Context References ✅ Correcto Sin referencias estáticas a Activity/Fragment
Listeners/Callbacks ✅ Correcto Desuscripción automática con lifecycle-aware pattern
Compose Functions ✅ Correcto Uso adecuado de remember y DisposableEffect
Conclusión del Análisis de Memoria

La arquitectura MVVM implementada con Jetpack Compose, StateFlow y viewModelScope proporciona un manejo de ciclo de vida robusto que previene las fugas de memoria comunes en aplicaciones Android. Los componentes se liberan correctamente cuando salen del scope de composición o cuando las Activities/Fragments son destruidos.

Estado: ✅ Gestión de memoria óptima - Sin anomalías detectadas


🧪 Testing

La aplicación implementa una suite de pruebas exhaustiva que abarca tanto pruebas unitarias (JUnit + MockK) como pruebas funcionales instrumentadas (Compose UI Testing / Espresso), garantizando la calidad y confiabilidad del sistema.

Pruebas Unitarias (JUnit)

Se desarrollaron 4 clases de prueba enfocadas en la validación de lógica de negocio, transformaciones de datos e integridad del modelo de dominio:

Clase de Prueba Tests Propósito
EntityMappersTest 18 Transformaciones bidireccionales Entity↔Model (User, Pet, Appointment, VaccineRecord, Owner)
SessionManagerTest 17 Lógica de autenticación: login, logout, roles (Admin/Owner), estado de sesión
ConvertersTest 24 TypeConverters de Room: LocalDateTime, LocalDate, Enums (UserRole, PetSpecies, AppointmentStatus)
ModelValidationTest 31 Reglas de negocio, invariantes de datos, filtrado, ordenamiento y validaciones de formulario

Ejecución:

./gradlew :app:testDebugUnitTest

Aspectos de lógica de negocio testeados:

  • ✅ Integridad referencial en mappers (roundtrip Entity→Model→Entity)
  • ✅ Serialización/deserialización de tipos complejos (ISO 8601)
  • ✅ Gestión de estado de sesión (StateFlow reactivo)
  • ✅ Validación de formularios (email, contraseña, edad de mascotas)
  • ✅ Filtrado de mascotas por especie, dueño y búsqueda case-insensitive
  • ✅ Ordenamiento de listas por nombre y edad
  • ✅ Filtrado de citas por estado
  • ✅ Manejo de valores nulos en campos opcionales
  • ✅ Edge cases: strings inválidas, listas vacías, múltiples logouts

Pruebas Funcionales Instrumentadas (Compose UI Testing)

Se implementaron 2 clases de prueba instrumentada que simulan interacciones reales del usuario:

Clase de Prueba Tests Pantalla Testeada
LoginScreenTest 8 Pantalla de Login — Renderizado, ingreso de datos, navegación
PetFormValidationTest 5 Formulario de Mascotas — Campos, chips de especie, navegación

Ejecución (requiere emulador o dispositivo):

./gradlew :app:connectedDebugAndroidTest

Interacciones de usuario verificadas:

  • ✅ Renderizado correcto de componentes UI (logo, subtítulo, campos, botones)
  • ✅ Ingreso de datos en campos de email y contraseña
  • ✅ Callback de navegación "Olvidaste tu contraseña"
  • ✅ Botón de login habilitado e interactuable
  • ✅ Visualización de credenciales de prueba
  • ✅ Flujo completo: Onboarding → Login → Dashboard → Mascotas → Formulario
  • ✅ Visualización de campos del formulario de mascotas (nombre, especie, raza, edad)
  • ✅ Selección de especie mediante chips (Perro, Gato, Ave, Conejo)
  • ✅ Ingreso de texto en el campo nombre del formulario
  • ✅ Navegación de vuelta desde el formulario a la lista de mascotas
  • ✅ Estabilidad de la UI sin crashes

Stack de Testing

Dependencia Tipo Propósito
JUnit 4.13.2 testImplementation Framework de pruebas unitarias
MockK 1.13.8 testImplementation Mocking de clases Kotlin
Coroutines Test 1.7.3 testImplementation Testing de operaciones async
Arch Core Testing 2.2.0 testImplementation Testing de LiveData/ViewModel
Compose UI Test JUnit4 androidTestImplementation Framework de pruebas de UI Compose
Espresso Core 3.5.1 androidTestImplementation Interacciones de UI instrumentadas
Navigation Testing 2.7.7 androidTestImplementation Testing de navegación
Room Testing 2.7.0 androidTestImplementation Testing de base de datos

📦 APK Firmado (Release)

La aplicación cuenta con un APK firmado listo para distribución, generado con keystore dedicado.

Parámetro Valor
Nombre de la app VetCare
Application ID com.example.vetcare_android_kotlin_compose_mvvm
Version Code 3
Version Name 1.3
Min SDK API 26 (Android 8.0)
Target SDK API 35 (Android 15)
Compile SDK API 36
Ícono Ícono personalizado (ic_launcher-playstore.png)
Signing Keystore dedicado con configuración en signingConfigs
ProGuard Configurado (proguard-rules.pro)

Generación del APK:

./gradlew assembleRelease

El APK firmado se encuentra en:

app/build/outputs/apk/release/app-release.apk

💾 Base de Datos Local (Room)

La aplicación implementa persistencia local completa utilizando Room Database, permitiendo operaciones sin conexión a internet.

Esquema de Base de Datos

┌─────────────────────────────────────────────────────────────────┐
│                     vetcare_database                             │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────────────┐  │
│  │   users     │    │   owners    │◄───│       pets          │  │
│  │─────────────│    │─────────────│    │─────────────────────│  │
│  │ id (PK)     │    │ id (PK)     │    │ id (PK)             │  │
│  │ email       │    │ fullName    │    │ ownerId (FK)        │  │
│  │ passwordHash│    │ email       │    │ name, species       │  │
│  │ role        │    │ phone       │    │ breed, ageYears     │  │
│  └─────────────┘    └─────────────┘    └─────────────────────┘  │
│                                                │                 │
│  ┌─────────────────────┐    ┌──────────────────▼──────────────┐ │
│  │   veterinarians     │    │         appointments            │ │
│  │─────────────────────│    │─────────────────────────────────│ │
│  │ id (PK)             │◄───│ id (PK)                         │ │
│  │ name, specialty     │    │ petId (FK), vetId (FK)          │ │
│  │ phone               │    │ dateTime, reason, status        │ │
│  └─────────────────────┘    └─────────────────────────────────┘ │
│                                                                  │
│  ┌─────────────────────┐    ┌─────────────────────────────────┐ │
│  │   consultations     │    │       vaccine_records           │ │
│  │─────────────────────│    │─────────────────────────────────│ │
│  │ id (PK)             │    │ id (PK)                         │ │
│  │ petId (FK)          │    │ petId (FK)                      │ │
│  │ vetId (FK)          │    │ vaccineName                     │ │
│  │ diagnosis           │    │ lastDate, nextDueDate           │ │
│  │ treatment           │    │                                 │ │
│  └─────────────────────┘    └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Características de Persistencia

Característica Implementación
Base de datos SQLite via Room 2.7.0
Operaciones CRUD completo (Create, Read, Update, Delete)
Relaciones Foreign Keys con CASCADE delete
Tipos complejos TypeConverters para LocalDateTime y Enums
Consultas Flow para datos reactivos, suspend para operaciones
Inicialización Datos de demostración precargados

🌐 Integración de Librería Externa: Retrofit

La aplicación integra Retrofit 2.9.0 como cliente HTTP para comunicación con APIs REST, preparando la arquitectura para futuras integraciones con backend.

Justificación Técnica de Retrofit

Criterio Retrofit HttpURLConnection Ktor Volley
Type Safety ✅ Alto (interfaces) ❌ Manual ✅ Alto ⚠️ Medio
Boilerplate ✅ Mínimo ❌ Extenso ✅ Mínimo ⚠️ Medio
Coroutines ✅ Nativo ❌ Manual ✅ Nativo ❌ Callbacks
Interceptors ✅ OkHttp ❌ Manual ✅ Plugins ⚠️ Limitado
Comunidad ✅ Muy amplia ⚠️ Básica ⚠️ Creciendo ⚠️ Legacy
Documentación ✅ Excelente ⚠️ Básica ✅ Buena ⚠️ Desactualizada
Mantenimiento ✅ Square (activo) ✅ Android ✅ JetBrains ⚠️ Google (bajo)

Decisión: Se eligió Retrofit por:

  1. Estándar de la industria para Android (>90% de apps en producción)
  2. Integración nativa con Coroutines via funciones suspend
  3. OkHttp como base con interceptors para logging, auth y retry
  4. Conversión automática JSON ↔ Kotlin con Gson
  5. Mantenimiento activo por Square Inc.

Arquitectura de la Capa de Red

┌─────────────────────────────────────────────────────────────────┐
│                      NETWORK LAYER                               │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐  │
│  │  VetCareApi     │    │  RetrofitClient │    │  OkHttp     │  │
│  │   Service       │◄───│   (Singleton)   │◄───│  Client     │  │
│  │  (Interface)    │    │   + Gson        │    │ +Interceptor│  │
│  └─────────────────┘    └─────────────────┘    └─────────────┘  │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐    ┌─────────────────┐                     │
│  │ RemoteDataSource│    │  NetworkResult  │                     │
│  │  (API Calls)    │───►│ (Success/Error) │                     │
│  └─────────────────┘    └─────────────────┘                     │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐    ┌─────────────────┐                     │
│  │   DTO Mappers   │───►│  Domain Models  │                     │
│  │ (JSON ↔ Kotlin) │    │  (Pet, Owner..) │                     │
│  └─────────────────┘    └─────────────────┘                     │
└─────────────────────────────────────────────────────────────────┘

Estructura de Archivos de Red

data/remote/
├── api/
│   └── VetCareApiService.kt    # Interfaz Retrofit con endpoints
├── dto/
│   └── ApiDtos.kt              # Data Transfer Objects (JSON)
├── mapper/
│   └── DtoMappers.kt           # Conversión DTO ↔ Domain Models
├── RetrofitClient.kt           # Configuración singleton de Retrofit
├── RemoteDataSource.kt         # Encapsulación de llamadas API
└── NetworkResult.kt            # Sealed class para resultados

Endpoints Implementados

Módulo Endpoints Métodos HTTP
Auth /api/auth/login, /register, /reset-password POST
Pets /api/pets, /pets/{id}, /pets/owner/{id} GET, POST, PUT, DELETE
Appointments /api/appointments, /appointments/pet/{id} GET, POST, PUT, PATCH
Veterinarians /api/veterinarians, /veterinarians/{id} GET
Consultations /api/consultations/pet/{id} GET, POST
Vaccines /api/vaccines/pet/{id} GET, POST
Owners /api/owners/{id} GET, PUT

Características Implementadas

// RetrofitClient.kt - Configuración centralizada
object RetrofitClient {
    private val okHttpClient = OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .addInterceptor(loggingInterceptor)  // Logging en debug
        .addInterceptor { chain ->           // Headers comunes
            chain.proceed(chain.request().newBuilder()
                .header("Accept", "application/json")
                .header("Content-Type", "application/json")
                .build())
        }
        .build()
}

Manejo de Respuestas con NetworkResult

// NetworkResult.kt - Patrón sealed class
sealed class NetworkResult<out T> {
    data class Success<out T>(val data: T) : NetworkResult<T>()
    data class Error(val message: String, val code: Int?) : NetworkResult<Nothing>()
    data object Loading : NetworkResult<Nothing>()
}

// Uso en ViewModel
when (result) {
    is NetworkResult.Success -> _uiState.value = result.data
    is NetworkResult.Error -> _error.value = result.message
    is NetworkResult.Loading -> _isLoading.value = true
}

Justificación: ¿Por qué NO se usa Glide?

Aspecto Decisión Justificación
Sistema actual Recursos locales (R.drawable.*) Imágenes embebidas en APK
Rendimiento ✅ Óptimo Sin latencia de red para cargar imágenes
Offline ✅ Completo Funciona sin conexión a internet
Tamaño APK ⚠️ Aumenta Trade-off aceptable para demo/prototipo
Futuro Glide cuando se integre backend Cuando las imágenes vengan de servidor

Conclusión: Glide se integrará en versión 2.0 cuando la app se conecte a un backend real con URLs de imágenes. Actualmente, el sistema de recursos locales es más eficiente para el caso de uso.


🔄 Flujo de Usuario

graph TD
    A[Onboarding] --> B[Login]
    B --> C{Rol?}
    C -->|Admin| D[Dashboard Admin]
    C -->|Owner| E[Dashboard Owner]
    
    D --> F[Gestión Mascotas]
    D --> G[Gestión Citas]
    D --> H[Staff Veterinario]
    D --> I[Activity Log]
    D --> P[Configuración]
    
    E --> J[Mis Mascotas]
    E --> K[Mis Citas]
    E --> L[Descubrir]
    E --> Q[Configuración]
    
    P --> R[Debug & Profiling]
    Q --> R
    
    F --> M[CRUD Mascotas]
    G --> N[CRUD Citas]
    H --> O[CRUD Veterinarios]
Loading

🗺 Roadmap

Versión 1.0 ✅

  • Sistema de autenticación
  • Gestión de mascotas (CRUD completo)
  • Gestión de citas
  • Gestión de veterinarios
  • Notificaciones automáticas
  • Registro de actividad
  • UI/UX Material 3
  • Sistema de temas (Claro/Oscuro/Automático)
  • Accesibilidad (Alto contraste, TalkBack, reducir animaciones)
  • Persistencia local con Room Database (SQLite)
  • Operaciones offline sin conexión a internet

Versión 1.1 ✅ (Optimización de Rendimiento)

  • Procesamiento asincrónico con Kotlin Coroutines
  • Carga paralela de datos con async/await
  • Dispatchers optimizados (IO para BD, Default para CPU)
  • Pull-to-refresh sin bloqueo de UI
  • Debounce en búsquedas (300ms)
  • Fire-and-forget para logging de actividad
  • Flow reactivo desde Room Database

Versión 1.2 ✅ (Debug & Profiling)

  • Sistema de logging avanzado con tags personalizados
  • Excepciones personalizadas del dominio (VetCareExceptions)
  • Herramientas de Debug & Profiling integradas
  • Métricas de rendimiento en tiempo real
  • Manejo estructurado de errores (try-catch)
  • Simulación de errores para testing
  • Actualización a Room 2.7.0

Versión 1.3 ✅ (Memory Profiling & Optimization)

  • Integración de LeakCanary v2.14 para detección de memory leaks
  • Análisis exhaustivo con Android Profiler (heap dump, allocations, GC)
  • Validación de gestión de memoria en flujos críticos
  • Verificación de liberación correcta de ViewModels y Coroutines
  • Confirmación de ausencia de referencias estáticas indebidas
  • Documentación de métricas de memoria y resultados de análisis

Versión 1.4 ✅ (Integración de Librerías Externas)

  • Integración de Retrofit 2.9.0 para API REST
  • Configuración de OkHttp 4.12.0 con interceptors
  • Serialización JSON con Gson 2.10.1
  • Capa de red completa: DTOs, Mappers, DataSource
  • NetworkResult sealed class para manejo de respuestas
  • Endpoints preparados para 7 módulos (Auth, Pets, Appointments, etc.)
  • Documentación de justificación técnica vs alternativas

Versión 1.5 ✅ (Release & Distribución)

  • Generación de APK firmado (release) con keystore dedicado
  • Configuración de signingConfigs en build.gradle.kts
  • Actualización de versión: versionCode = 3, versionName = "1.3"
  • Creación de ícono personalizado para Play Store (ic_launcher-playstore.png)
  • Configuración de nombre de app, permisos y metadatos de distribución
  • Redirección del build directory fuera de iCloud Drive para estabilidad de compilación
  • ProGuard rules configuradas para release

Versión 2.0 🔜

  • Integración con backend REST API
  • Autenticación con Firebase Auth
  • Sincronización cloud
  • Chat en tiempo real
  • Telemedicina veterinaria
  • Pagos integrados

Versión 3.0 📋

  • Módulo de farmacia
  • Gestión de inventario
  • Reportes y analíticas avanzadas
  • Multi-idioma (i18n)
  • Backup automático en la nube

👨‍💻 Autor

Rodrigo Sánchez

Rodrigo Sánchez

Full Stack Developer


Portfolio Email

LinkedIn CV

Agenda


¿Tienes una idea de proyecto? Conversemos cómo puedo ayudarte.


📄 Licencia

Este proyecto está bajo la Licencia MIT. Consulta el archivo LICENSE para más detalles.


Footer

Desarrollado con Kotlin, Jetpack Compose & Room Database

⭐ Si este proyecto te resultó útil, considera darle una estrella


🤝 Contribuciones

¡Las contribuciones son bienvenidas! Este proyecto está abierto a la comunidad y agradecemos toda ayuda para mejorarlo.

🌟 ¿Cómo Contribuir?

  1. Lee la guía: Revisa CONTRIBUTING.md para conocer las normas de contribución
  2. Encuentra un issue: Busca issues etiquetados como good first issue
  3. Fork & Branch: Crea un fork y una rama para tu contribución
  4. Desarrolla: Implementa tu mejora siguiendo las convenciones de código
  5. Testing: Asegúrate de que todos los tests pasen
  6. Pull Request: Envía tu PR con una descripción clara

📋 Áreas de Contribución

  • 🎨 UI/UX: Mejoras visuales, animaciones, Material Design 3
  • 🧪 Testing: Tests unitarios, tests de UI, cobertura
  • Accesibilidad: Soporte TalkBack, contraste, navegación
  • Performance: Optimizaciones, lazy loading, caching
  • 🌍 i18n: Traducciones y localización
  • 📱 Features: Nuevas funcionalidades para clínicas veterinarias
  • 📚 Documentación: Mejoras en docs, tutoriales, ejemplos

🎯 Good First Issues

Perfecto para comenzar:

  • #1 🌙 Agregar soporte para tema oscuro
  • #2 ♿ Mejorar soporte de TalkBack
  • #3 ⚡ Optimizar rendimiento de listas
  • #4 🧪 Agregar tests unitarios
  • #5 🌍 Mejorar traducciones al español

Ver todos los Good First Issues →

💬 Código de Conducta

Este proyecto sigue el Código de Conducta de Contributor Covenant. Al participar, aceptas mantener un ambiente respetuoso y acogedor para todos.

👥 Colaboradores

Gracias a todas las personas que han contribuido a VetCare:


About

🐾 Sistema de gestión para clínicas veterinarias con Android nativo, Kotlin, Jetpack Compose y Material Design 3. PRs bienvenidos!

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages