33 KiB
Análisis de la aplicación Senza Paura
Revisión técnica y de experiencia de uso del 11 de septiembre de 2026
La prioridad es corregir la autorización del panel antes de ampliar funciones o dar por cerrado el dominio musical. La aplicación compila y supera sus pruebas actuales, pero una petición anónima alcanza acciones administrativas sin comprobar el rol. Además, hay inconsistencias en los créditos, las descargas y el despliegue que esas pruebas no cubren.
Esta revisión identifica 16 hallazgos, cuatro líneas de refactorización y seis propuestas de ampliación. Cada hallazgo distingue el defecto observado de los escenarios que aún requieren una prueba de integración. Las recomendaciones se refieren al código revisado; la configuración efectiva del servidor de producción no se ha inspeccionado.
| Prioridad | Significado | Hallazgos |
|---|---|---|
| P0 | Corregir inmediatamente | H01 autorización administrativa |
| P1 | Resolver antes de ampliar ventas o publicar cambios afectados | H02 a H07 y H10 |
| P2 | Corregir en la siguiente entrega técnica | H08, H09, H11, H12, H13 y H15 |
| P3 | Resolver con mantenimiento editorial | H14 y H16 |
Decisiones recomendadas
- Proteger todas las peticiones del grupo administrativo desde el hook del panel y verificar también los puntos de escritura.
- Completar los intérpretes y endurecer el auditor para que falle ante publicaciones incompletas.
- Separar la biblioteca comprada del catálogo público y garantizar el formato de descarga prometido.
- Actualizar el despliegue para las dos aplicaciones y los tres almacenes compartidos.
- Abordar después las consultas por ruta, los editores grandes y las nuevas funciones.
La base tiene elementos sólidos que conviene conservar: transacciones en pedidos y OTP, consumo único del voto, cookies de sesión limitadas al host, streaming autorizado con rangos y generación de audio sin sobrescribir archivos existentes.
Referencia de la revisión: rama codex/redisenio-dominio-musical, commit c15b4582e765e940fb8be83503a384b27c0f82bc. El árbol de trabajo estaba limpio al comenzar. No se han corregido archivos de la aplicación ni aplicado migraciones durante este análisis.
Alcance y resultados de las comprobaciones
Se revisaron las rutas públicas y administrativas, autenticación, compra, entrega de audio, consultas, esquema, importación, despliegue y pruebas. Se ejecutaron los builds y se recorrieron vistas locales de la aplicación con Chromium. Las consultas adicionales a PostgreSQL fueron de solo lectura y devolvieron agregados.
| Comprobación | Resultado observado |
|---|---|
npm run check |
Sitio y panel con 0 errores y 0 avisos de svelte-check. El proceso del panel imprime una advertencia adicional sobre tsconfig. |
npm run test:unit -- --run |
34 archivos y 387 pruebas pasan. Se imprime un TypeError de inicialización; se reproduce en una segunda ejecución sin check simultáneo. |
npm run lint |
Falla por formato en 11 archivos. ESLint no llega a ejecutarse dentro de este comando. |
npx eslint . |
Pasa por separado, código de salida 0. |
| Builds de sitio y panel | Pasan con node scripts/construir.mjs y su variante --panel; ambos procesos salen con 0. |
| E2E de navegación y responsive | 52 pruebas pasan con dos workers. |
| Muestreo de páginas | Inicio, música, Dorina, carrito y acceso a 375 y 1440 px: diez respuestas 200, sin desbordamiento horizontal ni errores JavaScript observados. |
| Petición anónima al panel | GET redirige al acceso, pero POST inválido ejecuta la validación de la acción H01. |
| Auditor musical y consultas agregadas | 11 principales publicadas, 0 versiones, 6 artistas, 11 másteres MP3 y 11 streams MP3. Cero créditos de interpretación y cero representaciones explícitas de descarga. |
Límites: no se ejecutó la suite E2E completa, un cobro real, un envío de correo ni una edición administrativa válida. Tampoco se probó recuperación de copias, carga concurrente o el proxy real. Los escenarios de cobro duplicado, pérdida de créditos y compra retirada se sustentan en sus rutas de código; no se provocaron en los datos existentes.
Cambios respecto al seguimiento anterior
El plan docs/plan-implementacion-dominio-musical.md sigue siendo útil, pero algunos estados de “hecho” necesitan matices. La generación de stream y onda funciona y tiene prueba real con FFmpeg; la descarga MP3 desde cualquier máster sigue incompleta. Las guardas del catálogo existen, pero no protegen por sí solas las acciones del panel. Los intérpretes son entidades administrables, aunque todavía no están asociados a las canciones publicadas. PR 9 y la división de UI de PR 10 continúan pendientes.
H01 Acciones administrativas sin autorización efectiva
P0 · Confirmado mediante petición local inocua.
El único uso productivo de exigirAdmin está en el load del layout protegido. El hook del panel valida la sesión si existe y luego llama a resolve, incluso cuando locals.usuario es nulo. Las acciones de artistas, canciones, géneros y modelos no comprueban el rol antes de ejecutar su lógica.
Una acción JSON de SvelteKit se resuelve antes del load del layout. El runtime instalado lo muestra en node_modules/@sveltejs/kit/src/runtime/server/page/index.js:57. El comentario que afirma que el layout siempre protege a sus páginas induce a confiar en una barrera que no cubre las escrituras.
Prueba realizada: contra el panel local en el puerto 4174, sin cookies:
GET /artistasdevuelve 303 hacia/entrar.POST /artistas?/crear, con origen local,Accept: application/jsony los campos vacíosnombre=&slug=, devuelve HTTP 200 con resultado de acciónfailure, estado lógico 400 y el mensaje “Escribe un nombre y un slug válidos.”
Esto demuestra que la acción se ejecutó antes de exigir autenticación. La petición vacía termina antes de llamar a crearArtista, por lo que no se crearon ni alteraron datos. Con campos válidos, el código continúa directamente hacia la escritura; ese paso no se ejecutó durante la revisión.
Impacto: una persona capaz de alcanzar el servidor del panel puede invocar operaciones de contenido sin ser administradora. La separación en otro dominio y la protección CSRF no sustituyen la autorización de una petición directa.
Corrección: aplicar exigirAdmin en el hook antes de resolver rutas del grupo (dentro). Mantener las rutas de entrada y salida necesarias fuera de esa guarda. Añadir una comprobación compartida en las acciones o servicios administrativos para que las nuevas rutas no omitan el permiso.
Aceptación: probar GET, datos de navegación, POST normal y POST JSON con usuario anónimo, usuario ordinario, administrador y rol revocado. Verificar tanto la respuesta como la ausencia de escrituras para los tres casos no autorizados.
Código: src/panel/hooks.server.ts:24-37; src/panel/rutas/(dentro)/+layout.server.ts:5-15; src/panel/rutas/(dentro)/artistas/+page.server.ts:9-18; src/lib/server/administracion.ts:1-8.
Documentación de contraste: SvelteKit sobre carga y autenticación. La documentación recomienda comprobar permisos en hooks o en cada carga protegida; no confiar en la ejecución universal de un layout.
H02 El ejemplo de Nginx intercepta la escucha autorizada
P1 · Confirmado en configuración versionada; pendiente contrastar el proxy instalado.
location /escucha/ busca archivos en build/client y devuelve 404 si no existen. La aplicación actual usa esa misma ruta para resolver la canción, comprobar su acceso y entregar el archivo privado desde ESCUCHA_DIR.
Con este archivo de Nginx, /escucha/prometiste no llega a Node y no encuentra el archivo que espera la ruta dinámica. Si permanecen copias antiguas bajo ese prefijo, se siguen ofreciendo como estáticos sin la nueva política de acceso.
Corrección: dirigir /escucha/ al servidor autorizado, o usar una entrega interna del proxy después de autorización. Inventariar los estáticos heredados antes de retirar las copias sobrantes.
Aceptación: a través del proxy, comprobar 200 y 206 para escucha permitida, 401/403 para acceso restringido y ausencia de copias públicas residuales. No basta con probar vite preview.
Código: despliegue/senzapaura.nginx.conf:82-92; src/routes/escucha/[cancion]/[[version]]/+server.ts; src/lib/server/medios.ts:42-49.
H03 El script de despliegue no entrega la arquitectura actual
P1 · Confirmado en el script; riesgo al utilizarlo como procedimiento completo.
El script construye y sube build, pero no build-panel. Transfiere media/audio, pero no media/escucha. En una instalación limpia puede dejar los másteres presentes y la escucha sin sus archivos. Tampoco reinicia el panel.
Además, borra el build y las dependencias remotas antes de completar la transferencia. Una interrupción deja una instalación parcial. La migración se ejecuta con el .env local, sin demostrar que su base sea la del destino SSH.
Corrección: desplegar ambas aplicaciones mediante una versión preparada en un directorio nuevo; mantener los almacenes en rutas persistentes compartidas y cambiar la versión activa al terminar las comprobaciones. Validar explícitamente la identidad del destino de la migración. Definir cómo se provisionan streams y ondas sin sobrescribir material subido desde el panel.
Aceptación: despliegue sobre entorno vacío con una canción, escucha y descarga funcionales; corte de transferencia con la versión anterior aún disponible; comprobación de ambos procesos y ensayo de reversión.
Código: despliegue/desplegar.sh:35-76; despliegue/con-proxy-manager.md:148-190; vite.config.ts:119-130.
H04 El auditor declara íntegro un catálogo sin intérpretes
P1 · Confirmado en PostgreSQL y en la condición de salida del auditor.
La lectura actual devuelve 11 canciones publicadas y 11 publicadas sin intérprete. Hay seis artistas, uno publicado, pero ninguna fila en cancion_interprete. El auditor devuelve salida 0 y anuncia “créditos y streams completos”.
El auditor detecta créditos antiguos sin migrar, pero no canciones sin ningún crédito antiguo ni nuevo. Por tanto, ambos contadores a cero pasan. Esto contradice la validación del panel, que exige un intérprete para publicar, y deja vacías las conexiones entre canciones y discografías.
Corrección: añadir al auditor publicaciones sin intérprete, versiones sin créditos y representaciones de entrega que falten. Completar las asociaciones con identidades confirmadas; no asignar automáticamente un nombre supuesto. Revisar también las publicaciones previas a la nueva validación.
Aceptación: una publicación sin intérprete debe producir un hallazgo y salida distinta de cero. El catálogo corregido debe tener cero publicaciones incompletas. Las fichas de artistas deben enlazar las canciones asociadas.
Código: scripts/db/auditar-dominio-musical.mjs:20-50; src/lib/server/panel-canciones.ts:384-389. La cifra procede de consultas agregadas de esta revisión, no del documento anterior.
H05 Guardar una canción elimina detalles del crédito principal
P1 · Confirmado por lectura; requiere créditos detallados para manifestarse.
guardarCancion borra todos los créditos de rol principal y los inserta de nuevo usando únicamente artista, rol y orden. El esquema permite instrumento y acreditadoComo; esos valores desaparecen aunque el usuario solo haya cambiado el título o la letra. Los otros roles no se borran en ese bloque.
Actualmente no hay créditos en la base revisada, por lo que no se ha observado pérdida histórica. El defecto aparecerá al completar los datos detallados que prevé el plan.
Corrección: reconciliar altas y bajas conservando los atributos de las relaciones existentes. Editar los campos detallados de forma explícita y preservar la acreditación histórica al cambiar el nombre del artista.
Aceptación: crear en una base aislada un crédito con instrumento, acreditación y orden; cambiar solo el título de la canción y verificar que esos tres valores se conservan.
Código: src/lib/server/panel-canciones.ts:699-711; src/lib/server/db/schema/catalogo.ts:222-248.
H06 Las compras retiradas desaparecen de la biblioteca
P1 · Confirmado por el recorrido de datos; sin retirar canciones reales.
La cuenta transforma data.compras en canciones mediante el catálogo público y descarta los resultados ausentes. Si se retira una canción, su álbum o su estilo, esa canción deja de aparecer en “Mis canciones”. Las versiones retiradas también quedan fuera de los enlaces generados desde ese catálogo.
La autorización de descarga sí permite resolver material comprado que ya no está publicado. El derecho puede seguir existiendo, pero la interfaz deja de ofrecer el enlace. Esto contradice el mensaje “Las descargas no caducan” y puede mostrar una biblioteca vacía a alguien con compras.
Corrección: devolver desde la cuenta un modelo específico de biblioteca comprada con títulos históricos, estado de disponibilidad y enlaces autorizados. Separar la visibilidad pública de la disponibilidad para compradores.
Aceptación: después de retirar la canción, su disco o su estilo en una base aislada, el comprador conserva sus enlaces permitidos y un visitante público no recupera la ficha retirada.
Código: src/routes/(sitio)/cuenta/+page.svelte:19-22,75-114; src/lib/server/catalogo.ts:193-195; src/lib/server/audios.ts:84-125.
H07 La subida de un máster no garantiza la descarga MP3 prometida
P1 · Defecto confirmado en el flujo; condicionado a subir un formato distinto de MP3.
Stripe describe la compra como descarga MP3. El alta acepta WAV, FLAC, M4A, AAC y OGG, pero genera únicamente máster y stream. La descarga prioriza una representación descarga y, si no existe, entrega el máster original con su extensión.
Un WAV subido desde el panel termina ofreciéndose como WAV al comprador, aunque el producto indique MP3. En la base actual los once másteres ya son MP3 y no hay representaciones explícitas de descarga: los datos actuales ocultan la discrepancia del flujo nuevo.
Corrección: generar y registrar la representación MP3 comercial desde el máster, con un perfil de calidad explícito. Conservar el original como archivo y evitar que la ausencia de un derivado cambie silenciosamente el formato vendido. Si se desean varios formatos, mostrarlos como opciones de producto.
Aceptación: probar WAV, FLAC y MP3 de entrada; verificar MIME, extensión y metadatos técnicos del archivo descargado. No presentar una conversión desde una fuente comprimida como recuperación de calidad perdida.
Código: src/lib/server/ingreso-audio.ts:21-28,243-245; src/lib/server/panel-canciones.ts:429-478; src/lib/server/audios.ts:119-125; src/lib/server/stripe.ts:72.
H08 Las versiones no reciben las mismas guardas de publicación
P2 · Confirmado en código; actualmente hay cero versiones en la base.
La acción valida el stream de la canción principal mediante actual.tieneAudio. En el bucle de versiones se comprueban valores básicos y se escribe el estado solicitado, sin verificar su propio stream ni sus créditos. Una versión recién creada como borrador puede pasar a publicada con el audio principal presente, aunque ella carezca de audio.
Corrección: validar cada grabación que cambia a publicada dentro del servicio de dominio y la transacción; devolver errores asociados a la versión concreta. La carga de audio actual también está limitada a principales, por lo que debe completarse el recorrido de versiones.
Aceptación: impedir publicar una versión sin stream o intérprete sin bloquear los cambios válidos de su principal. Código: src/panel/rutas/(dentro)/canciones/[slug]/+page.server.ts:68-74; src/lib/server/panel-canciones.ts:391-400,597-610,713-729.
H09 La invalidación del panel no alcanza la caché del sitio
P2 · Confirmado por separación de procesos.
El catálogo se conserva en una variable de módulo durante 60 segundos. El panel llama a olvidarCatalogo, pero vacía su propia memoria; el proceso público conserva su copia. Un cambio guardado puede tardar hasta la caducidad de esa copia en aparecer, y las pestañas ya abiertas requieren además refrescar sus datos.
Corrección: retirar primero la caché global al introducir consultas pequeñas por ruta, o usar una revisión persistente de contenido que ambos procesos observen. Evitar añadir un servicio de caché antes de medir. Revalidar disponibilidad al cobrar.
Aceptación: modificar un contenido desde el panel y comprobar su visibilidad en otro proceso según una latencia definida. Código: src/lib/server/catalogo.ts:72-85; src/lib/server/panel-canciones.ts:773; vite.config.ts.
H10 Varias solicitudes de pago abren sesiones independientes
P1 · Riesgo confirmado en el diseño; no se realizaron cobros.
Cada POST de pago crea una nueva sesión Stripe y un nuevo pedido. No hay clave de idempotencia de la intención de compra ni recuperación de una sesión pendiente equivalente. El botón no queda bloqueado por envío en curso. Dos pestañas pueden abrir dos sesiones válidas para las mismas canciones y pagar ambas.
La idempotencia de finalizarPedido resuelve repeticiones de una misma sesión, no sesiones distintas. Ignorar compras duplicadas en SQL tampoco devuelve un segundo cobro.
Corrección y aceptación: representar una intención de compra por cuenta y selección; reutilizar su sesión y usar idempotencia en Stripe. En pruebas con proveedor simulado, dos peticiones simultáneas deben devolver la misma intención y una única sesión. Código: src/routes/(sitio)/carrito/+page.server.ts:93-117; src/routes/(sitio)/carrito/+page.svelte:147-151; src/lib/server/stripe.ts:60-85; src/lib/server/pedidos.ts:134-172.
H11 El modo de espera también bloquea los webhooks
P2 · Confirmado en el enrutamiento; condicionado a activar PROXIMAMENTE.
El portón permite únicamente la página de espera y /_app/ para direcciones no autorizadas. Un POST externo a /api/stripe/webhook termina redirigido a la espera antes de verificar su firma. Si se activa el cierre con sesiones de pago todavía abiertas, sus confirmaciones dejan de procesarse mientras continúe activo.
Corrección: permitir la ruta exacta del webhook a través del portón, manteniendo obligatoria la firma Stripe. Definir también el comportamiento de los retornos de pago durante el cierre.
Aceptación: con el portón activo, un evento firmado llega al controlador y uno inválido se rechaza; las páginas públicas siguen cerradas. Código: src/hooks.server.ts:58-60; src/lib/server/proximamente.ts:59-60; src/routes/api/stripe/webhook/+server.ts.
H12 El límite de subida no reserva espacio al formulario
P2 · Confirmado en límites configurados; sin subir un archivo grande.
El archivo admite 256 MiB, pero el cuerpo HTTP completo también tiene un límite de 256M y el proxy documenta 256m. Un archivo que alcanza el máximo válido requiere bytes adicionales para cabeceras multipart y los demás campos; se rechaza antes de que la validación de la aplicación pueda responder de forma útil.
Corrección: dejar margen acotado para el formulario o reducir el límite visible del archivo. Alinear el límite del proxy con el del adaptador. La transcodificación síncrona merece además un trabajo en segundo plano si aumenta el uso: cada proceso tiene hasta cinco minutos y el proxy dispone de 300 segundos para la petición completa.
Aceptación: verificar justo por debajo, en el límite y por encima; probar el conjunto proxy y adapter-node. Código: src/lib/server/ingreso-audio.ts:19,76,102,242; .env.example:18; despliegue/con-proxy-manager.md:174-185.
H15 La señal de calidad no está completamente limpia
P2 · Reproducido con los comandos del proyecto.
Vitest anuncia 387 pruebas correctas y salida 0, pero imprime Cannot read properties of undefined (reading 'wrapDynamicImport') durante la inicialización de SvelteKit. Se repite ejecutando la suite sin una sincronización de tipos simultánea. La causa exacta de la interacción entre versiones y entorno necesita diagnóstico; no se atribuye aquí a un paquete concreto.
El lint falla en 11 archivos por Prettier. Los E2E del panel prueban acceso visual, no POST anónimos. Por eso una suite verde no ha detectado H01.
Corrección y aceptación: aislar la configuración de pruebas si procede, eliminar el error de arranque, restaurar el formato e incorporar integración HTTP y PostgreSQL para las invariantes sensibles. Exigir pruebas sin excepciones inesperadas en stderr. Código: vite.config.ts sección test; package.json scripts; e2e/panel.e2e.ts:5-10; runtime señalado en H01.
H13 El modal deja una columna vacía en pantallas bajas
P2 · Confirmado visualmente en Chromium a 1024 por 500 px.
La regla de altura oculta la ilustración, pero conserva las dos columnas de .marco. El formulario ocupa la primera columna, de 320 px, y deja otra de 382 px vacía dentro de un diálogo de 704 px. El cierre queda junto al formulario en vez de en el extremo del marco. El fallo también es relevante al usar zoom o una ventana baja.
Corrección: cuando se oculta la ilustración, convertir el marco en una columna y limitar el ancho al del formulario. Mantener el foco y el botón de cierre accesibles.
Aceptación: comprobar 1024 por 500 y 844 por 390 px, zoom al 200 %, teclado y retorno del foco al activador. Código: src/lib/components/ModalAcceso.svelte:167,273-297.
H14 La cuenta anuncia packs de cinco en una tienda de diez
P3 · Confirmado en el texto de la interfaz.
El estado vacío de “Mis canciones” afirma que se vende en packs de cinco. La regla real exige diez y el resto de la compra usa ese tamaño. Es una contradicción comercial visible para quien acaba de crear su cuenta.
Corrección: componer el mensaje con CANCIONES_POR_PACK, y centralizar también precio, formato e inclusión de versiones en los mensajes de producto.
Aceptación: con cuenta sin compras, verificar que la pantalla coincide con el carrito y Checkout. Código: src/routes/(sitio)/cuenta/+page.svelte:77; src/lib/tienda.ts:15.
La identidad visual general se mantiene coherente en las vistas revisadas. Las 52 pruebas seleccionadas cubren navegación, anchos, controles, respuesta al puntero, contraste del dorado y comportamiento del fondo. Estos resultados no equivalen a una certificación integral de accesibilidad.
H16 La documentación mezcla procedimientos actuales y retirados
P3 · Confirmado en documentación versionada.
README indica que migrar crea local.db y anuncia el panel en /admin, aunque la aplicación usa PostgreSQL y un build separado. .env.example describe SQLite y Turso sobre una URL PostgreSQL. También se dice que faltan páginas legales que ya tienen rutas y contenido; eso no permite concluir que su contenido esté validado, solo que el inventario está desactualizado.
Corrección: distinguir puesta en marcha actual, importación histórica y despliegue de dos procesos. Retirar los comentarios de catálogo que afirman que todavía no hay administración. Eliminar la explicación errónea sobre autorización en layouts señalada en H01.
Aceptación: otra persona debe poder arrancar sitio y panel siguiendo únicamente el procedimiento documentado. Código: README.md:66,73,86,185-188; .env.example:2; src/lib/server/catalogo.ts:23,76.
Refactorizaciones recomendadas
R01 Consultas específicas por pantalla. El layout público envía el catálogo completo a cualquier página. La carga del catálogo consulta la fila completa de cada canción, incluida la letra que luego se reduce a extracto, y varias relaciones completas. El pago resuelve compras tema a tema. Crear modelos de listado, ficha, reproductor, carrito y biblioteca comprada; consultar en lote los identificadores necesarios. Medir bytes del HTML y datos, número de consultas y latencias antes y después. Fuentes: src/routes/(sitio)/+layout.server.ts:27-34; src/lib/server/catalogo.ts:180-198; src/routes/(sitio)/carrito/+page.server.ts:68-78.
R02 Separar responsabilidades en los módulos grandes. Hay 1211 líneas en Capitulo.svelte, 1137 en el editor de géneros, 775 en panel-canciones.ts y 662 en TablaCanciones.svelte. El tamaño orienta dónde revisar, pero no constituye por sí solo un error. Extraer secciones de edición, validadores, presentación de créditos y servicios de audio según sus responsabilidades; conservar contratos estables y evitar fragmentar por número arbitrario de líneas.
R03 Consolidar reglas de dominio. La publicación, la acreditación, la selección de audio y las reglas comerciales están repartidas entre acciones, consultas y componentes. Crear operaciones explícitas como publicar grabación, registrar crédito y preparar entrega. Aplicar la misma validación desde panel e importadores. La base debe seguir garantizando las invariantes que pueda expresar, sin delegarlas únicamente al formulario.
R04 Dar un ciclo de vida recuperable al procesado. La publicación de archivos y la transacción PostgreSQL compensan fallos controlados, pero no forman una transacción única frente a la caída del proceso. Registrar trabajos y sus estados, limitar concurrencia y añadir reconciliación de temporales y archivos huérfanos. Mantener la estrategia de no sobrescribir. Introducir esta infraestructura cuando se implemente regeneración o subida frecuente; priorizar antes H01 y las entregas incorrectas.
Mejoras de diseño y funciones propuestas
Estas propuestas son ampliaciones, no defectos confirmados. Deben implementarse después de proteger el panel y cerrar los problemas que afectan a compras y datos.
A01 Alta musical completa. Añadir portada opcional con previsualización, recorte y validación; asociar intérpretes sin abandonar el alta y mostrar el estado de máster, stream, onda y descarga. Completar audio propio por versión y créditos con rol, instrumento, acreditación y orden. Valor alto para publicación diaria; esfuerzo medio o alto, dependiente de H05, H07 y H08.
A02 Biblioteca y pedidos gestionables. Mostrar disponibilidad, formato y tamaño de cada descarga; ofrecer pedidos pendientes y una vía clara para incidencias. Añadir conciliación de pagos y estados de reembolso en el panel. Una descarga conjunta puede evaluarse si hay demanda, cuidando que los archivos se preparen sin cargar todos los másteres en memoria. Dependencias: H06, H07 y H10.
A03 Listas con edición completa. La implementación actual permite crear una lista con una canción y alternar pertenencia. Añadir renombrado, borrado con confirmación y orden mediante teclado y controles accesibles; preservar la propiedad de la lista en servidor. Criterio de éxito: ordenar una lista desde móvil y verla igual al volver a entrar.
A04 Recorrido comprensible de la suscripción. La cuenta muestra si está activa, pero no ofrece contratación o gestión. Si el catálogo exclusivo va a comercializarse, completar alta, estado, renovación, cancelación y acceso al portal de gestión. Si es una concesión manual, explicar cómo solicitarla. El esquema de suscripción existente no implica que todo ese producto esté implementado.
A05 Descubrimiento y primera escucha. En la portada móvil revisada, el disco decorativo ocupa la parte superior y la llamada principal comienza cerca de los 800 px de altura. Probar una composición más compacta que acerque “Poner el disco” al primer tramo visible. Conservar la identidad de la marca y medir inicio de reproducción; no asumir que menos imagen mejora necesariamente la experiencia. En el catálogo, facilitar la llegada a intérpretes y explicar los estilos sin obras disponibles.
A06 Estado operativo del catálogo. Crear una vista que reúna publicaciones sin intérpretes, medios ausentes, derivados pendientes y fallos de procesado. Mostrar acciones concretas para resolverlos. Diferenciar integridad de relaciones en PostgreSQL de existencia y calidad de los archivos: el auditor actual no demuestra por sí solo que los 22 audios estén físicamente presentes ni que se puedan decodificar.
Criterios de diseño transversales
Conservar tipografía, contraste y la distinción entre contenido y controles. Hacer consistentes los estados vacío, cargando, error y guardado; indicar el progreso de operaciones largas. Validar móviles en vertical y horizontal, zoom, teclado y tecnologías de asistencia en los flujos principales. Evitar cambios visuales generales hasta resolver los defectos concretos y contar con una hipótesis medible.
Secuencia de trabajo propuesta
Entrega inmediata. Corregir H01 y añadir las pruebas HTTP de autorización antes de reabrir el panel a usuarios no controlados. Revisar la configuración efectiva del proxy para determinar si H02 está presente. La auditoría no demuestra que el defecto se haya explotado.
Entrega de integridad y compra. Completar intérpretes y auditor; preservar créditos al guardar; separar la biblioteca comprada; generar la representación comercial; aplicar guardas a versiones e idempotencia de la intención de pago. Preparar casos de integración en una base aislada antes de modificar datos existentes.
Entrega operativa. Actualizar despliegue y rutas compartidas, resolver el paso de webhooks durante el cierre y alinear límites de subida. Ensayar instalación limpia, reinicio, interrupción del despliegue y restauración de una copia.
Entrega de mantenimiento y producto. Limpiar la señal de tests y lint, corregir el modal y textos, actualizar README e introducir modelos por ruta. Después, completar el alta de portadas y versiones, listas y gestión comercial según las prioridades del negocio.
Comprobaciones de cierre
| Área | Evidencia necesaria para cerrar |
|---|---|
| Autorización | Ninguna petición no autorizada ejecuta consultas sensibles o escrituras del panel. Probar también rol revocado. |
| Datos | Cero publicaciones sin créditos o stream; guardar campos básicos conserva acreditaciones detalladas. |
| Compra | Una intención genera un único Checkout; confirmar dos veces no duplica derechos; retirar una ficha no oculta descargas permitidas. |
| Medios | Fuentes WAV y FLAC producen la descarga MP3 descrita. MIME, rango, tamaño y autorización comprobados. |
| Operación | Sitio y panel arrancan desde una instalación limpia y comparten almacenes correctos; no se pierde servicio ante un fallo de transferencia. |
| Interfaz | Modal sin columna vacía, mensajes comerciales consistentes, teclado y zoom comprobados. |
| Calidad | Check, formato, ESLint, unitarias e integración pasan sin excepciones de inicialización inesperadas. |
Inventario del fallo de formato
Prettier señaló once archivos: Capitulo.svelte, FormularioAcceso.svelte, Heroe.svelte, player/BarraReproductor.svelte y TarjetaEstilo.svelte dentro de src/lib/components; y las páginas de inicio, blog, entrada de blog, carrito, letristas y legal dentro de src/routes/(sitio). ESLint pasó al ejecutarse de forma independiente.
