Cambios
Lo nuevo de Lomos en cada versión, en lenguaje claro: qué cambia para ti. Formato basado en Keep a Changelog.
v0.11.0
Tanda de pulido sobre la búsqueda, el alta de libros y la invitación, a partir de uso real.
Nuevo
- Priorizar un idioma en la búsqueda: si tu catálogo mezcla idiomas, puedes elegir cuál ver primero. No esconde el resto —solo sube los tuyos arriba— y Lomos recuerda tu elección.
- Más orígenes para los ejemplares: además de "Comprado" y "Regalado", ahora hay Segunda mano, Heredado / familia, Intercambio o gratis y Otro.
Cambios
- La búsqueda es más permisiva: ya no hace falta escribir todas las palabras para encontrar un libro (antes exigía que coincidieran todas), y tolera más erratas al teclear nombres de autor.
- "Quiero leer" se ordena por lo último añadido (lo más reciente arriba), en vez de por título.
- La etiqueta "Solo mío" pasa a llamarse "De préstamo": describe mejor los libros que tienes prestados o leíste fuera de tu librería (de la biblioteca, de un amigo…), que solo ves tú.
- Los libros digitales ya no piden ubicación: al añadir un eBook o audiolibro desaparece el campo de estantería, que no tenía sentido.
- El email de invitación explica cómo llevarte Lomos al móvil: con enlace directo a Google Play y el recordatorio de que, una vez activada la cuenta, entras con el mismo email o cuenta de Google.
Corregido
- Al añadir un libro desde el móvil, el teclado ya no tapa el selector "¿cómo es este libro?": el foco automático en el título se reserva ahora al escritorio.
v0.10.1
Cambios
- La Librería se ordena por defecto por lo último añadido (los libros más recientes arriba), en vez de por título. Y si cambias el orden, Lomos recuerda tu elección la próxima vez que entres — antes volvía al orden por defecto al salir y volver.
v0.10.0
Tanda grande de pulido a partir del segundo audit de UX y
accesibilidad (docs/ux-audit-2026-05-18.md). El foco ha sido que
Lomos funcione bien para todo el mundo —también con teclado o
lector de pantalla— y cerrar cabos sueltos de las últimas versiones.
Nada de esto cambia lo que la app hace; cambia cómo de pulida y
accesible se siente.
Corregido
- El primer paso "Empieza a leer" ya no lleva a una página de error (apuntaba a una ruta retirada). Y algunos elementos de color que habían quedado invisibles tras un cambio interno (la linterna del escáner encendida, ciertos avisos) vuelven a verse.
- Mensajes de error más legibles: el color de los errores tenía poco contraste; ahora cumple el mínimo de accesibilidad.
- Lo que añades desde Lecturas ya no se esconde por un filtro: al abrir la Librería se muestran "Todos" los libros por defecto, así que quien importa solo eBooks ya no la ve "vacía".
- Textos afinados: Casa ya no repite el título, el aviso de "Primeros pasos" apunta a la sección correcta, y la web dice "beta cerrada" y "Cambios" de forma coherente.
Nuevo
- Leyenda de los colores de estado en los filtros de la Librería (qué significa cada punto de color sobre las portadas).
- Aviso de duplicado en todas las altas: si añades un libro con un ISBN que ya tienes —no solo escaneando, también a mano o por búsqueda— Lomos te avisa antes de crear un repetido.
- Compartir invitación más cómodo: al generar el enlace, en el móvil se abre el menú de compartir del sistema (WhatsApp, email…), con aviso de "copiado" si no.
- Exportar tus datos (RGPD) pasa de "Zona peligrosa" a "Privacidad y datos", donde corresponde.
Accesibilidad
- Teclado y lector de pantalla en toda la app: las ventanas y paneles atrapan y devuelven el foco; las pestañas (Lecturas, ficha) y el selector de estado se manejan con las flechas; los menús y filtros anuncian su estado.
- Tamaños táctiles mayores en los controles de uso frecuente.
- Menos movimiento si tu sistema lo pide.
- Foco siempre visible al navegar con teclado, también en oscuro.
Diseño
- Las portadas que no cargan muestran un icono de libro en vez de un rectángulo gris roto.
- Menos hueco vacío al final de las listas cortas.
- Color propio para las estrellas de valoración (coherente entre la app y las imágenes que compartes).
- La tipografía con serifa queda reservada a las citas.
v0.9.3
Pulido del alta de libros tras unos días de uso real. Tres correcciones que arreglan tres dolores distintos.
Corregido
Lo que añades desde Lecturas ya no acaba en la Librería. Antes, si entrabas al alta desde la pestaña Lecturas y elegías "Lo estoy leyendo", el libro se creaba como compartido del hogar y con un ejemplar físico por defecto — la promesa "Librería ≠ Lecturas" se rompía. Ahora el wizard tiene dos contextos claros e independientes:
- Librería: el libro entra como compartido con el hogar y se crea ejemplar.
- Lecturas: el libro entra como privado tuyo, sin ejemplar.
Un nuevo chip "Librería / Lecturas" en la cabecera del wizard muestra a dónde está yendo el libro en cada momento, y cambia con un solo tap si te equivocaste de contexto — sin perder el progreso del paso actual. El selector "¿y tu lectura?" ya solo controla el estado personal del libro (Sin estado / Leyendo / Leído / Quiero leer), no la pertenencia.
Marcar "Lo estoy leyendo" al alta ahora crea la sesión de lectura. Antes el libro quedaba como "Leyendo" en el chip pero sin sesión abierta, así que no aparecía con su "desde hace N días" en Lecturas. Ahora se crea automáticamente una sesión con fecha de inicio = hoy. Si quieres otra fecha, la editas en la pestaña Lectura tras crear.
Nuevo
- Saga clicable en la ficha de libro. Si un libro tiene saga definida ("Iron Widow", "El cementerio de los libros olvidados", etc.), el nombre se muestra como link al buscador y muestra los otros libros de la misma serie que tengas en casa.
v0.9.2
Dos correcciones al estreno de v0.9.1:
Corregido
- El selector "¿cómo es este libro?" ahora arranca en la opción correcta cuando añades un libro desde Lecturas. Si entras al alta vía el botón flotante (+) estando en Quiero leer, Leyendo o Leídos, el selector se posa en el kind que corresponde (privado + el estado del tab) en vez de quedarse siempre en En mi librería. El CTA del empty state ya lo hacía bien; faltaba que el FAB propagase el mismo contexto.
Bajo el capó
- Migración
pendiente→wishlist: default a producción. El scriptscripts/migrate-pendiente-to-wishlist.tsahora apunta a Firestore real por defecto (con la confirmación interactiva ya existente). Para usar el emulator en local se pasaLOMOS_MIGRATE_TARGET=emulatorexplícito. Documentación del comando actualizada con la sintaxis correcta para PowerShell.
v0.9.1
Pulido del alta de libros tras estrenar el split Librería/Lecturas en v0.9.0. Dos cambios que entre sí se piden el uno al otro.
Nuevo
Selector "¿cómo es este libro para ti?" en el alta. Sustituye al viejo checkbox "Solo para mí" por una rejilla de cuatro cards que reconoces a primera vista:
- En mi librería — lo tienes en casa, compartido con la casa.
- Lo estoy leyendo — lo tienes en casa y lo estás leyendo ahora.
- Lo he leído — lectura externa (biblioteca, prestado, ebook de otro sitio…). Privada, no entra en la librería compartida.
- Quiero leer — wishlist personal. Privada.
Con un solo gesto decides a la vez si es del hogar y en qué punto estás con el libro. La sección "Ejemplar" del form solo aparece para los kinds compartidos. El selector arranca con la opción que encaja con el contexto (desde Librería, "En mi librería"; desde Quiero leer, "Quiero leer"; etc.), pero puedes cambiarlo siempre.
Cambios
- Estados unificados:
pendientese fusiona con "Quiero leer". En v0.9.0 quedaban dos estados que en la práctica significaban lo mismo ("aún no he leído este libro"). La diferencia histórica ("lo tengo en casa pero no lo he empezado" vs "no lo tengo") ya la cubreownership, así que mantener los dos era ruido.- El chip de estado ahora muestra siempre Quiero leer — también en filtros y badges.
- Importar de Goodreads sigue reconociendo
to-read/pendiente/pendientes/pending; todos colapsan a "Quiero leer". - Migración de datos automática para los libros que tenías como
pendiente: pasan a "Quiero leer" sin que tengas que tocar nada. (Si por algún motivo no se aplicó la migración en tu cuenta, el chip seguirá funcionando — los datos sin migrar quedan vacíos hasta que les pongas estado a mano.)
Bajo el capó
- Nuevo componente
BookKindSelectorreutilizable.BookFormacepta una nueva propkindSelectoren el alta y mantiene el checkbox "Solo para mí" intacto en edición (donde la semántica es solo cambiarshared↔private, no recategorizar el alta). - Script
scripts/migrate-pendiente-to-wishlist.tsidempotente, con guardLOMOS_MIGRATE_TARGET=prod+ confirmación interactiva para ejecutar contra Firestore real. - Capturas de
/docs/regeneradas.
v0.9.0
Refactor grande de navegación para consolidar lo que es Lomos en dos pilares claros, separados pero conectados:
- Librería es lo que tienes en casa, compartido con tu pareja o familia: papel, ebook, ejemplares, préstamos.
- Lecturas es lo que tú lees, has leído o quieres leer: privado de cada miembro. Puede incluir libros que no están en la librería — algo prestado, de la biblioteca, un audiolibro de Spotify o un libro que viste en redes y quieres apuntar para más adelante.
El cambio no toca el modelo de datos. Lo que cambia es cómo se navega y cómo se presenta. Y, con esta versión, Lomos hace lo que el slogan promete desde la home: "Tus libros y tus lecturas, juntos por fin" — ahora literalmente son dos secciones distintas en el menú principal.
Nuevo
Navegación con dos pilares. El bottom nav en móvil pasa de 5 a 4 slots y queda en Librería · Lecturas · Buscar · Yo. El sidebar en escritorio mantiene 6 ítems con Novedades y Sugerencias añadidos. Stats sale del menú principal — se queda como link dentro de Yo → Mis estadísticas (es uso ocasional).
Página Lecturas unificada. La nueva pestaña sustituye a las tres antiguas (Leyendo / Mis lecturas / Wishlist) con un segmented control en cabecera: Leyendo · Leídos · Quiero leer. La pestaña activa se guarda en la URL (
?tab=...) para que sea bookmarkeable.Pestaña por defecto adaptativa. Si tienes alguna sesión de lectura abierta, al entrar en Lecturas se abre en Leyendo. Si no, en Leídos. Pensado para que el primer click siempre caiga en lo que tiene más probabilidad de querer ver.
Apuntar un libro suelto sin pasar por la Librería. Desde los empty states de Lecturas y de Quiero leer puedes crear un libro como lectura privada — no entra en la librería compartida. Es el flujo natural para apuntar algo que te prestaron, viste en Instagram o vas a sacar de la biblioteca. El back link y el título del wizard cambian de contexto ("Apuntar un libro" en lugar de "Añadir libro a la librería").
Contador del año en Lecturas. Si has cerrado al menos un libro en el año en curso, el subtítulo de la pestaña dice "Llevas N libros este año". Primer paso del reto anual integrado — el dashboard completo sigue en Stats.
Cambios
"Catálogo" → "Librería" en headers, breadcrumbs, empty states y toda la copy visible. "Catálogo" sonaba a inventario; "Librería" comunica posesión personal.
"Físicos" → "Papel" en el toggle de visibilidad de la Librería. Más natural en contexto de lectores que "Físicos", que sonaba a inventario.
Visibilidad de la Librería simplificada de 4 → 3 opciones: Papel · eBook · Todos. La cuarta opción ("Leídos fuera") se retira — esos libros viven ahora en Lecturas, no en la Librería. Coherente con la separación.
Empty states sin duplicar invitaciones. Cuando Lecturas está vacío en las tres pestañas, se muestra un solo empty state global ("Tu historial de lectura está vacío") en lugar de apilarlo con el de la pestaña activa. Cada empty state lleva su CTA específico: "Apuntar mi primer libro", "Empezar una lectura" o "Apuntar un libro" según corresponda.
/yosimplificada. La sección "Mi actividad" pasa de 4 enlaces a 2: Mis estadísticas y Prestados ahora. Los tres antiguos (Leyendo, Mis lecturas, Wishlist) están ahora en la pestaña Lecturas top-level del menú.Landing en
lomos.appalineada con la nueva estructura. El subtítulo del hero deja explícita la separación; las dos primeras feature cards ("Tu librería, compartida con quien convives" y "Tus lecturas, solo tuyas") describen los pilares y qué se comparte y qué no.Sección "Qué hace Lomos" con iconos lineales. Cada feature card lleva ahora un icono minimalista de 28×28 px (stroke 1.5). La séptima card (Escaneo IA en modo avanzado) ocupa todo el ancho del grid como cierre destacado.
Mockup de compartir reseña en la landing actualizado: libro ejemplo cambia a "Las malas" de Camila Sosa Villada con portada real de Open Library, en lugar del placeholder gris.
Back links de las rutas legacy (
/yo/leyendo,/yo/lecturas,/yo/wishlist) ahora apuntan a/lecturasen lugar de/yo. Las rutas legacy siguen vivas para que bookmarks viejos no rompan, pero el back natural lleva al sitio donde realmente vive el contenido.Documentación de
lomos.app/docs/actualizada. Antes había un/docs/catalogoque mezclaba posesión y lectura. Ahora hay/docs/libreria(qué tienes) y/docs/lecturas(qué lees), cada uno con su perfil. El resto de docs (compartir, perfil, empezar) actualizan referencias y matizan privacidad.
Diseño y arquitectura
Nueva
LecturasPageque reusa la lógica de las tres páginas antiguas con dedupe por libro, orden por fecha de fin, manejo de releyendo/abandonados yStaleReadingsAlertintegrado en la pestaña Leyendo.AddBookPageadmite ahora navigation state conintent: 'private'yinitialState: BookState. Cuando llega así, el wizard crea el libro conownership='private'+ aplica el estado tras crear, y ajusta el copy del header y el back link al contexto Lecturas.Los componentes
MyReadingsPage,ReadingPageyWishlistPagequedan montados como rutas legacy pero ya no se enlazan desde el nav principal ni desde/yo. Una versión futura los retirará.
Privacidad (decisión consciente)
- No cambia el modelo de datos. Los miembros de una misma casa pueden, técnicamente, ver el contenido privado de otros miembros vía DevTools de Firestore. Es decisión activa: el modelo de Lomos asume que los miembros de una library son personas que conviven (pareja, familia), no desconocidos. La separación Librería/Lecturas mejora la experiencia de usuario sin pretender que sea barrera contra alguien que ya comparte casa contigo.
v0.8.0
Versión dedicada casi entera a la auditoría UX 2026-05. Tras una revisión sin zalamerías de cómo se sentía la app en el primer minuto de un usuario nuevo, salieron tres conclusiones honestas:
- La app no distinguía "tu librería" de "lo que estás leyendo" en la primera pantalla. Eran dos modelos mentales mezclados.
/yoera una pantalla cajón-de-sastre con 15 secciones del mismo peso visual, mezclando settings cotidianos con power-user.- La landing prometía un feature (escaneo IA) que en la app pedía crear una API key — divergencia grande entre web y app.
Las tres se han abordado, además de un puñado de bugs visuales y
renames de copy confusos. El informe completo queda versionado en
docs/ux-audit-2026-05.md por si quieres
ver el "porqué" detrás de cada decisión.
Nuevo
Onboarding contextual tras tu primer libro. Cuando catalogas el libro inicial (de 0 a 1 en tu librería), la ficha te pregunta con un sheet pequeño: "¿Lo estás leyendo ahora?". Si dices que sí, te abre la sesión de lectura y lo marca como "Leyendo". Si dices que no, queda solo catalogado. Es la forma menos intrusiva de enseñar que catalogar y leer son cosas distintas en Lomos sin meter un tour modal pesado.
Sheet de compartir reseña al cerrar una lectura. Cuando pulsas "Cerrar y marcar como leído" en un libro, te aparece un sheet proponiendo compartir lo que te ha parecido como imagen 1080×1920 (si ya tienes reseña con texto) o invitándote a escribir unas líneas primero (si todavía no la has redactado). Si elegiste "Solo cerrar" sin marcar como leído, el sheet no aparece — interpretamos que esa lectura no te importó lo bastante como para proponer share.
Sección dedicada "Comparte tus reseñas" en la home web. El feature de generar imagen vertical lista para Stories/WhatsApp pasa de ser una card más del grid de features a una sección propia con mockup visual y CTA a la documentación. Es el único mecanismo realista de crecimiento orgánico que tiene Lomos sin presupuesto de marketing — cada reseña compartida es una "publicidad" genuina.
Empty state del catálogo redesignado. Cuando tu librería está vacía ya no ves tres CTAs iguales (Goodreads / Kobo / Manual) compitiendo entre sí. Ahora hay un CTA primario grande ("Cataloga tu primer libro") como camino recomendado, con un separador y dos chips secundarios para importar de Goodreads o Kobo si vienes con historial. Bajo todo eso, un link discreto a la guía rápida en
lomos.app/docs/empezar— antes solo se descubría llegando a la landing.
Cambios
/yopartida en niveles. Antes era un solo scroll plano con 15 secciones del mismo peso. Ahora Mantenimiento (wizard de portadas, enriquecimiento) y Privacidad y datos (audit log, diagnóstico técnico) están plegadas por defecto detrás de un<details>con su hint inline. Las secciones cotidianas (Tu cuenta, Tu librería, Importar libros, Apariencia, Mi actividad, Ayuda) siguen visibles arriba. Cero pérdida de funcionalidad — solo un click más para llegar a las herramientas avanzadas.Tu cuenta y Apariencia más compactas. La card "Tu cuenta" pasa a una sola fila (nombre/email a la izquierda, botón "Cerrar sesión" pequeño a la derecha). La lista de proveedores de login se mueve a un
<details>interno si la necesitas. El toggle de tema pasa a segmented icon-only inline (Monitor / Sun / Moon) — mismo patrón que la web, sin chip redundante "claro/oscuro".Labels renombrados:
- "Ideas" → "Sugerencias" en bottom nav (slot 3) y en el
banner de beta. El item enlaza a
/yo/sugerencia(formulario de feedback); "Ideas" + bombilla daban a entender "ideas de libros" cuando en realidad es "envíame ideas para mejorar la app". - "Externos" → "Leídos fuera" en el toggle de visibilidad del catálogo. Describe el caso real (lecturas pasadas que no son libros físicos de casa) y deja de sonar a "miembros externos" o "API externa".
- "Mejorar ficha" → "Completar ficha" en la ficha del libro. El feature rellena portada y datos automáticamente; "Mejorar" sugería edición manual.
- "Ideas" → "Sugerencias" en bottom nav (slot 3) y en el
banner de beta. El item enlaza a
SideNav (desktop) alineado con BottomNav (mobile). Ahora los dos navs llevan los mismos 5 items: Catálogo · Leyendo · Sugerencias · Stats · Yo. Antes desktop tenía "Novedades" y mobile "Sugerencias", inconsistencia detectada en el audit. El feed de actividad sigue accesible vía la campanita del header del catálogo y por URL directa
/<lib>/novedades.Escaneo IA despromocionado de la home. Antes era la promesa estrella de
lomos.app(primera card del grid con badge "Nuevo", sección hero-secundaria dedicada). Era la mayor divergencia entre lo que vendía la web y lo que entregaba la app — el primer uso en la app pide crear una API key de Google AI Studio, fricción que no se anticipaba. Ahora el feature sigue accesible en su página/escaneoy como card al final del grid, pero sin protagonismo y con copy honesto sobre el setup técnico. En/escaneoel badge cambia de "Nuevo en Lomos" a "Modo avanzado" y se añade un disclaimer prominente sobre los ~5 min de setup con enlace a la guía estándar.Discover (
/yo/descubre) retirado. Era un mini-quiz que recomendaba libros de tu propia biblioteca a partir de 3 favoritos. Útil en principio pero con 2 usuarios beta el ROI era marginal. Aparcado en el backlog (B-050) con criterios claros para reabrir cuando haya base de usuarios. El código original sigue accesible vía git revert si se reactiva.Hero desktop más compacto. El padding vertical del hero pasa de
sm:py-24asm:py-16 lg:py-20. Antes desktop dejaba un hero alto con whitespace enorme antes de la siguiente sección.
Corregido
UID de Firebase expuesto en
/yo/casa. La sección "Miembros" mostraba el UID crudo (jALNgPClGptGaqx9sraVoCBQu8LY) cuando el doc de Firestore no llevabadisplayNameniemail(caso real:consumeSignupCodeguardadisplayName: null). Ahora para tu propio usuario se cogen los datos de Auth (más fiables, sin backfill) y para otros miembros hay un fallback legible.FAB "+" persistente en pantallas donde no aplicaba. Antes aparecía en casi todas las páginas autenticadas. Ahora solo se muestra donde "añadir libro" tiene sentido contextual: catálogo,
/buscar,/yo/leyendo,/yo/wishlist. En/yo,/yo/casa,/stats,/novedades, etc. ya no.FAB solapaba el último item de la lista del catálogo cuando había muchos libros y hacías scroll al final. Subido el padding-bottom del main en mobile para dar clearance al FAB flotante.
Cards de features de la landing podían quedar invisibles si JS no se ejecutaba a tiempo. Tenían
opacity: 0inicial y se hacían visibles solo cuando un IntersectionObserver añadía.is-visible. Si el JS no cargaba (red lenta, crawler, captura fullPage) quedaban invisibles permanentemente. Ahora la reglaopacity: 0solo aplica cuando<html>tiene la clasejs-ready(añadida en el inline script de BaseLayout antes del primer paint). Sin JS, todo se ve desde el principio.
Diseño y arquitectura
Nuevo componente
CollapsibleSection(enMePage.tsx) que usa<details>/<summary>nativo. Sin estado React, accesible por defecto, animación CSS pura.Nuevo componente
FirstBookOnboardingSheetpara el onboarding contextual del primer libro.Nuevo componente
ShareAfterReadingSheetpara la propuesta de share tras "marcar como leído".Eliminados:
src/pages/DiscoverPage.tsx,src/lib/discovery.ts,src/lib/__tests__/discovery.test.ts(Discover retirado).
Documentación
Informe completo de auditoría UX versionado en
docs/ux-audit-2026-05.md: análisis estructurado por flujo, 10 puntos críticos con severidad y esfuerzo, plan de acción priorizado, persona target, lo que el audit NO es. Referencia histórica para no perder el "porqué" detrás de los cambios cuando los PRs se mergeen.Entrada B-050 en
docs/backlog.md(Considerado): "Reintroducir/yo/descubrecuando haya base de usuarios", con contexto, criterios para reabrir y estimación si se reactiva.
v0.7.0
Tres frentes acumulados desde el cierre anterior: escáner más fiable
con linterna para baja luz, animaciones en la landing para que deje de
sentirse estática, y el blog en vivo en lomos.app/blog con los dos
primeros posts pilar — primer paso del plan de contenido / SEO de
soft launch.
Nuevo
Linterna en el escáner. En dispositivos Android donde Chrome permite controlar el flash desde web (cosa que depende del modelo y versión de Android, no de la versión de la app — algunos teléfonos con cámara potente no lo exponen), aparece un botón ⚡ en el visor para encender/apagar la luz del flash sin salir de la app. Soluciona prácticamente todos los fallos de lectura por iluminación pobre. En iOS Apple no soporta esta API y nunca aparecerá; en Android, si no te aparece tras varios intentos, es limitación del WebView de tu dispositivo y no se puede arreglar desde la web.
Animaciones en la landing (
lomos.app). El hero entra en cascada al cargar y lleva un fondo aurora muy sutil que se mueve; las secciones bajo el hero aparecen al hacer scroll en lugar de cargarse todas a la vez; las cards de features se inclinan ligeramente al pasar el cursor por encima (solo desktop). Sin invadir y respetandoprefers-reduced-motionpara quien lo tenga activado.Blog en
lomos.app/blog. Dos primeros posts publicados: "Goodreads no soporta familia: cómo compartir tu biblioteca en casa" y "Cómo importar tu Goodreads a Lomos sin perder ni un libro". Infra completa por debajo: collection Astroblog, layout con schema.org Article + reading time, RSS 2.0 en/blog/rss.xml, sitemap automático que ya incluye/blog/*, e imagen Open Graph dinámica por post (1200×630 con paleta Sunset + logo + título wrapped + tags) que sale bien al compartir en Instagram, WhatsApp, Twitter o LinkedIn. Sin link en el header de momento — accesibles solo vía URL directa hasta que haya más volumen de contenido.Términos de uso y Aviso legal publicados en
lomos.app/docs/terminosylomos.app/docs/aviso-legal(B-005 y B-006). Aviso legal conforme a LSSI-CE con identificación del titular (Juan José Cacho, sin actividad económica registrada durante la beta) y propiedad intelectual; Términos con condiciones de la beta cerrada, acceso por invitación, titularidad del contenido del usuario y licencia limitada para que la app lo muestre solo a su misma librería, limitación de responsabilidad y jurisdicción española. Versión 0 — para v1.0 se revisarán con abogado o se migrarán a plantilla Iubenda/Termly, igual que se hizo con la privacidad. Enlazados en el footer junto a Privacidad.
Cambios
Escáner solo acepta EAN-13 con prefijo Bookland. Antes pasaban EAN-13 de productos no-libro y EAN-8 / UPC-A / UPC-E que añadían ruido al pipeline de estabilización. Ahora el detector filtra a formato
ean_13y descarta los códigos cuyo prefijo no sea 978/979. Resultado: no se confirman como ISBN códigos que no son libros.Estabilización del escáner sube de 2 a 3 lecturas idénticas seguidas. Con 2, en condiciones malas podía colarse un ISBN con un par de dígitos mal leídos que casualmente pasaba la validación de checksum (se observó al escanear un libro español y aparecer
9788013366023, prefijo checo). Con 3 la probabilidad de falso positivo cae a casi cero.Cámara pide resolución 1920×1080 ideal. El driver suele negociar el máximo soportado. Códigos pequeños o lejos del lomo se reconocen mejor sin perder dígitos.
Header de la web en móvil pasa a dos filas. Antes en pantallas <400 px se solapaban logo, links, theme toggle y botón "Entrar". Ahora arriba va
logo · "Lomos"+Entrary debajolinks · theme toggle. Desktop se queda igual que siempre.
Corregido
Race condition al detectar la linterna. Algunos dispositivos Android tardan un instante después de
getUserMedia()en exponertorchengetCapabilities()— antes leíamos demasiado pronto y el botón no aparecía aunque la cámara lo soportara. Ahora reintentamos en t=0, t=400ms y t=1500ms. Si tras los tres intentos sigue sin verse, se registra automáticamente un evento de diagnóstico en/yo/diagnosticocon la lista exacta de capabilities que tu cámara expone, para poder distinguir limitación real del dispositivo de un problema arreglable.Test E2E del flujo "actualizar portada" adaptado al submenú "Mejorar ficha" que entró en v0.6.0. El test seguía esperando el botón "Buscar portada" en la fila principal; ahora hace clic primero en "Mejorar ficha" para desplegar el submenú antes de continuar. Sin este fix CI no desplegaba la PWA en producción.
Diseño y arquitectura
- CLAUDE.md afinado:
- Comandos
pnpm --filter webcorregidos apnpm -C web(el repo no es pnpm workspace y el filtro fallaba con "No projects matched"). - Regla "sin autoría de Claude en commits/PRs" ampliada para
cubrir explícitamente
Co-Authored-By,🤖 Generated with Claude Codey cualquier variante. Aplica a commit messages, bodies de PR y cualquier artefacto del repo.
- Comandos
⚠️ Tras el merge, CI deploya automáticamente. No requiere acciones manuales adicionales (CORS de Storage y TTL de Firestore se configuraron en v0.6.0).
v0.6.0
Cierre del bloque "diagnóstico + enriquecimiento + escaneo robusto". Una página nueva para depurar bugs desde el propio móvil, una acción para repescar metadatos de un libro al momento, y un fix gordo en la imagen de compartir reseña que dejaba portadas vacías.
Nuevo
Mejorar ficha en el detalle de un libro. Botón nuevo que agrupa las acciones que repescan datos de fuentes externas:
- Enriquecer datos: pega Open Library + Google Books y rellena autor, páginas, sinopsis, idioma, categorías… sin tocar lo que hayas editado a mano. Útil para libros que entraron con información incompleta (escaneo que solo sacó el título, imports parciales, alta manual rápida).
- Buscar/actualizar portada: la acción de portada que ya existía, ahora dentro del mismo submenú.
- Mensajes humanos del resultado: "Actualizado: autor, páginas y sinopsis" / "Ya tenías todos los datos" / "No se encontró info adicional".
Diagnóstico técnico en Yo → Diagnóstico técnico → Ver eventos (
/yo/diagnostico). Eventos de lookups, errores y otros sucesos internos visibles desde la propia app, útil para reportar bugs sin tener DevTools a mano (móvil/TWA). Filtros por categoría y nivel, expand del contexto, "Copiar JSON" por evento y "Exportar JSON" global. Cada usuario ve los suyos; el admin ve los de toda la beta para diagnóstico cruzado. Los eventos se borran solos a los 30 días.Buscar por título y autor cuando el ISBN no encuentra nada en Open Library ni Google Books. Antes el flujo te dejaba con "Añadir a mano" o "Probar otro ISBN"; ahora hay una salida natural a la búsqueda por texto, que resuelve la mayoría de libros de editoriales pequeñas y catálogos en español poco indexados.
Cambios
Imagen de compartir reseña lleva ahora un footer con CTA
Cataloga tu librería en lomos.apppara que quien la vea (Stories, WhatsApp Status, chats) pueda llegar a la app. Antes solo decía "Mi librería en Lomos", descriptivo pero sin invitación.Cuota de Google Books: configurada API key del proyecto. Pasa de ~1.000 req/día por IP (anónimo, fácil de saturar con escaneos rápidos o IPs CG-NAT compartidas) a 100.000/día por proyecto. Si varios miembros escanean estanterías en paralelo, no se pisan.
Infraestructura: paso a Firebase Blaze. Activados backups automáticos de Firestore (diario 15 días + semanal 60 días). Coste esperado: céntimos al mes por almacenamiento de los snapshots. Resto sigue dentro del free tier con holgura. Budget alert recomendada en GCP Billing para captar cualquier anomalía.
Corregido
- Portadas vacías en la imagen de compartir cuando la portada
estaba alojada en Firebase Storage (subida por el usuario). Era una
combinación de dos cosas: el bucket no tenía CORS configurado, y
los
<img>del catálogo cargaban sincrossOrigin="anonymous", envenenando el HTTP cache del navegador para esas URLs. Resultado: cuando la pantalla de compartir intentaba fetchearlas con CORS, reutilizaba la entrada cacheada sin headers ACAO y la rechazaba. Fix completo: CORS aplicado al bucket +crossOriginselectivo en 12 sitios donde se cargacoverUrl, evitando contaminación a las fuentes que sí soportan CORS (Open Library) y respetando las que no (Google Books — su<img>quedaría roto si forzamos CORS allí).
Diseño y arquitectura
- Helper centralizado
coverCrossOrigin(url)ensrc/lib/cover-cors.tspara decidircrossOriginpor fuente. Una sola línea de verdad para todas las imágenes de portadas. lookupByIsbnahora reporta una traza por fuente conhttpStatusreal, lo que distingue desde diagnóstico si una "miss" fue200+vacío,429, otro4xx/5xxo error de red. Antes todo fallo silencioso era opaco.- Decisión documentada en
CLAUDE.md: "sin Cloud Functions" sigue como regla dura, ahora reformulada como decisión arquitectónica (cero ops, target 0€ por free tier, resiliencia offline). CF Pages Functions / Workers explícitamente permitidos como alternativa para cuando algo necesite servidor. Si en el futuro una feature pide Functions, se propone como cambio explícito de regla.
⚠️ Tras este despliegue, dos cosas se han hecho manualmente:
configurar CORS en el bucket de Firebase Storage (gcloud storage buckets update --cors-file=storage-cors.json) y activar la política
TTL del campo expiresAt en el collection group log (consola
Firebase → Firestore → TTL). Imprescindibles para que los fixes y la
limpieza automática funcionen — ver docs/storage-cors.md y
docs/diagnostics.md.
v0.5.34
Paquete grande de fixes detectados haciendo testing E2E de la cuenta del reviewer de Play Store. Cinco bugs reales + endurecimiento RGPD.
Nuevo
Borrado de cuenta cumple RGPD de verdad (B-046). Antes, "Borrar mi cuenta" eliminaba la cuenta de Firebase Auth pero dejaba huellas en Firestore: la library doc, los eventos de audit del actor, los
signupCodesconusedBy=tu uidy los feedback con tu email/nombre. Ahora el flujo de borrado limpia todo:- Library doc (la rule la bloqueaba con
if false; ajustada para permitir al owner borrar si es single-member). - Audit events del user (en single-member: todos; en multi: solo los suyos).
- Anonimización de signupCodes consumidos:
usedBya null yusedByEmailborrado, conservando el doc para auditoría histórica. - Anonimización de feedback: borra
userEmailyuserDisplayName, conservauserUidy eltext/reasons(útil para iterar).
- Library doc (la rule la bloqueaba con
El admin de feedback distingue bajas vs sugerencias (B-047). Tabs "Todo / Sugerencias / Bajas" con contador en cada uno. Badge garnet en las bajas, gris neutro en las sugerencias. Render de
reasons[](los chips marcados en la encuesta) bajo el nombre del usuario.
Corregido
El email de verificación llegaba duplicado tras signup. Race condition:
signUpWithEmailenviaba el email pero no marcaba el cooldown hasta DESPUÉS delawait; mientras tanto,onAuthStateChangedya disparaba el redirect a/verify-email, cuyouseEffectveía el cooldown vacío y disparaba un segundo envío. Ahora el cooldown se setea ANTES del await, así VerifyEmailPage al montar respeta los 60s y no reenvía. Confirmado con logs en producción.Portadas con tamaños distintos en el grid del catálogo (B-042 cierre raíz). El
<button>deBookCardno teníaw-full— tomabamin-contentwidth según el texto interno (título corto → button estrecho → cover ~100px; título largo → cover ~168px) en la misma celda de grid de 184px. Bug pre-existente desde la creación del componente. Confirmado con DevTools (grid uniforme, buttons no-uniformes). Fix:w-fullen el button.Descripción del
package.json(B-045): "PWA personal de catálogo de libros" → "Cataloga, lee y comparte". El "personal" no encajaba con el modelo multi-tenant.
Seguridad / rules
signupCodes/{token}update: tres branches (admin, canje, anonimización).feedback/{id}update: el dueño puede anonimizar manteniendouserUid.audit/{libraryId}/events/{eventId}: el actor puede leer y borrar sus propios events (necesario para que el cleanup de borrado de cuenta funcione).libraries/{libraryId}delete: el owner puede borrar si es single-member (antes eraif false, lo que bloqueaba el delete en el flow de borrado de cuenta).
⚠️ Las rules ya están desplegadas en producción durante el ciclo de testing E2E.
v0.5.33
Corregido
- Las invitaciones se marcan como "usadas" ahora SÍ de verdad
(causa raíz). El paso 5 de
consumeSignupCode(updateDocque seteausedBy/usedAt) seguía rebotando conpermission-denieden producción tras los retries y la simplificación de v0.5.32. Tras bisección con una rule mínimaif isSignedIn()confirmamos que pasaba — el problema era una de las conditions específicas. La culpable:resource.data.revoked != trueevaluado contra un doc donde el camporevokedno existía (no se setea al crear el code). En Firestore Rules v2, acceder a un campo inexistente conresource.data.Xtiene comportamiento errático — el evaluador rebota comopermission-denieden vez de tratar el campo comonull. Solución: usarresource.data.get('revoked', false)que devuelve el default explícito si el campo no existe. Aplicado defensivamente también ausedBy.
⚠️ Deploy manual requerido: firebase deploy --only firestore:rules
desde local del owner. (En este caso ya se hizo durante la sesión.)
v0.5.32
Corregido
- Las invitaciones se marcan como "usadas" de forma fiable tras
el signup. El paso 5 de
consumeSignupCode(elupdateDocque seteausedBy/usedAt) fallaba ocasionalmente por una race entreauth.currentUserrecién creado y la propagación al SDK de Firestore — las rulesisSignedIn()rebotaban transitoriamente. Ahora hace 3 intentos con backoff de 250 ms y 750 ms; suficiente para cubrir la ventana en la práctica. Si tras 3 sigue fallando, loggea pero no bloquea (el user ya tiene library + asociación). Cierra B-043 de raíz.
v0.5.31
Corregido
- Hotfix sobre v0.5.30: el flujo signup-or-signin de la pantalla
de invitación rebotaba con "contraseña incorrecta" cuando la cuenta
no existía todavía. Causa: Firebase Auth tiene "Email enumeration
protection" activado por defecto y devuelve
auth/invalid-credentialtanto si la cuenta no existe como si la contraseña es incorrecta — no se puede distinguir desde el mensaje de error. Ahora el handler intenta el signup trasinvalid-credential: si Firebase respondeemail-already-in-use, sí mostramos "contraseña incorrecta"; si no, la cuenta se crea. Sin esto, ningún usuario nuevo podía registrarse desde el enlace de invitación.
v0.5.30
Saneado completo del onboarding por invitación. Detectado al subir el TWA a Play y crear la cuenta del reviewer: el flujo email+password tenía 7 problemas que se quedaban a medias en distintos puntos. Ahora es coherente de principio a fin.
Nuevo
- Pantalla de invitación muestra el email destinatario desde el primer momento. Antes pedía credenciales a ciegas; ahora ves "Para juan@ejemplo.com — caduca el 8 de noviembre" y sabes con qué cuenta tienes que entrar.
- Crear cuenta directamente desde el enlace de invitación. Si tu
email no tiene cuenta Google, escribes una contraseña y se crea la
cuenta en el mismo paso. Antes tenías que ir a
/login, allí no funcionaba bien con invites, y se rompía el sessionStorage. - Pantalla "Verifica tu email" automatizada: envía el email al cargar (si no se envió ya), y detecta cada 3 segundos cuando lo verificas en otra pestaña — ya no hay que pulsar "refrescar".
- Borrar cuenta funciona con email+password, no solo con Google.
Antes
reauthenticateWithGoogleforzaba un popup de Google aunque hubieras entrado con email; ahora detecta tu provider y abre un modal pidiendo la contraseña si toca.
Cambios
- El email de verificación vuelve a Lomos automáticamente. Antes
caducaba en una página de Firebase y tocaba volver a mano. Ahora
el botón "Continuar" del email te trae directo a
/verify-emaildonde el polling detecta el cambio y entras solo. /loginya no permite "Crear cuenta". Lomos es invite-only: las cuentas solo se crean al canjear una invitación. Quitarlo de/logincierra el camino de "cuentas huérfanas" creadas sin invite. Para reset de contraseña sigue funcionando.signupCodese marca correctamente como usado aunque haya un fallo en el primer intento (B-043). El admin ya no ve invitaciones "pendientes" cuando ya están consumidas.- El email de invitación dice "tu cuenta", no "tu cuenta de Google" en el aviso de borrado. Pequeño detalle, pero antes confundía a usuarios sin Google.
Seguridad
/signupCodes/{token}legible sin login. Necesario para mostrar el email destinatario antes del login. El token (16 caracteres aleatorios) sigue siendo el secret real.- Nota sobre futuras mejoras: B-044 en backlog cubre el cierre server-side definitivo de "solo signup via invite" cuando haya volumen suficiente de usuarios.
⚠️ Deploy manual requerido: tras el push, el owner debe ejecutar
firebase deploy --only firestore:rules desde local para activar el
nuevo permiso de lectura. Sin ese paso, la pantalla de invitación
funciona pero NO muestra el email destinatario (cae al fallback).
v0.5.29
Cambios
- Login con email y contraseña en la pantalla de invitación.
Hasta ahora la pantalla
/unirse/{token}solo ofrecía "Continuar con Google", aunque la pantalla de login normal admite también email+password y enlace mágico. Ahora la página de invitación muestra los dos métodos: Google primero y, debajo, un toggle "Entrar con email y contraseña" — el flujo de consumo del invite es agnóstico al provider.
v0.5.28
Auditoría completa de Stats: cada KPI cuenta ahora exactamente lo que debería. Algunos números bajan a propósito; otros suben porque ya no inflaban con eventos que no eran lectura.
Cambios
- Abandonar un libro ya no cuenta como leído. Hasta ahora el histórico, el ritmo, los autores top, "mejor año", la cobertura compartida y las páginas leídas sumaban los abandonados como si hubieras terminado el libro. Único sitio que ya filtraba: el reto familiar. Ahora todo va alineado.
- Releer un libro no duplica páginas. "Total páginas" y los charts por año cuentan cada libro una sola vez, en el año de su primera lectura. Antes, releer en otro año sumaba las páginas otra vez — daba la sensación de leer el doble.
- "La librería" cuenta solo físicos shared. Los libros que
importaste como
private(leídos fuera, en biblioteca, prestados) ya no inflan los KPIs de "Libros físicos en casa", "Sin leer", ni "Páginas en casa". Esos siguen contando en tu actividad personal (sección Lecturas), donde sí tiene sentido. - "Top autores en la librería" ahora solo cuenta autores de físicos shared. Antes mezclaba con tus privates importados.
- Distribución por formato y Cobertura compartida pasan a operar sobre el catálogo compartido (sin privates de nadie).
- "Más antiguo sin leer" vuelve a aparecer como pendiente cuando abandonas un libro, porque abandonar ya no cuenta como leerlo.
Eliminado
- KPI "Racha" (meses seguidos leyendo). Inflaba con abandonados y no aportaba nada accionable. Lo recuperaremos si cambia el criterio.
- Card "Lectura más rápida". Las importaciones de Goodreads no
traen
startDate, así que el ranking ignoraba el grueso de tus lecturas — el resultado no era representativo. - Card "Categorías leídas". Mientras los libros no tengan categoría asignada masivamente, casi todo iba a "Sin categoría". Lo valoramos cuando haya datos que mostrar.
v0.5.27
Cierre del bloque B-038 — afinados de UI/UX detectados usando la app a diario. 9 correcciones agrupadas en un patch.
Nuevo
- Botón "copiar" discreto al lado del título y del ISBN en la ficha del libro. En mobile seleccionar texto a mano era un fastidio; ahora un toque copia al portapapeles para pegar en Google, Amazon o Casa del Libro.
- Cambiar formato en bloque desde la selección múltiple del
catálogo. Tras un import de Goodreads que interpretó mal la
columna
Binding, ahora puedes seleccionar 7 libros y cambiarlos todos a "Físico" en una pasada en lugar de entrar uno a uno. - Auto-marcar como leído al puntuar o reseñar. Si guardas un rating o un texto de reseña por primera vez en un libro, Lomos cierra la sesión de lectura abierta y marca el libro como "leído". Si lo habías marcado como abandonado, respeta esa decisión y no toca el estado.
Cambios
- Sección "¿Sigues con estas?" plegable en "Leyendo ahora".
La cabecera muestra el contador (
¿Sigues con estas? (3)) y se puede plegar para no estorbar visualmente cada vez que entras. El estado persiste entre sesiones. - Búsqueda y filtros del catálogo se preservan al volver atrás. Si estabas buscando "márquez", entras a la ficha y vuelves con el botón atrás, el catálogo aparece otra vez con la búsqueda activa y restaurando la posición de scroll donde lo dejaste. Igual con los filtros de estado, idioma, año, formato, etc. — todos viajan en la URL y son compartibles.
- "Limpiar caché" baja al pie. Ya no ocupa una sección entera en "Yo"; ahora es un link discreto en la línea de la versión: "Lomos v0.5.27 · build … · Limpiar caché".
- "Yo" más limpio. Quitados los duplicados de "Escanear estantería" (ya está en el botón ⊕ del catálogo desde v3.1) y de "Cómo funciona el escaneo" (accesible desde el botón de ayuda dentro de Spine Scan).
- Zona peligrosa al pie y plegada. Las opciones de exportar, borrar librería y borrar cuenta viven ahora en una sección plegable al final del todo, debajo de la versión, plegada por defecto. Se entra solo si vas a por algo destructivo.
- Mini-encuesta antes de borrar cuenta. Si decides borrar tu cuenta, te pregunto un par de cosas opcionales (motivo en botones rápidos + texto libre, máx. 500 caracteres) para mejorar Lomos. Puedes saltarla con un link discreto.
Corregido
- Toast "Nueva versión disponible" dejó de aparecer en bucle.
La guard que evitaba dispararlo dos veces vivía en
useRefy se reseteaba al desmontar el componente (Suspense, lazy chunks). Ahora vive enlocalStoragecon clave por versión, sobrevive a remounts y solo aparece una vez por versión instalada.
v0.5.26
Hotfix de portadas: arregla un bug que impedía sustituir la portada subida automáticamente y añade la opción de quitarla.
Corregido
- Subir una portada manual desde la edición ya guarda la nueva. Antes, si el libro tenía ISBN y ya había una portada en el pool comunitario para ese ISBN, la subida manual se ignoraba en silencio: el "Guardando…" terminaba bien pero la imagen seguía siendo la anterior. Causa: la política write-once del pool comunitario reutilizaba la URL existente en lugar de subir la nueva. A partir de ahora las subidas manuales siempre van a tu carpeta privada de la librería, no al pool compartido.
Añadido
- Botón "Quitar portada" en la edición de un libro. Si la portada que asignó el lookup automático es errónea o no te convence, ahora puedes dejarla vacía sin tener que subir otra encima. Si cambias de idea antes de guardar, "Deshacer quitar" restaura la actual.
v0.5.25
Fase 1 de optimización de cuotas Firestore (B-026 + B-028 + B-029 del análisis B-025). Ningún cambio visible para ti — pero la app debería consumir muchas menos lecturas de Firestore en el día a día, y la cuota de Spark deja de tocar techo con un solo usuario activo.
Cambios
- Persistencia offline activada. Cada vez que abres Lomos, en lugar de descargar todos tus libros otra vez, el SDK los lee del cache local del navegador y solo pide a Firestore lo que ha cambiado. Estimación: -70 % de lecturas en uso recurrente.
- Filtro de "rating de cualquier miembro" carga bajo demanda. Antes leía las reseñas de toda la librería al abrir el catálogo aunque no fueras a usar ese filtro. Ahora solo se carga si activas el filtro.
- Reto familiar y cobertura cross-usuario solo cuando hay 2+ miembros. Si tu librería es de uso personal, ya no se cargan todas las readings de todos los miembros (que serían las tuyas duplicadas en otra query).
Pendiente para ti — pasar a Blaze
Junto con esta versión queda pendiente B-027: migrar el
proyecto Firebase a plan Blaze (pay-as-you-go) con alertas de
presupuesto. Es un cambio de 5 minutos en la consola de Firebase
que yo no puedo hacer porque requiere tu tarjeta. Detalles
exactos en docs/scaling-blaze-migration.md.
Sin Blaze: si en algún momento alguien excede 50.000 reads/día, la app deja de funcionar hasta el reset (con esta versión es mucho menos probable, pero el riesgo cero solo se elimina con Blaze).
v0.5.24
Hotfix del feed de Novedades.
Corregido
- El feed de Novedades reventaba con un error de validación cuando había algún evento con un rating decimal (medias estrellas, p. ej. 4.5). El schema antiguo del feed solo aceptaba enteros, herencia de antes de v0.4.10 cuando los ratings eran 1-5 en pasos de 1. Ahora acepta cualquier valor válido del schema de reseñas (0.5..5 paso 0.5).
v0.5.23
Cambio de prioridades del flujo post-import.
Cambios
- Tras importar Goodreads o Kobo, ahora se busca portadas automáticamente en lugar de enriquecer fichas. Las portadas son lo que más impacto visual tiene: el catálogo recién creado se ve bonito casi al instante. El enrichment de metadata (sinopsis, idioma, categorías) sigue accesible manual desde Yo → Mantenimiento → Enriquecer fichas.
- Toast nuevo para la búsqueda de portadas con la misma estética del de enrichment: barra de progreso de fondo, contador X/N y botón cancelar. Aparece arriba del de enrichment si ambos coinciden.
Por qué
El enrichment tarda más (consulta Open Library y Google Books para cada libro completo) y la mayor parte del valor percibido — el "wow inicial" — viene de las portadas. Si la gente quiere las sinopsis y categorías, está a un click en Mantenimiento.
v0.5.22
Hotfix detectado en pruebas reales: cuando se excede la cuota diaria
de Firestore (50K reads en plan Spark), el SDK queda colgado
reintentando lecturas internamente en lugar de fallar rápido. El
scheduler de enrichment se quedaba en deadlock — "0 de 401" sin
avance posible — porque un getBook colgado no decrementaba el
contador de jobs activos.
Corregido
- Timeout de 30s por job en el enrichment. Si una operación de
Firebase queda atascada (cuota agotada, red caída, lo que sea),
el job se descarta como error tras 30s y el scheduler avanza al
siguiente. Tras 3 intentos consecutivos en el mismo libro, lo
retiramos de la cola con su
enrichmentErrorcorrespondiente.
Esto se manifestó al exceder cuota Spark (74K reads contra 50K de límite) tras varias pruebas de import seguidas. Cuando vuelva la cuota a su sitio (reset diario a las 09:00 hora peninsular), el flujo recupera con normalidad.
v0.5.21
Tres bugs detectados al re-importar 431 libros de Goodreads para probar el flujo completo. Importantes: dejaban el catálogo en estado inconsistente y a más de la mitad de libros sin enriquecer.
Corregido
- "Leyendo" sin fecha de inicio. Goodreads no exporta "Date Started" en su CSV, solo "Date Read" y "Date Added". Para libros marcados como currently-reading sin fecha de cierre, ahora usamos "Date Added" como aproximación de cuándo empezaste. Si tampoco hay "Date Added", la sesión queda abierta sin fecha (igual que antes). El recordatorio de "¿lo dejas o sigues?" (>60 días sin actividad, v0.5.19) ya puede dispararse para estos libros.
- Enrichment automático tras importar quedaba muerto. El scheduler salía del bucle al vaciar la cola y no se relanzaba cuando entraba un nuevo lote — el toast se quedaba en 0/X para siempre. Solo se reanudaba parando + relanzando manual. Ahora se relanza automáticamente al meter items nuevos.
- Cascada de 429 contra Google Books. La concurrencia y la
paralelización de OL+GB por libro generaban
6 req/s sobre Google Books, que rechazaba con 429 tras unos cuantos. La mayoría de los 431 se quedaban sin enriquecer y sin posibilidad de recuperación automática. Ahora hay throttle local (3 req/s) y un retry automático tras 429 respetando el header Retry-After. La concurrencia del scheduler también baja de 3 a 2 jobs. Resultado: ETA ligeramente mayor (un par de minutos para 400 libros) pero completa todo en lugar de saltarse la mitad.
v0.5.20
Bloque C de v0.6: descubrimiento, catálogo en español y tarjeta para Stories.
Cambios
- Mini-quiz para descubrir qué leer. Nueva pantalla "Descubre" en Yo: marca hasta 3 libros que te encantaron y Lomos te recomienda 5 de tu propia casa que aún no has leído. Recomienda por autor compartido y categoría — todo local, sin AI ni red.
- Catálogo en español más rico. Las búsquedas por título y autor ahora se sesgan al español si el navegador está en español. La cobertura de Open Library / Google Books filtra primero por idioma y reordenamos en cliente para que los matches en español aparezcan arriba.
- Tarjeta para Stories pulida. La imagen 1080×1920 que se genera al pulsar "Compartir" en la ficha del libro ahora presenta la portada como una polaroid: marco blanco con espacio inferior y ligera inclinación, sombra más suave. La reseña sigue truncada a 8 líneas como hasta ahora.
v0.5.19
Bloque B de v0.6: lecturas y feedback más útiles durante la beta.
Cambios
- Recordatorio "¿abandonas este libro?" sobre la lista "Leyendo ahora" para readings sin actividad más de 60 días. Tres acciones: "Sigo" (oculta el aviso esta sesión), "Lo dejo" (cierra como abandonada y marca el estado correspondiente), "Lo terminé" (cierra y marca como leído). Mantiene la lista limpia y los stats fieles.
- Reto anual con la casa. Si tu librería tiene 2 o más miembros, la tarjeta del reto muestra debajo una mini tabla con el progreso de cada uno (libros leídos / meta), incluso para quien aún no se haya puesto reto. Sin opt-in: la casa es la casa.
- Feedback con más contexto técnico. Al enviar una
sugerencia desde la app, además de la versión y la pantalla
ahora se adjunta el
libraryIdy los métodos de login activos del user. El admin lo ve en su lista para reproducir bugs sin necesidad de pedir más datos por chat.
v0.5.18
Bloque A de v0.6: pulido de UX antes de abrir la beta cerrada a gente de confianza.
Cambios
- Banner sutil "Beta cerrada" en la cabecera del catálogo. Si algo no va o se te ocurre una mejora, link directo a Ideas. El banner se cierra por sesión: si lo ocultas, vuelve a aparecer en la próxima visita.
- Aviso de versión nueva como toast con el botón "Ver qué cambió" que abre el changelog directamente en la versión correspondiente. Antes solo había un badge enterrado en la pantalla "Yo".
- Primeros pasos rediseñado. El bloque grande encima del catálogo ya no estorba. El progreso vive ahora en una tarjeta limpia en "Yo" con barra y porcentaje. Click → abre el checklist completo en un panel. Las cards se siguen tachando solas según vas haciendo cosas.
- Catálogo vacío con tres rutas claras: Importar Goodreads, Importar Kobo, Añadir a mano. La mayoría llega de Goodreads o Kobo, así que esos dos van primero.
v0.5.17
Las invitaciones se envían automáticamente por email al aprobar una solicitud o pulsar "Email" en el panel admin. Antes había que pasar por el cliente del navegador (mailto). Sigue funcionando el flujo manual como red de seguridad si el envío automático falla.
Cambios
- Endpoint nuevo en
lomos.app/api/admin/send-invite(Cloudflare Pages Function). Verifica que quien llama es el admin via Firebase ID Token y envía el email vía Resend con plantilla HTML brandeada. - El panel admin avisa con un toast: "Email enviado a X" cuando el envío automático funciona, o "Envío automático no disponible — abriendo tu cliente" si rebota y cae al fallback.
- Plantilla HTML del email con cabecera Lomos, botón CTA destacado, enlace de respaldo y aviso de caducidad. Mismo contenido que el mailto pero presentado como email decente.
Para ti como admin
Cuando aprobas una solicitud o pulsas "Email" en un código existente:
- En la mayoría de casos el invitado recibe el email directamente, sin que tengas que abrir Gmail.
- Si por alguna razón el envío automático falla (sin red, función caída), Lomos te abre el cliente de email pre-rellenado igual que antes, así puedes mandarlo a mano.
v0.5.16
Tanda de afinados de UI y bugs después del primer pase de invitaciones reales.
Stats
- Tus libros privados ya cuentan en tus stats. Antes la página
filtraba todos los libros con
ownership=private, así que si tenías muchos privados los KPIs aparecían a 0 mientras la distribución de formato sí los contaba — totalmente confuso. Ahora tus privados cuentan como tuyos en tus propios stats; los privados de otros miembros siguen sin aparecer (es la semántica correcta de privacidad). - Los KPIs "Libros" y "Páginas en casa" cuentan solo físicos. Los ebook ya no inflan el total de inventario "en casa". Un libro se considera físico si tiene al menos un ejemplar en formato físico, o si no tiene ningún ejemplar registrado (en ese caso lo asumimos físico, mismo criterio que el filtro del catálogo).
Admin
- Aprobar una solicitud de invitación abre ahora el cliente de email pre-rellenado con el enlace y el cuerpo listo para enviar. Antes solo se copiaba el link al portapapeles y había que ir a Gmail a mano. Sigue sin haber Worker de Resend (es la decisión consciente para la beta cerrada con bajo volumen).
- Botón "Email" en solicitudes ya aprobadas para reabrir el mailto si pierdes la pestaña o si quieres reenviar.
- Admin tiene su propio enlace en el menú lateral de escritorio. En móvil sigue accesible desde "Yo".
Móvil
- "Ideas" (sugerencias) en el menú inferior durante la beta cerrada para promover el envío de feedback. Pasa de 4 a 5 iconos en la barra; cada uno se aprieta un poco pero sigue siendo cómodo de pulsar.
v0.5.15
Cierre fino del flujo de invitaciones. Tras v0.5.14 los invitados ya entran, pero el panel admin seguía mostrando el código como "pendiente" porque la última escritura — la que marca el código como usado — rebotaba en silencio (era no-bloqueante por diseño, pero dejaba el panel desincronizado).
Corregido
- La rule de actualización de códigos de alta usaba una
comprobación frágil basada en diff de campos. Sustituida por
checks explícitos: el invitado se autoasigna como
usedByy no toca los campos sensibles (token, caducidad, email vinculado, creador). El resto de campos (timestamp de uso, email del invitado, etc.) se pueden escribir libremente — es metadata de auditoría, no compromete la seguridad.
A partir de aquí los nuevos códigos consumidos aparecen en el panel como "Usado" con email del invitado y timestamp.
Despliegue manual de las rules necesario.
v0.5.14
Cuarto intento del flujo de invitaciones. Resulta que la invitación que mandaba el panel admin no es una invitación a casa, sino un código de alta — el destinatario crea su propia librería al consumirlo. v0.5.13 reescribió el flujo de "unirse a casa de otro" pero no el de "alta vía código admin", que es el que se estaba usando en realidad.
Cambios
- El consumo de un código de alta también deja de ser una
transacción atómica. Pasa a tres escrituras secuenciales:
crear la nueva librería con el invitado como propietario,
rellenar
users/{uid}con sulibraryId, marcar el código como usado. Cada paso loguea con etiqueta concreta (step:libRef-create / userRef-set / codeRef-update) si falla. - Si la última escritura falla (marcar el código como usado), ya no se aborta el alta: el invitado entra y solo el panel admin queda con el contador desactualizado.
v0.5.13
Tercer intento de arreglar el flujo de invitaciones externas. v0.5.11 y v0.5.12 corrigieron las dos primeras barreras (búsqueda del invite + lectura cosmética del library), pero el commit final de la consumición seguía fallando con un 403 genérico de Firestore sin pistas sobre cuál de las tres escrituras violaba las rules.
Cambios
- Reglas más tolerantes. Las reglas que evaluaban la membresía
del invitado y la cuenta de usos del invite usaban operaciones
(
map.diff,array.concat/hasAll) que crashean en silencio si los camposmembersousesno existían o tenían un schema ligeramente distinto al esperado. Las nuevas comprobaciones son más simples y aceptan los dos casos. - Consumición no atómica con logs por paso. La transacción
atómica se ha dividido en tres escrituras secuenciales:
añadir al invitado a
members, actualizarusers/{uid}y contabilizar el uso en el invite. Cada paso loguea su error con etiqueta concreta — el siguiente fallo dirá exactamente cuál write rebota. La pérdida de atomicidad es aceptable: el orden está pensado para que un fallo intermedio deje el flujo reanudable o cosméticamente desincronizado, no roto.
Despliegue manual de las rules necesario (el CI no las despliega).
v0.5.12
Segundo hotfix del flujo de invitaciones. v0.5.11 arregló la búsqueda del invite por token, pero el siguiente paso —cargar el nombre de la librería para mostrarlo en la pantalla de bienvenida— también estaba bloqueado por rules: el invitado externo aún no es miembro y la rule de lectura del doc de librería exige membership.
Corregido
- La carga del nombre/owner de la librería para la pantalla de invitación se hace ahora de forma opcional. Si las rules la niegan (porque el invitado todavía no es miembro), el flujo continúa con un nombre por defecto en lugar de abortar la consumición.
v0.5.11
Hotfix: invitar a otra persona externa estaba roto. El destinatario entraba por el enlace, hacía login con Google, y al volver veía "No se pudo usar la invitación: Missing or insufficient permissions". La cuenta de Google quedaba creada pero sin acceso a la librería.
Corregido
- Faltaba una rule de Firestore que permite buscar invitaciones por token sin saber de antemano a qué librería pertenecen. Sin esa rule, la búsqueda fallaba y abortaba toda la consumición. Ahora está añadida y desplegada.
Si te pasó
Si invitaste a alguien estos días y se quedó sin entrar:
- Pídele que cierre sesión en Lomos.
- Reabra el enlace de invitación que le mandaste.
- Vuelva a entrar con Google.
La cuenta de Auth ya existe pero no tiene librería; el segundo intento ahora sí ejecuta la consumición y le añade como miembro.
v0.5.10
Tres bugs del escaneo de estantería en móvil, vistos en uso real, ya están corregidos.
Corregido
- La foto se perdía al rotar el móvil durante el preview. El estado del preview vivía dentro del componente de cámara y un re-mount lo borraba. Ahora vive en el estado de la página y sobrevive a la rotación.
- El botón "Añadir N" quedaba tapado por la barra inferior en mobile. La barra de acciones del scan se solapaba con la navegación principal. Ahora va por encima y deja sitio para ambos. El FAB de "Añadir libro" tampoco aparece en esta pantalla — el scan ya tiene su propia confirmación.
- "Ver foto" daba imagen rota tras editar un candidato. La URL temporal de la foto se liberaba antes de tiempo cada vez que cambiabas algo en la lista. Ahora solo se libera al salir del flujo.
v0.5.9
Tests automáticos end-to-end (E2E) que ejercitan los flujos críticos antes de cada deploy. Si rompes algo importante, el deploy no sale.
Para ti como user
Cero cambios visibles. Pero tienes una red de seguridad nueva: cuando suba algo a producción, antes una batería de tests automatizados ha simulado a un usuario haciendo las cosas importantes y todas tienen que pasar.
Tests cubiertos
8 escenarios críticos, cada uno corre en Chrome desktop y Chrome mobile:
- La pantalla de login carga con todos los métodos.
- La raíz sin sesión redirige a
/login. - Alta manual de un libro.
- Marcar un libro como "Leyendo".
- Crear una sesión de lectura.
- Editar el título de un libro.
- Importar libros desde un CSV de Goodreads.
- Actualizar la portada vía búsqueda por título y autor.
- Alta de libro por ISBN con búsqueda en bases públicas.
Total: 18 tests, ~45 segundos en local con todo cacheado.
v0.5.8
Si usas dos métodos de login con el mismo email (Google + email y contraseña, por ejemplo), Lomos los vincula automáticamente — es una sola cuenta con dos puertas de entrada, no dos cuentas separadas.
Cambios
- Vinculación automática de métodos. Si tienes cuenta con email y contraseña y un día pulsas "Continuar con Google" usando el mismo email, Lomos te avisa: "tu cuenta ya existe, entra con email y contraseña y vinculamos Google después". Tras el login, Google queda añadido como método secundario sin tocar tus datos. Al revés también funciona (de Google a email y contraseña).
- Lista de métodos en Yo → Tu cuenta. Ahora ves "Métodos de login activos" con todos los providers que tienes vinculados: Google, email y contraseña, enlace mágico, Apple, Microsoft.
Notas
- Apple Sign In y Microsoft están preparados a nivel de UI para cuando se habiliten — hoy no son providers activos.
- El flujo de vinculación respeta tu password: si chocaba el login
con email + contraseña, Lomos guarda esa contraseña en memoria
durante el flujo y la usa para el
linkWithCredentialtras el login con Google. No se persiste.
v0.5.7
Más formas de entrar a Lomos: ya no hay que tener cuenta de Google.
Nuevo
- Login con email y contraseña. Aparte del botón de Google, ahora puedes crear cuenta con cualquier email y una contraseña (mínimo 8 caracteres). Útil si no quieres asociar tu lectura a tu cuenta personal de Google.
- Enlace mágico. Pones tu email, recibes un email con un botón,
pulsas y dentro. Sin contraseñas, sin recordar nada. Lomos manda
el email con tu dominio (
hola@lomos.app). - Reset de contraseña. Si te olvidas, "¿Olvidaste tu contraseña?" en el login te manda un email con instrucciones.
- Pantalla de verificación. Tras crear cuenta con email + contraseña, te enviamos un email para verificar. Hasta que pulses el enlace, no puedes entrar.
Cómo funciona la pantalla de login ahora
- Botón grande "Continuar con Google" (lo que ya había).
- Separador "o".
- "Entrar con email y contraseña" o "Recibir enlace mágico por email" — el form aparece al pulsar.
- Dentro del form de email + contraseña hay enlaces a "Crear cuenta" y "¿Olvidaste tu contraseña?".
Notas
- Las invitaciones siguen funcionando igual: el código está vinculado a un email concreto y al usar el método que sea (Google, email+password o magic link), Lomos comprueba que coincide con el email del code.
- Apple Sign In y Microsoft llegarán más adelante. Si los necesitas hoy, dímelo y subo la prioridad.
v0.5.6
Cumplimiento RGPD: ahora puedes exportar tus datos y borrar tu cuenta desde la propia app.
Nuevo
- Exportar mis datos. En Yo → Privacidad y datos, un botón "Descargar mis datos" genera un JSON con tu librería, tus reseñas, lecturas, citas, préstamos y ajustes. Útil como respaldo o para llevarte tus datos a otra app (RGPD, derecho de portabilidad).
- Borrar mi cuenta. Nueva tarjeta en Privacidad y datos: borra tu cuenta de Google asociada y todo lo tuyo. Si eres el único miembro de la librería, también la borra entera. Si la compartes con familia, los libros comunes se conservan para los demás miembros — solo desaparece lo que era tuyo (reseñas, lecturas, citas, préstamos atribuidos a ti).
Cómo funciona el borrado
- Te pide confirmar escribiendo "BORRAR MI CUENTA" (lo mismo que el reset de la librería).
- Borra todo en cliente: libros privados, lecturas, reseñas, citas, préstamos atribuidos, estado personal, secrets de IA, doc de usuario y la cuenta de Firebase Auth.
- Si la sesión es vieja, Google te pedirá volver a autenticarte para confirmar el borrado.
v0.5.5
Mejoras de email para la beta cerrada.
Cambios
- Emails de Firebase Auth con dominio propio. Verificación de
email, reset de contraseña y cambio de email ya salen desde
hola@lomos.appcon plantilla brandeada de Lomos. Antes salían desdenoreply@lomos-2026-….firebaseapp.com. El cambio es de configuración (Resend SMTP en Firebase) — no requiere update de los users que ya estén dentro. - Botón "Enviar por email" en el panel admin al lado de cada signup code pendiente. Abre el cliente de email con destinatario, asunto y plantilla pre-rellenada. Cachuco solo revisa y manda.
v0.5.4
Cambio de analítica: Lomos pasa de Google Analytics a Umami, que es analítica anónima sin cookies. Ya no hay rastreo cruzado entre sitios ni identificadores persistentes — solo páginas vistas y eventos contados.
Cambios
- Sin cookies de rastreo. Antes Lomos cargaba Google Analytics (GA4), que en navegadores europeos exigiría un banner de cookies. Ahora la analítica es Umami: sin cookies, sin huella digital, sin banner.
- El bundle de la PWA pesa menos. Hemos quitado el SDK de Firebase Analytics — la app inicial baja unos 30 KB.
- El footer de lomos.app ahora explicita "Analítica anónima con Umami" para que sepas exactamente qué se mide.
- Mismo dashboard para landing y app. Cuando llegue la beta, el funnel landing → solicitar invitación → app activa se podrá seguir entero sin cruzar herramientas.
Notas
- No tienes que hacer nada — el cambio es transparente. Si tu
navegador bloqueaba Google Analytics, ahora verá Umami en
cloud.umami.is(también bloqueable y respetado).
v0.5.3
Bugfix rápido: las medias estrellas ahora funcionan también en desktop.
Corregido
- Rating con media estrella en escritorio. En móvil ya iba bien, pero en desktop al hacer click en una media estrella el valor se quedaba en el entero más cercano. Y el preview del ratón por encima del slider tampoco mostraba medias. Causa: el slider HTML5 nativo no mueve el thumb con un solo click en desktop, y el hover preview truncaba a entero. Ahora se calcula el valor a partir de la posición del cursor sobre el ancho del componente para que click y hover encajen al medio paso correcto en cualquier dispositivo.
v0.5.2
Versión interna para preparar la beta cerrada: registro de actividad y errores para iterar con datos, y reconciliación de la frase de la landing en SEO/OG/docs.
Para los betas
- Audit log. Durante la beta registramos en silencio las acciones importantes (añadir libro, escaneo, errores no capturados…) para que podamos arreglar lo que falle sin tener que preguntarte. Lo ve solo el admin (Cachuco). En Yo → Privacidad y datos tienes un toggle para desactivarlo si prefieres no participar.
Para el admin
- Nueva ruta
/yo/admin/auditcon la lista cronológica de eventos filtrable por usuario y por tipo, "solo errores" como toggle rápido, y detalle expandible con stack trace y payload.
Marca y SEO
- El title SEO por defecto pasa a "Lomos — Tu librería y tus lecturas, en una sola app" (mantiene "librería" como keyword).
- La imagen Open Graph muestra ahora "Tus libros y tus lecturas, juntos por fin" — coherente con el hero.
- Docs internos (
launch-strategy.md) actualizados con la frase nueva.
v0.5.1
Iteración del escaneo de estanterías tras los primeros tests reales. Más fiable, más rápido cuando repites una foto, mejor identificación de libros y un sitio dedicado para aprender a usarlo.
Cambios en el escaneo
Mejor identificación de libros. Lomos ahora hace tres búsquedas en cascada cuando el modelo te da un libro:
- Primero busca por título + autor.
- Si no hay resultados, busca solo por título (a veces el autor leído es ligeramente distinto del de Open Library).
- Si aún no, busca al menos una portada candidata y la usa.
El umbral para marcar un libro como "Encontrado" también es más permisivo: ahora un match parcial (contains) puntúa alto, y los libros con portada en Google Books reciben un pequeño bonus porque suelen ser ediciones canónicas.
Buscar de nuevo desde la lista. Cada candidato gris ("Sin datos") o ámbar ("Posible") tiene un botón "Buscar de nuevo" que abre el editor inline. Cambias el título o autor y pulsas buscar — Lomos relanza la búsqueda y actualiza la portada y los datos en sitio. Útil cuando el OCR se equivoca por un carácter.
Caché de fotos durante la sesión. Si vuelves a subir la misma foto (por ejemplo porque tocaste cancelar y la quieres rehacer), Lomos no vuelve a llamar a Gemini — lo recuerda. Dos beneficios: resultado idéntico (no más "la misma foto da cosas distintas") y ahorro de cuota.
Vista de la foto original mientras revisas la lista de candidatos. Botón "Ver foto" en el header para verificar lomos concretos sin tener que volver al rollo de la cámara.
Lista más limpia. Los candidatos sin match y baja confianza van plegados a un botón "Ver descartados", para que la lista principal solo contenga lo importante.
Mensajes de error más claros y un disclosure plegable con el detalle técnico cuando algo falla — para que sepas si fue tu API key, el límite gratuito, una imagen ilegible o un problema de red.
Mejor prompt para el modelo: ahora ignora explícitamente los lomos cortados por arriba o por abajo (caso típico de fotos de estanterías altas), y los lomos que solo muestran nombre de editorial sin título.
Cantidad mayor de libros por foto. Hemos cuadruplicado el límite interno de respuesta del modelo, para que baldas con muchos libros no se queden a mitad.
Reintenta automáticamente una vez si Gemini tiene un problema pasajero de red, para que no tengas que repetir la foto.
Documentación
- Nueva página
/yo/escanear/ayudadentro de la app: guía paso a paso para crear tu API key Gemini gratis, ejemplos visuales de buenas fotos y de las que conviene evitar, explicación de privacidad, límites del plan gratuito y un FAQ con los problemas típicos. - Nueva página pública
lomos.app/escaneocon el detalle de la feature de cara a quienes aún no la conocen, con ilustraciones y FAQ de marketing. - La home de
lomos.appmuestra un bloque destacado con la feature como gancho principal junto al doble eje "librería + lecturas".
Nuevo en /yo
- Ajustes reordenados. La sección "Yo" se ha reagrupado en bloques con cabeceras claras: Tu cuenta, Tu librería, Importar libros, Apariencia, Mi actividad, Mantenimiento, Privacidad y datos, Ayuda y feedback. Mismas funciones, encontrar las cosas más fácil.
v0.5.0
Escanear estantería: saca foto a una balda y la IA identifica los libros para añadirlos al catálogo. Pensado especialmente para librerías grandes que no vienen de Goodreads ni Kobo.
Nuevo
Escanear estantería. Nueva entrada en Yo → Escanear estantería y también en el FAB de "Añadir libro" (sección "O en lote"). Sacas una foto a una balda, esperas 5–15 segundos, y Lomos te muestra una lista de los libros que ha leído. Cada uno con su estado:
- Encontrado (verde): match en Open Library / Google Books, con portada y datos completos.
- Posible (ámbar): match parcial; revisa antes de añadir.
- Sin datos (gris): el modelo lo lee pero no lo encuentra en bases de datos abiertas. Puedes añadirlo manualmente.
- Ya en tu librería (granate): no se duplica.
- Duplicado: dos entradas iguales en la misma foto, se queda una.
Cada item tiene checkbox, edición rápida (lápiz) y descartar (X). Al pulsar "Añadir N libros" se añaden todos al catálogo en una operación.
Cómo funciona — privacidad
- El reconocimiento usa la IA de Google (modelo Gemini 2.5 Flash). Para usarlo necesitas una clave gratuita de Google AI Studio (250 escaneos/día, sin tarjeta). El wizard te guía paso a paso — un minuto en total.
- La clave se guarda solo en tu cuenta dentro de Firestore con reglas estrictas (ni los miembros de tu casa pueden verla). Nunca pasa por servidores de Lomos.
- La foto se envía cifrada a Google. Lomos no la guarda ni en Firestore ni en Storage.
Detalles
- Tu librería existente se chequea automáticamente para evitar duplicados. Si tu foto incluye libros que ya tenías, los marca con "Ya en tu librería" y no los añade.
- El feed de novedades muestra una entrada agregada por sesión: "Cachuco escaneó una balda y añadió 12 libros" — no llena el feed con un evento por libro.
- Compresión cliente: la foto se envía a 1024 px JPEG para que cada llamada use poca cuota.
Notas
- Funciona mejor con: foto frontal, 10–20 libros por balda, luz natural o lámpara cercana, lomos verticales (los apilados horizontales no se leen).
- En esta primera versión solo soportamos Gemini. En la próxima añadimos OpenAI y Anthropic para quien ya tenga clave en otro proveedor.
v0.4.11
Categoría y temática como desplegables, navegación por facetas, filtro por estrellas y modo oscuro/claro en la web pública.
Nuevo
- Modo oscuro / claro / auto en la web (lomos.app). Toggle con tres modos en la cabecera: automático (sigue al sistema operativo), claro forzado y oscuro forzado. Tu elección se recuerda en el navegador y se aplica antes de pintar la página, así no hay flash de color incorrecto al cargar.
- Categoría como lista cerrada en la ficha del libro. Antes podías escribir cualquier cosa y acababas con 30 variantes de "Novela histórica" / "novela histórica" / "Histórica". Ahora hay un desplegable con una lista pensada (33 categorías: Novela contemporánea, Thriller, Romance, Fantasía, Ciencia ficción, Ensayo, Biografía, Cómic, Manga, etc.) que puedes filtrar escribiendo. La lista es cerrada por ahora — si echas en falta una categoría, dínoslo desde la app.
- Temática como sugerencias abiertas. La temática (subject) sigue permitiendo texto libre, pero ahora con autocompletado contra una lista de 30 sugerencias frecuentes (Familia, Amistad, Amor, Guerra, Inmigración, Identidad, Feminismo, etc.) para no tener que reescribir las habituales y mantener consistencia.
- Navegación por facetas desde la ficha del libro. Pinchas en el autor, la editorial, la categoría o la temática y vas al catálogo filtrado por ese valor — con la URL guardable y compartible. Útil para "todos los libros de Stanislaw Lem que tengo", "todo lo de Anagrama", "todos los thrillers".
- Filtro por estrellas en el catálogo. Nuevo selector que te deja ver solo libros con cierta valoración: 1, 2, 3, 4 o 5 estrellas completas, "sin valorar" (libros que nadie en tu librería ha puntuado), o "cualquiera". El filtro mira las reseñas de cualquier miembro de la librería, no solo las tuyas — útil cuando compartís libros y quieres ver lo que ha gustado a la familia.
Notas
- Las categorías que ya tenías escritas a mano (libres) se siguen respetando para lectura. Al editar la ficha, si tu valor antiguo no coincide con ninguno de la lista cerrada, te aparece el desplegable vacío para que elijas uno equivalente.
- Las facetas en la ficha se enlazan también al pinchar el año, pero el año de momento muestra texto plano (no filtra) para no abrir esa caja todavía.
v0.4.10
Rating con medias estrellas (en lugar de cuartos) y picker más cómodo de usar.
Cambios
- Medias estrellas (paso 0,5) en vez de cuartos. Tras pruebas en móvil acertar un cuarto era demasiado fino — los targets táctiles eran de 5 píxeles. Con medias hay 10 puntos posibles a lo largo del slider y se acerta sin esfuerzo.
- Nuevo picker que usa el slider nativo del navegador detrás de las estrellas: arrastras el dedo sin soltar y el rating va subiendo fluido, o tocas directamente en la posición que quieras y el navegador encaja al medio más cercano. También funciona con flechas ← → del teclado en desktop.
- Estrellas más grandes en el editor de reseña (32 px vs 16 px en lectura). Solo cuando estás escribiendo tu rating; en el catálogo y en el feed siguen pequeñas como antes.
- Botón "Quitar" para borrar el rating, en lugar del antiguo "tocar la estrella seleccionada para quitar". Más explícito.
Notas
- Tus ratings con cuartos (de v0.4.9) siguen visibles tal cual — el render acepta cualquier fracción. Pero al editar volverán a redondearse al medio más cercano.
v0.4.9
Tres mejoras de UI: progreso visible al enriquecer, abandonar libro nativo y cuartos de estrella en los ratings.
Nuevo
- Aviso de enriquecimiento con progreso visible: ahora la notificación muestra cuántos libros de cuántos llevamos ("Enriqueciendo 234 de 416"), una barra de progreso de fondo que avanza, y el tiempo estimado restante. Cuando termina, te saluda con un "✓ N fichas enriquecidas" durante unos segundos antes de irse. Hay un nuevo icono ⓘ que abre una explicación de qué pasa si apagas la pantalla, cierras la app o te quedas sin red. Resumen: no se pierde nada.
- Abandonar libro de manera nativa: nuevo botón "Abandonar" en la ficha del libro. Cierra la sesión de lectura abierta y marca el libro como abandonado en una sola acción. Aparece cuando estás leyendo el libro o su estado es "Leyendo". Si en lugar de eso prefieres usar el chip de estado, ahora también permite saltar directamente a "Abandonado" sin tener que cerrar la sesión a mano primero.
- Cuartos de estrella en los ratings (paso 0,25). Antes solo podías dar 1, 2, 3, 4 o 5. Ahora también 3,5, 3,75, 4,25... Toca donde quieras dentro de la estrella: la mitad izquierda da cuartos bajos, la derecha cuartos altos. En catálogo, fichas y feed se ven con la fracción exacta. Compartir reseña como imagen también respeta los cuartos. Tus ratings históricos enteros siguen valiendo, no hay que tocar nada.
Detalles técnicos para curiosos
- El cálculo de tiempo restante solo aparece cuando hay al menos 3 libros procesados (los datos de velocidad antes de eso son ruidosos y daban estimaciones disparatadas).
- Cuando abandonas un libro, la sesión cierra con la fecha de hoy y un marcador "abandonada". Las stats de "leídos" filtran las abandonadas, así que no inflan tu cuenta de lecturas terminadas.
v0.4.8
Arreglo crítico del catálogo tras enriquecer libros.
Corregido
- El catálogo daba error "invalid_type enrichedAt" después de enriquecer fichas, dejando la app sin libros visibles. Causa: la fecha del último enriquecimiento se guardaba bien en servidor pero al releerla la app no la convertía al formato esperado. La pantalla de Stats mostraba "No se pudo cargar el catálogo" y Catálogo salía vacío. Ahora se lee correctamente.
- Si tienes la app rota: refresca o reinicia. Tus datos están intactos, solo era un problema de lectura.
v0.4.7
Tus subrayados de Kobo, también en Lomos.
Nuevo
- Importamos tus marcadores de Kobo como citas asociadas al libro. Si tenías una nota personal sobre un subrayado, también viene. Al re-importar el mismo archivo no se duplican.
- Más detalle en el resumen de importación: te decimos cuántos marcadores hemos detectado y cuántas citas se han creado al final.
v0.4.6
Las fichas de los libros se completan solas en segundo plano.
Nuevo
- Enriquecimiento automático tras importar: cada libro con ISBN recibe sinopsis, categorías, idioma y portada (cuando faltan) sin que hagas nada. Lo hacemos consultando bases públicas (Open Library y Google Books) en segundo plano. Solo rellenamos lo que tienes vacío; jamás machacamos lo que tú hayas escrito.
- Aviso discreto mientras pasa: aparece una pequeña notificación en la esquina mientras procesa. Si no quieres que use datos del móvil, pausa con un toque y reanuda cuando vuelvas al wifi.
- Cierra la app y vuelve cuando quieras: si paras a media importación, la siguiente vez que entres retoma donde estaba.
- Botón manual en Yo → Mantenimiento para enriquecer fichas cuando tú decidas (útil para libros que añadiste antes y los quieres completar).
Detalles
- Refrescamos cada libro como mucho una vez cada 6 meses (la información no cambia tan rápido). Si quieres antes, usa el botón manual.
- Si una consulta falla, lo reintentamos hasta 3 veces antes de rendirnos.
v0.4.5
Importaciones más completas y arreglos en mostrar estado y reseñas.
Nuevo
- Importación de Goodreads más rica:
- El formato del libro (papel, eBook, audiolibro) se detecta automáticamente con la columna Binding de Goodreads. El filtro Físicos / eBook / Audiolibros del catálogo ya tiene con qué trabajar al instante.
- Tus estanterías personales tipo abandonados, releyendo o pendientes ya se mapean al estado correcto del libro. Antes quedaban como etiquetas y el libro se importaba sin estado.
- El número de relecturas que tuvieras anotado se conserva.
- Las series del título (
Algo (Saga, #2)) se separan automáticamente y aparecen como tal en la ficha del libro.
- Importación de Kobo más rica:
- Sinopsis del libro tal y como la tiene Kobo.
- Serie + número, idioma y subtítulo.
- Tus estanterías personales del Kobo se importan como etiquetas libres del libro.
- Tiempo total leído (en segundos) por libro, según lo que tu Kobo registró.
- Reading abierta para los libros que tienes empezados: si en Goodreads tienes algo como currently-reading o en Kobo en progreso, ahora aparece en Leyendo ahora automáticamente. Antes entraba con estado pero sin sesión y la vista se quedaba vacía.
Corregido
- Las estrellas y el indicador de estado se mantenían en blanco tras una importación (había que limpiar caché manualmente). Ahora se refrescan solos.
- El cálculo de duración de lecturas importadas de Kobo decía "leído en 1 día" aunque hubieras tardado meses. Ahora respetamos la fecha real cuando Kobo la aporta.
Cambios
- Versionado: a partir de aquí usamos
v0.X.Y. Las versionesv0reflejan que todavía estamos en pruebas privadas. Cuando salgamos al público, daremos el salto av1.0.0.
v4.4.3
Arreglo del borrado completo de librería en cuentas viejas.
Corregido
- El botón de borrado completo dejaba a medias algunos elementos (feed de novedades, estado personal) en cuentas creadas antes del rediseño multi-tenant. Ahora limpia todo correctamente. Y si algo fallara, el resto sigue adelante y el aviso te dice qué quedó pendiente.
- La librería ya no se queda mostrando "fantasmas" tras el borrado: se refresca al instante.
v4.4.2
Importación de Goodreads y la fecha de inicio de lectura.
Corregido
- El importador de Goodreads ignoraba la fecha de inicio de lectura y trataba todas las lecturas como leídas en el mismo día. Ahora, cuando el CSV trae fecha de inicio, se respeta. Si no la trae (caso común en históricos antiguos), la lectura se persiste sin fecha de inicio — más honesto que inventarla.
Cambios
- En la lista de lecturas de un libro, una lectura sin fecha de inicio se muestra como "Leído el {fecha}" en lugar de un guion vacío.
v4.4.1
Reset completo de librería + tres bugs corregidos.
Nuevo
- Borrado completo de tu librería en Yo → Zona peligrosa. Vacía
libros, ejemplares, lecturas, reseñas, citas, préstamos, feed y tu
estado personal. Hay que escribir literal
ELIMINARpara activar el botón rojo. Tu cuenta y tu casa se conservan: puedes volver a importar sin tener que pasar por el alta otra vez.
Corregido
- Filtro del catálogo arreglado: "Mi librería" sacaba todos los libros mezclados (papel + eBook), y "eBook" salía vacío.
- Aviso de versión nueva ahora aparece como debe en la app.
- La web mantenía la versión vieja en caché tras un despliegue. Resuelto.
Cambios
- Filtro "ePub" renombrado a "eBook" en el chip y en los mensajes.
v4.4.0
Solicitud pública de invitación + filtros de catálogo.
Nuevo
- Solicitud pública de invitación en
lomos.app/solicitar: cualquier visitante puede pedir acceso enviando nombre, email y un breve mensaje. Las solicitudes llegan al admin para revisarlas. - Panel de admin ampliado: nuevas secciones para ver solicitudes entrantes (con un click se aprueban — genera un código de invitación con el email del solicitante y copia el link al portapapeles) y las sugerencias de los usuarios.
- Filtro Físicos / eBook / Externos / Todos en el catálogo.
Corregido
- Importar de Kobo ya no duplica libros que vinieron de Goodreads cuando el ISBN del eBook es distinto al del libro físico.
Cambios
- En Yo, la entrada "Migración → Importar Goodreads" se renombra a "Importar" y cubre Goodreads + Kobo.
- Botón principal del hero de la web cambia de "Entrar a la app" a "Solicitar invitación".
v4.3.0
Primera versión con web pública, documentación y este changelog.
Nuevo
- Web pública en
lomos.appcon presentación, características y enlaces a la app y a la documentación. - Documentación con secciones de empezar, catálogo, lecturas, tu perfil, compartir librería, importar y compartir reseña.
- Esta página de cambios en
lomos.app/changelog. - Aviso de novedades en la sección Yo de la app: te avisa cuando hay una versión nueva desde tu última visita.
app.lomos.appcomo nuevo subdominio de la app. La home pasa a estar enlomos.app.
v4.2.3
Corregido
- La portada del libro ya se embebe correctamente al compartir reseña como imagen.
v4.2.2
Corregido
- El botón Compartir ahora siempre funciona. Si no hay reseña ni rating, la imagen sale con logo, portada, título y autor.
- Las portadas externas que antes no cargaban por restricciones del navegador ahora se sirven vía proxy y se muestran sin problema.
v4.2.1
Corregido
- El botón Compartir parecía no responder al clic en algunos casos con solo rating sin texto. Resuelto.
v4.2.0
Importadores, compartir como imagen y rediseño de la ficha móvil.
Nuevo
- Importar desde Goodreads con instrucciones paso a paso para obtener el CSV.
- Importar desde Kobo subiendo el archivo
KoboReader.sqlitedel eReader. Reconoce libros por ISBN para no duplicar lo que ya importaste de Goodreads. - Lomos asume posesión inteligentemente: si un libro estaba como "leído fuera" y al importar de Kobo confirmas que lo tienes en eBook, pasa a tu librería compartida automáticamente.
- Etiqueta "ebook" sobre la portada en el catálogo cuando el libro tiene al menos un ejemplar en formato digital.
- Compartir reseña como imagen 1080×1920 estilo story de Instagram. Logo, portada, título, autor, estrellas y tu texto. Se comparte directamente o se descarga como PNG.
- Rediseño de la ficha móvil: cabecera con cover y datos siempre uno al lado del otro. El estado pasa junto al título. Pestañas reordenadas. La cabecera se compacta al hacer scroll.
- Onboarding "Primeros pasos": 5 acciones recomendadas en el catálogo (añade un libro, registra lectura externa, importa, comparte tu librería, empieza a leer). Se va tachando cuando lo haces. Reactivable desde Yo → Ajustes.
Cambios
- Pestaña por defecto de la ficha de un libro ahora es Lectura (en vez de Detalles).
- Pestaña Físico renombrada a Ejemplar (cubre también eBook).
v4.1.0
Nuevo
- Pool de portadas compartido entre usuarios: cuando subes una portada, los demás que tengan el mismo libro la heredan automáticamente.
- Vinculación de email en invitaciones: el código de invitación va asociado al email del invitado y se consume automáticamente al hacer login.
v4.0.0
Migración a multi-tenant: librerías compartidas en casa.
Nuevo
- Cada usuario o pareja tiene su propia librería compartida ("casa").
- Sistema de invitaciones por email con códigos.
- Página Yo → Mi librería con gestión de miembros.
Versiones previas
Lomos arrancó como proyecto personal sin disciplina de changelog hasta la v4.0. En esas versiones tempranas se construyó la base: catálogo, lecturas, citas, préstamos, ejemplares, búsqueda, escaneo ISBN, wizard de portadas, dashboard de stats y reseñas con rating.