Skip to content
This repository was archived by the owner on Aug 14, 2026. It is now read-only.
VECTORG99Public archive

About

App Android (Kotlin) — marketplace de beats musicales. MVVM + Supabase + Room + Material Design 3.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

📚 Proyecto educativo — Este repositorio forma parte de mi formación temprana en DUOC UC (Instituto Profesional). Las prácticas aquí reflejadas corresponden al momento de desarrollo y pueden no representar estándares actuales.

🎵 FullSound

Tienda de beats musicales para Android, desarrollada en Kotlin

Kotlin 1.9.22 Android Material Design 3 MVVM License MIT

Arquitectura · Funcionalidades · Estructura · Instalación · Tests · Configuración


FullSound es una aplicación Android desarrollada en Kotlin que funciona como una tienda de beats musicales. Permite a los usuarios comprar y vender instrumentales, gestionar un carrito de compras y administrar su perfil.

Arquitectura

  • MVVM (Model-View-ViewModel)

  • Supabase (Base de datos remota)

  • Room Database (Caché local)

  • Navigation Component

  • Material Design 3

  • Retrofit + OkHttp (API Fixer para conversión de monedas)

  • Sistema de autenticación de usuarios (Login y Registro).

  • Gestión completa de Beats (Crear, Leer, Actualizar, Eliminar).

  • Carrito de compras funcional.

  • Base de datos en la nube mediante Supabase.

  • Interfaz de usuario moderna basada en Material Design 3.

  • Navegación fluida utilizando Navigation Component.

Arquitectura y Tecnologías

El proyecto sigue el patrón de arquitectura MVVM (Model-View-ViewModel) para asegurar una separación clara de responsabilidades y facilitar el mantenimiento.

  • Lenguaje: Kotlin 1.9.22
  • Arquitectura: MVVM
  • Base de Datos: Supabase (remota) + Room (caché local)
  • UI: XML con ViewBinding y componentes de Jetpack Compose
  • Navegación: Navigation Component
  • Diseño: Material Design 3
  • SDK mínimo: Android 7.0 (API 24) · Objetivo: API 34

Estructura del Proyecto

FullSound-KOTLIN/
├── app/
│   ├── build.gradle.kts              # Configuración del módulo app
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/com/grupo8/fullsound/
│       │   │   ├── MainActivity.kt
│       │   │   ├── data/
│       │   │   │   ├── local/            # Room DAOs y AppDatabase
│       │   │   │   └── remote/
│       │   │   │       ├── dto/          # Data Transfer Objects
│       │   │   │       ├── fixer/        # Integración API Fixer (conversión monedas)
│       │   │   │       └── supabase/     # Cliente y repositorios Supabase
│       │   │   ├── model/               # Entidades de datos (Beat, User, CarritoItem)
│       │   │   ├── repository/          # Capa de repositorios
│       │   │   ├── ui/
│       │   │   │   ├── auth/            # Fragments de Login y Registro
│       │   │   │   ├── beats/           # Catálogo y lista de beats
│       │   │   │   ├── Carrito/         # Carrito de compras
│       │   │   │   ├── profile/         # Fragment de Perfil de usuario
│       │   │   │   └── theme/           # Tema Compose (Color, Type, Theme)
│       │   │   ├── utils/               # Utilidades (validadores, sesiones, etc.)
│       │   │   └── viewmodel/           # ViewModels (Carrito, Login, Beats, Register)
│       │   └── res/                     # Recursos (layouts, drawables, animaciones, raw)
│       ├── androidTest/                 # Tests instrumentados (UI/Recursos)
│       └── test/                        # Tests unitarios
├── gradle/
│   └── libs.versions.toml              # Catálogo de versiones
├── build.gradle.kts                    # Build script raíz
├── settings.gradle.kts
├── gradle.properties
├── local.properties.example            # Plantilla de credenciales (ver Configuración)
├── LICENSE
└── README.md

Capturas de pantalla

📸 Screenshots coming soon — Las capturas de pantalla se agregarán en una próxima actualización.

Instalación y Compilación

Para compilar y ejecutar el proyecto, utilice el siguiente comando en la terminal:

# Compilar la aplicación
./gradlew assembleDebug

# Generar APK firmado
./gradlew assembleRelease

Nota: En Windows usa gradlew.bat en lugar de ./gradlew.

Tests

# Ejecutar todos los tests unitarios
./gradlew test

# Ejecutar tests instrumentados (requiere dispositivo/emulador)
./gradlew connectedAndroidTest

