Los 48 archivos entran en la base: 18 canciones con sus 5 versiones como
filas hermanas, 4 discos, 4 estilos, 8 géneros, 14 capítulos, 9 personas,
53 etiquetas, 2 entradas, 5 legales y una página. La web sigue leyendo de
los archivos; esto solo llena el sitio donde caben.
Reutiliza los analizadores del sitio en vez de leer el frontmatter otra
vez. Es la decisión que sostiene todo lo demás: si un valor por defecto o
una normalización cambian, cambian para los dos. Un segundo analizador
«parecido» es lo que garantiza que un día la base y la web cuenten cosas
distintas sin que nadie lo note.
Todo en una transacción, y al final comprueba lo escrito contra lo leído
—la letra de cada tema carácter a carácter— porque «no dio error» no es lo
mismo que «está bien». Si no cuadra, deshace y dice qué falló. Y es
idempotente: se puede lanzar las veces que haga falta sin duplicar nada,
sin tocar cuentas, pedidos ni compras.
Para poder reutilizar ese código desde Node hizo falta un gancho de
resolución —`$lib`, imports sin extensión y un sustituto de `$app/paths`—
y quitar una propiedad de parámetro de `ErrorDeContenido`: es sintaxis
exclusiva de TypeScript y ningún cargador que solo borre tipos puede con
ella.
Y una corrección: el cuerpo del Markdown de una canción NO era un
comentario, es la letra. Lo dije al revés en el documento del modelo y lo
repetí varias veces. El campo `letra:` del frontmatter —que aparece en un
solo archivo— son los créditos de quién la firma. Corregido en el
documento, en el esquema, y quitada la columna `nota` que sobraba.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Las dos ultimas decisiones se toman por defecto eligiendo la opcion
reversible en cada caso: valoracion y favoritos en la cancion principal
—si cada version se valorase aparte, la media de la tarjeta dejaria de
significar nada— y prompts privados, porque publicarlos manana es cambiar
una columna y despublicarlos cuando ya estan indexados no.
Queda apuntado lo que no es una tabla y hay que hacer igual: reescribir
la politica de privacidad antes de guardar escuchas, la ventanilla unica
del IVA, y el DNS y el certificado de m.senzapaura.es.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Glosario: `termino` se parte en termino y acepciones numeradas, y el
marcado apunta a una acepcion. Eso cierra la duda del automatico: sabe
encontrar la palabra pero no elegir el sentido —«clave» es patron ritmico
en un texto de bolero y armadura en uno de armonia—, asi que propone y
una persona confirma.
Facturas: el correlativo sale de un contador con bloqueo y no de
max(numero)+1, que con dos compras simultaneas daria el mismo numero. Y
hacen falta rectificativas: una venta anulada no borra su factura. El IVA
es el del pais del comprador, no el nuestro.
Escuchas: se conservan por persona, y eso obliga a reescribir la politica
de privacidad, que hoy afirma que no hay seguimiento.
Medios en m.senzapaura.es: cambia una decision anterior. Estaba escrito
que las descargas no usan URLs firmadas porque la sesion va delante; en
otro dominio ya no va, asi que para el audio completo la firma deja de
ser opcional.
Fichas por JSON: el contrato de importacion pasa a ser parte del modelo,
con esquema, procedencia y creacion marcada de lo que la IA se invente.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Los temas salen del array a `genero_tema` y comparten vocabulario con las
etiquetas de las canciones. No es por ahorrar una tabla: es lo que
permite cruzar «el desamor: nueve temas mios y cuatro generos que viven
de el». Con dos listas separadas, «desamor» y «desamor» serian dos cosas
distintas y nadie lo veria.
Los rasgos se quedan como array porque si son prosa de verdad.
Y la completitud de una ficha se deduce de sus secciones y relaciones, sin
columna: una marca de progreso que se pone a mano miente a la semana.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`padre_id` no aguantaba. Un genero no deriva de uno: el bolero-son es
bolero y son, y la bachata viene de tres. `genero_origen` guarda el grafo
con el tipo de vinculo —deriva, fusiona, influye— y una arista marcada
como principal da el arbol de navegacion, asi que no hay que elegir entre
la verdad y la usabilidad.
Ese tercer tipo ya estaba escrito en el contenido, dentro del campo
equivocado: son-cubano.md pone la herencia de la decima y la copla dentro
de `metrica` porque no habia donde ponerla.
Y lo comparable sale de la prosa a vocabularios: el octosilabo aparece en
tres de las cinco fichas y no se podia preguntar por el. `metro` enlaza
ademas con el glosario, que es donde ese termino ya vive.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
La forma del prompt la define un tercero y cambia sin avisarnos, asi que
modelarla en columnas es perseguir el esquema de otro. Es el caso
contrario al del contenido del sitio, donde el esquema es nuestro.
Abierto no es sin validar: cada `modelo_ia` trae su JSON Schema, se
valida al guardar y el panel puede pintar el formulario a partir de el.
Y lo que se consulta —genero, animo, modelo, valoracion, idioma— se
queda en columnas.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tres tablas: modelo_ia, animo y prompt.
El prompt cuelga del MODELO y no de la IA: uno de Suno v3 no es uno de
v4, y con la clave apuntando a "Suno" a secas queda una biblioteca sin
saber para que servia cada entrada.
El animo se codifica con la GEMS, hecha para emocion musical y no para
emocion en general —nostalgia es una de sus nueve categorias—, mas los
dos ejes de Russell, que ademas son redactables. Se llama `animo` y no
`version` a proposito: `version` ya significa otra cosa en este modelo.
Y un prompt no es un solo texto: Suno separa estilo de letra y admite
exclusiones, y guardar si funciono es lo que distingue una biblioteca de
un monton de texto.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Versiones: una version es una fila de `cancion` con `version_de_id`, no
una tabla aparte. Se descarto partir en obra y grabacion porque en ese
reparto el estilo y las etiquetas colgarian de la obra y una version no
podria tener los suyos. Van los cuatro cabos que hay que atar, empezando
por la vista `cancion_principal`: hay once sitios que listan o cuentan
canciones y a los once se les puede olvidar el filtro.
Generos: el catalogo aspira a ser completo. La ficha se amplia con
instrumentos, letristas, obras de referencia y secciones de prosa. Sin
tabla `letrista` —un letrista es una persona— y sin letras completas de
terceros, que tienen dueno: se cita y se enlaza.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fase 1 de la migracion del contenido a PostgreSQL: las 41 entidades con
sus campos, sus relaciones y el motivo de cada decision. Sin codigo.
De analizarlo salieron dos cosas que no se buscaban:
- Cinco tablas apuntan a una cancion por una cadena de texto y ninguna
tiene clave foranea, porque el destino esta en un archivo. Renombrar un
slug deja huerfana una compra en silencio. Por eso ese arreglo es la
fase 3 y no la ultima.
- `estilo` hace dos trabajos: las secciones del catalogo y los generos
del taller. El pais que hay que clasificar es del genero, y mientras
sean lo mismo esa clasificacion no se puede ni escribir.
Y el ISRC estaba en la cancion cuando identifica una grabacion, asi que
pasa a la version.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>