Modelo Emisora con todos los campos pedidos: id, uuid, nombre, url, favicon, pais, idioma, tags, orden
fromMap() / toMap() para serialización SQLite
copyWith() para mutaciones inmutables
== y hashCode por uuid (identidad de negocio)
lib/servicios/servicio_favoritos.dart
Singleton ServicioFavoritos con inicialización lazy (DB se abre en el primer acceso)
Tabla favoritos creada con CREATE TABLE IF NOT EXISTS — idempotente
Índice UNIQUE en uuid + índice en orden
Migration-ready: versión 1, _onUpgrade preparado para futuras versiones sin perder datos
Métodos implementados
Método
Descripción
obtenerTodos()
List<Emisora> ordenado por orden ASC
agregar(Emisora)
Insert + upsert por conflicto en uuid; orden auto al final si viene en 0
eliminar(uuid)
DELETE por uuid, idempotente
esFavorito(uuid)
bool — query ligera solo con id
reordenar(uuid, nuevoOrden)
Actualiza orden de una emisora
reordenarLista(uuids)
Reordena lista completa en una transacción (drag & drop)
contarFavoritos()
int — helper de utilidad
Decisiones de diseño
path package: servicio_favoritos.dart usa package:path/path.dart para construir la ruta de la BD — ya es dependencia transitiva de sqflite en el sdk de Flutter, no requiere añadir nada al pubspec
Orden automático: cuando se llama agregar() con orden = 0 y la emisora es nueva, se asigna MAX(orden) + 1 para que aparezca al final de la lista sin necesidad de recalcular todos los índices
Sin eliminación lógica en esta versión: los favoritos son una lista explícita del usuario; el borrado es intencional y reversible (volviendo a agregar). Si en v2 se necesita historial, se añade eliminado BOOLEAN en la migración
Tests sugeridos para QA
// 1. Agregar y obtener
awaitservicio.agregar(emisora);expect(awaitservicio.obtenerTodos(),contains(emisora));// 2. esFavorito
expect(awaitservicio.esFavorito(emisora.uuid),isTrue);expect(awaitservicio.esFavorito("uuid-inexistente"),isFalse);// 3. Eliminar e idempotencia
awaitservicio.eliminar(emisora.uuid);expect(awaitservicio.esFavorito(emisora.uuid),isFalse);awaitservicio.eliminar(emisora.uuid);// no lanza, devuelve 0
// 4. Reordenar
awaitservicio.reordenar(emisora.uuid,5);finallista=awaitservicio.obtenerTodos();expect(lista.first.orden,equals(5));// 5. Upsert — agregar dos veces no duplica
awaitservicio.agregar(emisora);awaitservicio.agregar(emisora.copyWith(nombre:"Nombre actualizado"));expect(awaitservicio.contarFavoritos(),equals(1));
## PluriWave — ServicioFavoritos (SQLite, sqflite)
### Qué incluye este PR
**`lib/modelos/emisora.dart`**
- Modelo `Emisora` con todos los campos pedidos: `id`, `uuid`, `nombre`, `url`, `favicon`, `pais`, `idioma`, `tags`, `orden`
- `fromMap()` / `toMap()` para serialización SQLite
- `copyWith()` para mutaciones inmutables
- `==` y `hashCode` por `uuid` (identidad de negocio)
**`lib/servicios/servicio_favoritos.dart`**
- Singleton `ServicioFavoritos` con inicialización lazy (DB se abre en el primer acceso)
- Tabla `favoritos` creada con `CREATE TABLE IF NOT EXISTS` — idempotente
- Índice UNIQUE en `uuid` + índice en `orden`
- Migration-ready: versión 1, `_onUpgrade` preparado para futuras versiones sin perder datos
### Métodos implementados
| Método | Descripción |
|--------|-------------|
| `obtenerTodos()` | `List<Emisora>` ordenado por `orden ASC` |
| `agregar(Emisora)` | Insert + upsert por conflicto en `uuid`; orden auto al final si viene en 0 |
| `eliminar(uuid)` | DELETE por uuid, idempotente |
| `esFavorito(uuid)` | `bool` — query ligera solo con `id` |
| `reordenar(uuid, nuevoOrden)` | Actualiza `orden` de una emisora |
| `reordenarLista(uuids)` | Reordena lista completa en una transacción (drag & drop) |
| `contarFavoritos()` | `int` — helper de utilidad |
### Decisiones de diseño
- **`path` package**: `servicio_favoritos.dart` usa `package:path/path.dart` para construir la ruta de la BD — ya es dependencia transitiva de sqflite en el sdk de Flutter, no requiere añadir nada al pubspec
- **Orden automático**: cuando se llama `agregar()` con `orden = 0` y la emisora es nueva, se asigna `MAX(orden) + 1` para que aparezca al final de la lista sin necesidad de recalcular todos los índices
- **Sin eliminación lógica** en esta versión: los favoritos son una lista explícita del usuario; el borrado es intencional y reversible (volviendo a agregar). Si en v2 se necesita historial, se añade `eliminado BOOLEAN` en la migración
### Tests sugeridos para QA
```dart
// 1. Agregar y obtener
await servicio.agregar(emisora);
expect(await servicio.obtenerTodos(), contains(emisora));
// 2. esFavorito
expect(await servicio.esFavorito(emisora.uuid), isTrue);
expect(await servicio.esFavorito("uuid-inexistente"), isFalse);
// 3. Eliminar e idempotencia
await servicio.eliminar(emisora.uuid);
expect(await servicio.esFavorito(emisora.uuid), isFalse);
await servicio.eliminar(emisora.uuid); // no lanza, devuelve 0
// 4. Reordenar
await servicio.reordenar(emisora.uuid, 5);
final lista = await servicio.obtenerTodos();
expect(lista.first.orden, equals(5));
// 5. Upsert — agregar dos veces no duplica
await servicio.agregar(emisora);
await servicio.agregar(emisora.copyWith(nombre: "Nombre actualizado"));
expect(await servicio.contarFavoritos(), equals(1));
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
PluriWave — ServicioFavoritos (SQLite, sqflite)
Qué incluye este PR
lib/modelos/emisora.dartEmisoracon todos los campos pedidos:id,uuid,nombre,url,favicon,pais,idioma,tags,ordenfromMap()/toMap()para serialización SQLitecopyWith()para mutaciones inmutables==yhashCodeporuuid(identidad de negocio)lib/servicios/servicio_favoritos.dartServicioFavoritoscon inicialización lazy (DB se abre en el primer acceso)favoritoscreada conCREATE TABLE IF NOT EXISTS— idempotenteuuid+ índice enorden_onUpgradepreparado para futuras versiones sin perder datosMétodos implementados
obtenerTodos()List<Emisora>ordenado pororden ASCagregar(Emisora)uuid; orden auto al final si viene en 0eliminar(uuid)esFavorito(uuid)bool— query ligera solo conidreordenar(uuid, nuevoOrden)ordende una emisorareordenarLista(uuids)contarFavoritos()int— helper de utilidadDecisiones de diseño
pathpackage:servicio_favoritos.dartusapackage:path/path.dartpara construir la ruta de la BD — ya es dependencia transitiva de sqflite en el sdk de Flutter, no requiere añadir nada al pubspecagregar()conorden = 0y la emisora es nueva, se asignaMAX(orden) + 1para que aparezca al final de la lista sin necesidad de recalcular todos los índiceseliminado BOOLEANen la migraciónTests sugeridos para QA
Pull request closed