# Ejecutar tests específicos
./gradlew test --tests "com.grupo8.fullsound.model.*"
./gradlew test --tests "com.grupo8.fullsound.viewmodel.*"

Tests Disponibles

  • ✅ Tests de Modelos (Beat, User, CarritoItem) - 20 tests
  • ✅ Tests de Repositorios (Beat, User, Carrito) - casos éxito/fallback/error
  • ✅ Tests de ViewModels (Beats, Login, Register, Carrito)
  • ✅ Tests de Utilidades (FormValidator, RutValidator, Constants) - 13 tests
  • ✅ Tests de API (ExchangeRateProvider) - 2 tests
  • ✅ Tests Instrumentados (UI/Recursos) - 8 tests

Funcionalidades Implementadas

  • ✅ Sistema de autenticación con Supabase Auth / GoTrue (Login/Registro) — ver docs/AUTH.md
  • ✅ Roles de usuario (User/Admin/Productor) determinados por id_rol en la tabla usuario (no por el dominio del correo)
  • ✅ CRUD completo de Beats conectado a Supabase
  • ✅ Catálogo de Beats desde base de datos remota
  • ✅ Búsqueda en tiempo real de beats por título, artista o género en BeatsListaFragment (barra de búsqueda con TextWatcher)
  • ✅ Estados de UI reutilizables (carga, vacío y error con botón de reintentar) mediante layout_loading.xml, layout_empty.xml y layout_error.xml, integrados en BeatsListaFragment y BeatsFragment
  • ✅ Fragment de Perfil (ProfileFragment) que muestra nombre, usuario, email, RUT y rol del usuario autenticado, con botón de cerrar sesión. Accesible desde la barra de navegación inferior
  • ✅ Imágenes y audios desde Supabase Storage (buckets)
  • ✅ Conversión de monedas CLP ↔ USD con API de Fixer
  • ✅ Carrito de compras con persistencia local
  • ✅ Reglas de negocio (No se puede agregar más de un beat duplicado)
  • ✅ Manejo de errores consistente: todos los repositorios exponen resultados mediante Resource<T> (Loading/Success/Error)
  • ✅ Strings externalizados en strings.xml (sin textos hardcoded en Kotlin)
  • ✅ KDoc en las APIs públicas (repositorios, ViewModels y utilidades)
  • ✅ Persistencia híbrida: Supabase (remoto) + Room (caché local)
  • ✅ Navegación con Navigation Component
  • ✅ Animaciones personalizadas
  • ✅ Material Design 3
  • ✅ Arquitectura MVVM
  • ✅ Tests unitarios e instrumentados (35+ tests)

Búsqueda de beats

La pantalla de catálogo (BeatsListaFragment) incluye una barra de búsqueda que filtra la lista en tiempo real a medida que el usuario escribe. La búsqueda es insensible a mayúsculas/minúsculas y compara el texto contra el título, artista y género de cada beat. Se combina con el filtro por género existente, por lo que ambos criterios se aplican simultáneamente. Cuando no hay resultados se muestra un estado vacío con un mensaje específico.

Estados de carga / vacío / error

Se añadieron layouts reutilizables para los estados de la UI:

  • layout_loading.xml — indicador de progreso con texto "Cargando…".
  • layout_empty.xml — ilustración + título y subtítulo configurables desde código.
  • layout_error.xml — mensaje de error + botón Reintentar.

Estos layouts se incluyen en los fragments y su visibilidad se alterna según el Resource emitido por el ViewModel. El botón de reintentar vuelve a disparar la carga de datos.

Perfil de usuario

El nuevo ProfileFragment (añadido al nav_graph) muestra la información del usuario en sesión (nombre, usuario, email, RUT y rol) leída desde UserSession, y permite cerrar sesión. Es accesible desde el botón de perfil de la barra de navegación inferior en BeatsFragment, BeatsListaFragment y CarritoFragment.

Configuración de Variables de Entorno

El proyecto usa un archivo local.properties (gitignored) para las credenciales sensibles. Se incluye una plantilla local.properties.example que puedes copiar y completar:

cp local.properties.example local.properties
# Supabase Configuration
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_anon_key

# Fixer API (Conversión de monedas)
FIXER_API_KEY=your_fixer_api_key

🔒 Seguridad: Las credenciales se inyectan en tiempo de compilación mediante BuildConfig. Nunca se suben a Git. Como alternativa, también puedes definir las variables de entorno SUPABASE_URL, SUPABASE_ANON_KEY y FIXER_API_KEY.

Estructura de Base de Datos (Supabase)

