You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
senzapaura_es/docs/modelo-de-datos.md

15 KiB

Modelo de datos

Diseño de la migración del contenido a PostgreSQL. Fase 1 —este documento— está entregada y pendiente de verificación; no hay código escrito todavía.

Versión presentable, con diagramas entidad-relación: https://claude.ai/code/artifact/d87ceb4d-6038-402f-852e-13ff5d86f02f

Este archivo es la especificación; el artefacto es la misma información puesta para leerse. Cuando se implemente, la verdad pasa a ser src/lib/server/db/schema.ts y esto queda como el porqué.

Por qué

Lo que hay hoy en src/content/** son registros disfrazados de documento: una canción tiene veinte campos estructurados en YAML —registro, duracion, interpretes, versiones, videos, etiquetas— y la letra entera también va en el frontmatter. El cuerpo en Markdown son cuatro líneas de comentario.

Dos hallazgos concretos, no cuestión de gusto:

1. Alguien puede perder una canción que pagó. Cinco tablas apuntan a una canción por una cadena de texto —carrito_item, pedido_item, compra, favorito, valoracion— y ninguna tiene clave foránea, porque el destino no está en la base sino en un archivo. Renombrar un slug deja huérfana una compra sin que salte ningún error en ningún sitio.

2. estilo hace dos trabajos distintos. En el catálogo son las secciones del artista (baladas románticas, clásica, rock, pop melódico); en el taller, una «ficha de estilo» es un género hispanoamericano (bolero, tango, cumbia). Son dos entidades que comparten palabra y hoy comparten nombre en el código. La clasificación por país es del género, no del estilo, y mientras sean lo mismo no se puede ni escribir.

A eso se suma que nada se valida —estilo: bolreo no falla, la canción desaparece de su sección—, nada se consulta sin cargar el catálogo entero en memoria, y cambiar una coma exige reconstruir y desplegar.

Alcance: 49 tablas (13 ya existen), 48 archivos que migrar, 22 rutas que hoy leen $lib/content.

Decisiones transversales

Decisión Elegido Motivo
Identificadores text (nanoid 21), como las tablas actuales El slug es texto que se lee y algún día se corrige; una clave primaria no debería cambiar nunca
Slugs únicos + tabla redireccion Renombrar deja de romper enlaces publicados; la dirección vieja responde 301
Prosa columna text con Markdown, compuesto en el servidor Comprobado: ningún archivo de contenido usa sintaxis de Svelte, así que no se pierde nada al dejar de compilarlo con mdsvex
Listas tabla si se consulta, text[] si solo se enseña Las etiquetas cruzan el catálogo; los temas y rasgos de un género solo se pintan
Publicación estado (borrador · publicado · retirado) Escribir una ficha a medias no puede significar publicarla
Fechas timestamptz siempre; creado_en y actualizado_en Y en los legales, además, historial: hay que poder demostrar qué decía el día de una compra
Enumerados texto con CHECK, no ENUM de Postgres Es lo que genera Drizzle y permite añadir un valor sin una migración que bloquee la tabla
Borrados reales en contenido; retirado en lo vendido Una canción comprada no se borra nunca: la compra tiene que seguir apuntando a algo

Las entidades

  • estilo (cambia) — id, slug, nombre, resumen, orden, principal con índice parcial único (hoy es un acuerdo de palabra), imagen_id, estado.

  • album (cambia) — + numero_catalogo, formatos text[], pais_edicion_id. Los campos de edicion dejan de estar anidados.

  • cancion (cambia) — album_id nulo en los singles; el álbum «Singles» deja de existir como registro, era un invento para pintar y se resuelve al consultar. letra, nota, inspiracion y traducción salen del YAML.

  • cancion.version_de_id (decidido) — una versión es una fila de cancion, no una tabla aparte. Nulo en las principales. Se llegó aquí descartando partir en obra y grabacion: en ese reparto el estilo y las etiquetas colgarían de la obra, y una versión no podría tener los suyos —una balada con arreglo de bolero no cabría—. Con una fila por versión, cualquier campo puede cambiar.

    De regalo se arregla algo que estaba mal: el disco pasa a ser de la fila. Hoy album_id y numero cuelgan del tema, así que la «Maqueta 2018» es el corte 1 del álbum igual que la versión de estudio, y es falso.

    Cuatro cabos que hay que atar, o se vuelve en contra:

    1. Vista cancion_principal. Cuatro funciones devuelven listas de canciones y siete rutas las pintan, más los recuentos por estilo y por etiqueta. Si a una se le olvida version_de_id IS NULL, el catálogo dice veinticinco temas donde hay dieciocho y nadie lo nota. Lo normal es consultar la vista; pedir versiones es lo que hay que escribir a propósito.
    2. Un solo nivel, comprobado en la base. Una autorreferencia admite ciclos —A apunta a B y B a A— y una consulta recursiva sobre eso se cuelga. Se ataja con una clave foránea compuesta contra una columna generada es_version, sin triggers.
    3. ala_venta solo en las principales, y comprar la principal entrega todas sus versiones. Es la regla que ya estaba escrita, ahora literal.
    4. Los campos se copian al crear, no se heredan al leer. Un nulo heredado nunca se sabe si es «no lo sé» o «lo mismo de arriba». Y aquí copiar es además lo correcto: la maqueta de 2018 no tiene la misma letra, le falta el puente.
  • persona (nueva) — nombre, nombre_legal, ipi. Hoy autores e intérpretes son cadenas sueltas repetidas en cada archivo.

  • cancion_persona (nueva) — rol (letra · musica · interprete · arreglos · produccion), orden.

  • version — desaparece como tabla: cada versión es una fila de cancion con version_de_id. El isrc va en esa fila, no en la principal: identifica una grabación, y cada arreglo es una grabación distinta. El iswc es de la composición y se repite en la familia.

  • registro_obra (cambia) — iswc, entidad, numero, editorial. 1:1 con la canción.

  • autoria (cambia) — porcentaje numeric(5,2), no entero: los repartos reales llevan decimales. Suma 100 comprobado en la base.

  • etiqueta, cancion_etiqueta (cambia) — hoy se deducen de texto libre, así que «desamor» y «Desamor» son dos etiquetas y nadie lo ve.

  • traduccion (nueva) — cancion_id + idioma. Hoy solo cabe una.

  • video, cancion_enlace, album_enlace, credito_album (cambia) — dos tablas de enlaces y no una polimórfica: una clave foránea de verdad vale más que ahorrarse una tabla.

2 · Taller, géneros y glosario

Decidido: el catálogo de géneros aspira a ser completo y se llena poco a poco. Eso cambia el peso de esta área: la ficha de género deja de ser una tarjeta y pasa a ser la pieza más rica del sitio, con su historia, sus instrumentos, sus letristas y sus obras de referencia.

  • pais (nueva) — código ISO 3166-1, nombre, gentilicio, region.

  • genero (nueva) — bolero, tango, cumbia. Solo lo corto y comparable va en columnas: compas, tempo, metrica, rima, origen_lugar, origen_ano (ordenable, hoy no lo es). Eso es lo que se pone en una tabla para comparar géneros. Y padre_id para la jerarquía: los subgéneros son sus hijos y el género del que deriva es su padre, sin nada más. Sin jerarquía, «todas las variantes» es una lista plana de cien nombres sin relación.

  • genero_seccion (nueva) — clave, titulo, cuerpo, orden. Toda la prosa de la ficha: introducción, historia, estructura de las canciones, motivación y temática. Y lo que surja mañana. Con una columna por bloque, en un mes hay quince columnas y la mitad vacías; siendo secciones ordenadas, un apartado nuevo no cuesta una migración. Es la respuesta a «y otros campos que puedan surgir».

  • genero_pais (nueva) — relacion: cuna · adoptado. La cumbia nace colombiana y se hace mexicana, peruana y argentina; el tango es de las dos orillas. Un solo país sería mentira.

  • instrumento (nueva) — slug, nombre, familia (cuerda · viento · percusión · teclado · electrófono · voz) y subfamilia libre, pais_codigo, descripcion, afinacion, imagen_id y muestra_id contra medio —el sonido de muestra es un archivo como cualquier otro—, estado.

  • genero_instrumento (nueva) — con importancia (esencial · habitual · ocasional) y papel («marca la clave», «lleva el bajo»). Sin eso, el tres cubano y una trompeta ocasional pesarían igual en la ficha, y no es verdad.

  • genero_persona (nueva) — papel: letrista · compositor · interprete · fundador. No hay tabla letrista: un letrista es una persona, y con dos tablas la misma acabaría existiendo dos veces con distinta grafía el día que colabore con alguien que además es figura de un género. persona gana los campos biográficos: nacimiento, defuncion, pais_codigo, retrato_id, semblanza.

  • obra_referencia + obra_referencia_persona (nueva) — titulo, ano, genero_id, nota, enlace, cita. «Letras de referencia de un letrista» y «canciones del género» son la misma entidad, mirada desde un lado o desde el otro.

    ⚠️ No se alojan letras completas de terceros. «Bésame mucho» tiene dueño y lo tendrá durante décadas. Se cita título, autor, año y un fragmento breve al amparo del derecho de cita —el mismo que invoca nuestro propio aviso legal— y se enlaza a dónde escucharla. Por eso el campo se llama cita y es corto, no letra.

  • cancion_genero (nueva) — un tema propio escrito en ese género, aunque en el catálogo viva bajo «baladas románticas». Es lo que permite que una ficha enseñe obra propia además de la ajena.

  • capitulo (cambia) — tipo (principio · ficha), genero_id solo en las fichas, cuerpo, estado.

  • termino (nueva) — el glosario. termino único, categoria, definicion de una o dos frases (lo que cabe en un globo sin taparle el texto a nadie), ampliacion, ejemplo.

  • termino_variante (nueva) — «sinalefas», «heptasílabos». Sin esto el marcado solo acierta en singular, que es casi nunca.

  • capitulo_termino (nueva) — se calcula al guardar el capítulo, no al pintarlo; y siendo tabla, se puede desmarcar una aparición cuando la palabra esté usada en otro sentido.

Regla editorial: solo la primera aparición de cada término por página. Marcar las veintidós veces que sale «estribillo» convierte el texto en un campo de minas subrayado.

3 · Editorial

  • entrada, entrada_cancion, entrada_etiqueta (cambia) — hoy la lista de canciones son slugs sin comprobar: si el tema no existe, la entrada enlaza a un 404 y nadie se entera.
  • documento_legal + version_legal (nueva) — historial con vigente_desde y resumen_cambios. No es burocracia: es prueba.
  • pagina, redireccion (cambia / nueva).

4 · Cuentas y comercio

  • usuario, identidad, sesion, codigo_acceso, limite (sin cambios).
  • carrito_item, pedido_item, compra (cambia) — cancion_slug text pasa a cancion_id fk. En pedido_item se congelan título y precio: una factura tiene que seguir diciendo lo que decía.
  • datos_facturacion (nueva) — tipo, nombre, nif, dirección, pais_codigo (decide el IVA), predeterminada.
  • factura (nueva) — serie y numero correlativos y sin huecos, base, iva_tipo, iva_cuota, total, y datos_congelados jsonb: si el cliente cambia su dirección, la factura vieja no puede cambiar con él.
  • descarga (nueva) — para poder demostrar la entrega en una reclamación.

5 · Interacción

  • favorito, valoracion (cambia) — clave foránea, y CHECK de 1 a 5 en la base y no solo al validar.
  • reproduccion (nueva) — con segundos: una reproducción de tres segundos no es una escucha, y contarla igual falsea la cifra. Agregación por día y borrado del detalle a los noventa días son parte del diseño, no un apaño para después.

6 · Medios

  • medio (nueva) — clase, clave, publico (los fragmentos sí, el audio completo nunca; hoy eso lo garantiza la carpeta), mime, bytes, duracion_s, ancho, alto, sha256, alt. Para que la administración pueda subir audio, un archivo tiene que ser una fila.

7 · Bocetos, no se construyen ahora

lista + lista_cancion (la playlist que sigue sin definirse), encargo, inscripcion_taller. Se dejan sitio porque aparecer después obliga a migrar lo ya cargado.

Qué cambia en la web

  1. Sveltia CMS deja de servir. Es un editor sobre git. Hasta que exista la administración propia —decidido: para después—, el contenido se carga por script y por SQL.
  2. El Markdown se compone en cada petición, no al construir. Se cachea.
  3. Cada página consulta la base. A cambio, cambiar una letra deja de exigir un despliegue.

Fases

  1. Este documento. Sin código. ← estamos aquí
  2. Esquema y migración, con el sitio leyendo todavía de los archivos. Un script vuelca los 48 archivos y comprueba que lo volcado coincide. Si algo no cuadra, se ve antes de que dependa nadie de ello.
  3. Las claves foráneas de las compras. Lo primero que se cambia de verdad, porque es lo único que hoy puede costarle dinero a alguien.
  4. Las 22 rutas, de archivos a consultas. Área por área, con las pruebas existentes de guía.
  5. Lo nuevo: géneros por país, glosario con globos, introducción larga del taller.
  6. La administración.

Pendiente de respuesta

Seis decisiones de negocio. Cambiarlas después de cargar el contenido cuesta mucho más que ahora.

  1. ¿Los géneros del taller aspiran a ser un catálogo completo? Respondido: sí, y se irá llenando poco a poco. De ahí la jerarquía, las secciones y la ficha ampliada.
  2. ¿Quién escribe las fichas que faltan? Es musicología: un compás equivocado sale publicado con su nombre.
  3. ¿El glosario se marca solo o a mano? «Clave» es un término del son y también una palabra normal.
  4. ¿Facturas con numeración correlativa? Si se vende, sí, y la serie no puede tener huecos ni empezar tarde.
  5. ¿Se conservan las escuchas por persona? Cambia la política de privacidad, que hoy dice que no se hace seguimiento.
  6. ¿Dónde viven los archivos: disco del servidor o almacenamiento aparte?

Powered by TurnKey Linux.