Commits
Crepe fora, BlockNote dins: editor nou i biblioteca de mitjans
Sis hores i catorze desplegaments contra el salt de selecció, canvi de llibreria
Ahir vaig tancar la jornada amb el panell redissenyat —el que agafava forma a Del Resum a l'editor: el panell agafa forma— i avui em vaig endur la pitjor tarda de les últimes setmanes i, a la vegada, una de les més productives: canvi d'editor i biblioteca de mitjans sencera. Vaig per parts.
El salt de selecció: sis hores i catorze desplegaments
A l'editor Crepe/Milkdown, seleccionar text feia saltar la pàgina. Semblava una bobada de CSS (el llenguatge que dona aspecte a una web), però no ho era. La llista de pegaments fallits és llarga: scroll-padding, scroll únic al llenç, overflow-anchor, TopBar fora del scroll (va trencar el layout), toolbar portalitzada (pàgina en blanc), position fixed amb variables CSS. Catorze desplegaments i 3 reverts sense tocar la causa real: les toolbars flotants de Crepe amb el scroll anidat no s'entenien amb Safari.
La lliçó se m'ha quedat gravada: si tres pegaments estructurals fallen, el problema és l'eina, no el pegament. I mai més retirar funcionalitats que l'usuari estima com a experiment de diagnòstic: ho vaig fer amb el menú «/» i els punts de bloc i va ser un error.
BlockNote substitueix Crepe
Vaig canviar d'eina: BlockNote amb l'adaptador Mantine oficial. Porta de fàbrica el menú «/», l'ansa de punts per bloc i el menú de selecció amb canvi de paràgraf a H1-H3, tot el que exigíem. Entra i surt Markdown, així que el camp content de l'API no canvia: migració zero de dades. Milkdown desinstalat, 155 paquets fora. Després de tres ajusts de CSS (tema, espaiats, selecció teal), l'editor va passar totes les proves i va entrar en producció.
Biblioteca de mitjans pròpia
Fins ara les imatges anaven com a data-URLs base64, el fitxer sencer incrustat dins del text: omplien la base de dades i les pàgines. Ara hi ha una taula media, fitxers en un volum Docker (un disc virtual del contenidor) i una pàgina /admin/medis amb graella, pujada múltiple, vista prèvia i còpia d'URL. L'editor hi puja amb uploadFile. SVG rebutjat per XSS emmagatzemat (un SVG pot portar codi executable a dins) i màxim 25 MB per fitxer.
WebP i 2.000px automàtics
Tota imatge pujada es converteix a WebP, un format modern molt més lleuger, qualitat 85 i, si supera 2.000x2.000, es redueix mantenint la proporció. EXIF transpose inclòs per a fotos de mòbil (el gir de la càmera es respecta). Un PNG de 4.000x1.000 passa a WEBP de 2.000x500.
Dos 520, dues causes
Un 520 és un error del servidor intermedi que amaga una causa que ell mateix no sap dir. El primer era estructural: a la xarxa edge compartida del servidor, un altre projecte té un servei anomenat web, i el DNS de Docker (la llibreta interna que tradueix noms a adreces) resolia el nom a dos contenidors. NPM repartia les peticions a l'atzar i la meitat anaven a parar a un servidor que no és el meu. Àlies únic web-base-astro i solucionat.
El segon era meu: el nou MediaLibrary llegia localStorage (la memòria pròpia del navegador) dins del useState. Les illes d'Astro (trossos interactius de la pàgina) es renderitzen també al servidor, on localStorage no existeix, i l'illa explotava a meitat de resposta. Valor per defecte en render i lectura dins d'useEffect.
Fases 1 i 2: carpetes i ajustos
Fase 1 de mitjans: carpetes jeràrquiques amb arrossegament, metadades (nom, alt, descripció), selecció múltiple i vista en targetes o llista. Fase 2: secció nova als Ajustos amb dimensió màxima i format (WebP o AVIF) que el servei llegeix a cada pujada.
Amb l'espec escrita abans, les fases van sortir a la primera, excepte typos. L'endemà, la IA hi entrava de ple: La IA entra als Ajustes: proveïdors, SEO i articles automàtics.