Tabla: beat

  • id_beat (PK, auto-increment)
  • titulo, slug, artista
  • precio (CLP), bpm, tonalidad, duracion
  • genero, etiquetas, descripcion
  • imagen_url, audio_url, audio_demo_url
  • reproducciones, estado
  • created_at, updated_at

Tabla: usuario

  • id_usuario (PK, auto-increment)
  • nombre_usuario, correo
  • nombre, apellido
  • id_rol (FK a tipo_usuario) — determina el rol (1=admin, 2=productor, otro=user)
  • activo, created_at, updated_at

🔐 Autenticación: La contraseña no se almacena en esta tabla desde la app ni en el caché local. La autenticación se realiza con Supabase Auth (GoTrue). Consulta docs/AUTH.md para el detalle del flujo, la configuración y las políticas RLS recomendadas.

Buckets de Storage

  • beats-images: Imágenes de beats
  • beats-audio: Archivos de audio de beats

Configuración de Supabase

La app usa Supabase como backend (Postgres + Auth + Storage). Para configurar tu propio proyecto:

  1. Crea un proyecto en supabase.com.

  2. Copia local.properties.example a local.properties y completa:

    SUPABASE_URL=https://TU_PROYECTO.supabase.co
    SUPABASE_ANON_KEY=tu_anon_key
    FIXER_API_KEY=tu_fixer_api_key

    Estos valores se inyectan en tiempo de compilación vía BuildConfig.

  3. Crea las tablas beat y usuario (y tipo_usuario con los roles) según el esquema de la sección anterior.

  4. Habilita Supabase Auth (proveedor Email) — la autenticación la maneja GoTrue. Consulta docs/AUTH.md para el detalle completo y las políticas RLS recomendadas.

  5. Crea los buckets de Storage Imagenes y audios (públicos o con políticas de lectura).

  6. Si cambias de proyecto de Supabase, verifica que el dominio en app/src/main/res/xml/network_security_config.xml coincida con tu SUPABASE_URL (el dominio genérico supabase.co ya cubre todos los subdominios).

Migraciones de Room (base de datos local)

La base de datos local (Room, fullsound_database) usa migraciones incrementales para preservar los datos del usuario al actualizar la app. Las migraciones definidas en AppDatabase.kt:

  • v6 → v7: elimina la columna password de la tabla users (la autenticación ahora se maneja con Supabase Auth; no se persisten contraseñas).
  • v7 → v8: añade índices a beats (slug, titulo, genero) y a carrito (userId, beatId), e incorpora la columna userId a carrito para alinear el caché local con el campo user_id de Supabase.

⚠️ Si modificas las entidades (Beat, CarritoItem, User), recuerda subir la versión de la base de datos en AppDatabase y añadir la migración correspondiente. Sin migración, Room lanza una excepción en tiempo de ejecución al detectar un cambio de esquema.

Solución de problemas (Troubleshooting)

  • La app no carga beats / error de red

    • Verifica que SUPABASE_URL y SUPABASE_ANON_KEY en local.properties sean correctos.
    • Confirma que el dispositivo tenga conexión a internet.
    • Revisa que la tabla beat tenga datos en Supabase.
    • Asegúrate de que el dominio en network_security_config.xml coincida con tu proyecto (el dominio supabase.co con subdominios suele ser suficiente).
  • No puedo iniciar sesión

    • La autenticación se realiza con Supabase Auth (GoTrue). Verifica que el usuario exista en Auth y en la tabla usuario.
    • El rol se obtiene de id_rol en usuario; si es null o distinto de 1/2, el usuario se trata como user normal.
  • No soy admin aunque uso un correo @admin.cl

    • El rol no se detecta por el dominio del correo. Debe estar configurado en la columna id_rol de la tabla usuario (1 = admin).
  • Error de Room: "A migration from X to Y was required but not found"

    • Falta una migración. Revisa la sección anterior y añade la migración en AppDatabase.kt, o incrementa la versión correctamente.
  • Las imágenes/audios no se ven

    • Verifica que los buckets Imagenes y audios existan y sean públicos (o tengan políticas de lectura).
    • Las URLs se construyen a partir de SUPABASE_URL + nombre de archivo.
  • La conversión CLP → USD no funciona

    • Requiere una API key válida de Fixer en FIXER_API_KEY. Sin ella, solo se muestra el precio en CLP.
  • BuildConfig no encuentra SUPABASE_URL

    • Asegúrate de haber creado local.properties (no se sube a Git) o de tener las variables de entorno definidas.

Licencia

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

About

App Android (Kotlin) — marketplace de beats musicales. MVVM + Supabase + Room + Material Design 3.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages