La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
/**
|
|
|
|
|
* Da o quita el rol de administrador.
|
|
|
|
|
*
|
|
|
|
|
* npm run db:admin # quién administra ahora
|
|
|
|
|
* npm run db:admin -- hola@senzapaura.es # se lo da
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
* npm run db:admin -- hola@… --crear # y crea la cuenta si no existe
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
* npm run db:admin -- hola@… --quitar # se lo quita
|
|
|
|
|
*
|
|
|
|
|
* Es un script y no una pantalla del panel a propósito: el primer administrador
|
|
|
|
|
* no puede nombrarse desde un panel al que todavía no puede entrar nadie. Y
|
|
|
|
|
* mientras administre una sola persona, una pantalla para gestionar permisos
|
|
|
|
|
* sería mantener un sistema de permisos para un usuario.
|
|
|
|
|
*
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
* Por defecto **no crea la cuenta**: se le da el rol a alguien que ya ha entrado
|
|
|
|
|
* alguna vez, y así el permiso no puede quedarse esperando en una dirección mal
|
|
|
|
|
* escrita. `--crear` es para el arranque en frío —una base recién puesta donde
|
|
|
|
|
* todavía no ha entrado nadie—, y por eso hay que pedirlo: escribir mal el
|
|
|
|
|
* correo con `--crear` da de alta una cuenta administradora que no es de nadie.
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import pg from 'pg';
|
|
|
|
|
|
|
|
|
|
const argumentos = process.argv.slice(2);
|
|
|
|
|
const quitar = argumentos.includes('--quitar');
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
const crear = argumentos.includes('--crear');
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
const email = argumentos
|
|
|
|
|
.find((a) => !a.startsWith('--'))
|
|
|
|
|
?.trim()
|
|
|
|
|
.toLowerCase();
|
|
|
|
|
|
|
|
|
|
const c = new pg.Client({ connectionString: process.env.DATABASE_URL, query_timeout: 15_000 });
|
|
|
|
|
await c.connect();
|
|
|
|
|
|
|
|
|
|
if (!email) {
|
|
|
|
|
const { rows } = await c.query(
|
|
|
|
|
`select email, ultimo_acceso_en from usuario where rol = 'admin' order by email`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (rows.length === 0) {
|
|
|
|
|
console.log('No administra nadie.');
|
|
|
|
|
console.log('Para dárselo a alguien: npm run db:admin -- correo@ejemplo.es');
|
|
|
|
|
} else {
|
|
|
|
|
console.log(`Administran ${rows.length}:`);
|
|
|
|
|
for (const f of rows) {
|
|
|
|
|
const visto = f.ultimo_acceso_en
|
|
|
|
|
? f.ultimo_acceso_en.toISOString().slice(0, 10)
|
|
|
|
|
: 'no ha entrado';
|
|
|
|
|
console.log(` ${f.email.padEnd(34)} último acceso ${visto}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await c.end();
|
|
|
|
|
process.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { rows } = await c.query(
|
|
|
|
|
`update usuario set rol = $2 where email = $1 returning email, rol`,
|
|
|
|
|
[email, quitar ? 'persona' : 'admin']
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (rows.length === 0) {
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
if (quitar) {
|
|
|
|
|
console.log(`No hay ninguna cuenta con «${email}», así que no administra.`);
|
|
|
|
|
await c.end();
|
|
|
|
|
process.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!crear) {
|
|
|
|
|
console.log(`No hay ninguna cuenta con «${email}».`);
|
|
|
|
|
console.log('Tiene que haber entrado al menos una vez para poder darle el rol,');
|
|
|
|
|
console.log('o pásale --crear si es el primer administrador de esta base.');
|
|
|
|
|
await c.end();
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { rows: creada } = await c.query(
|
|
|
|
|
`insert into usuario (id, email, rol) values (gen_random_uuid(), $1, 'admin')
|
|
|
|
|
returning email`,
|
|
|
|
|
[email]
|
|
|
|
|
);
|
|
|
|
|
console.log(`${creada[0].email} creado y administrando.`);
|
|
|
|
|
console.log('Entra por el panel: te mandará un código de un solo uso a ese correo.');
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
await c.end();
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
process.exit(0);
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(
|
El panel ya edita, y enseña todo el contenido y no siete filas
Un panel donde no se puede editar nada no es un panel.
**Se editan los capítulos** —los principios del taller y las fichas de género,
que son la misma tabla con un `tipo` distinto—: título, resumen, texto en
Markdown, estado y orden. Se guarda con el botón o con Ctrl+S, y sale publicado
al momento: el caché del Markdown tiene por clave el propio texto, así que un
cambio se invalida solo.
El botón de guardar va arriba y no al pie. Al pie tenía que ser flotante para
seguir a la vista mientras se escribe, y flotando se pintaba encima de la línea
que estabas escribiendo; se vio en la captura.
**La portada enseñaba siete cosas de las cuarenta largas que hay.** Ahora sale
todo el contenido agrupado —taller y géneros, glosario, catálogo, editorial—,
con su desglose y lo que falta en cada uno. Lo que no aparece en un panel no
existe: nadie se iba a acordar de que los metros y los compases siguen vacíos.
Fuera queda la explotación —pedidos, facturas, carritos—, que no se escribe.
Y los letristas ya se ven. Están en `persona` porque el papel no es de la
persona sino de su relación con cada género —`genero_persona.papel`, con clave
primaria (género, persona, papel)—, y la misma persona es letrista de uno y
compositora de otro. La página pública de letristas es una vista sobre eso. Lo
que estaba mal es que el panel no lo dijera: ahora la fila de Personas desglosa
15 letristas · 2 compositores · 1 intérprete · 4 fundadores.
Un menú, que tampoco había. Solo con lo que ya tiene pantalla: un menú con la
mitad de las entradas muertas es peor que uno corto.
`npm run db:admin -- correo --crear` para el arranque en frío. Sin eso no había
forma de nombrar al primer administrador: el script exigía que la cuenta ya
existiera, y en una base recién puesta no existe ninguna.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
quitar ? `${rows[0].email} ya no administra.` : `${rows[0].email} ya administra el sitio.`
|
La puerta del panel, y una portada que dice qué falta
Fase 6. Está lo que todo lo demás necesita: quién entra y por dónde.
El rol vive en `usuario.rol`, con un CHECK que impide inventarse uno, y se da
con `npm run db:admin`. En una variable de entorno con correos habría sido más
rápido, pero entonces revocar a alguien pide un despliegue y a la pregunta
«quién administra esto» solo sabe contestar quien pueda leer la configuración
del servidor.
La guarda está en el `+layout.server.ts` de la carpeta y no en cada ruta: una
pantalla nueva queda protegida por el hecho de estar dentro. Sin sesión, a
entrar con la vuelta puesta; con sesión y sin el rol, 404 y no 403, porque un
403 confirma que el panel existe y dónde vive. Los tres casos, comprobados
contra la aplicación de verdad.
La portada contesta «qué falta» y no «cuánto hay». Cada sección trae lo que
tiene, lo que está a medias y los nombres de lo que está a medias: decir «1
género sin ficha» obliga a ir a buscar cuál, y esa búsqueda ya la ha hecho la
consulta. Dos viajes a la base para las siete filas.
Fuera Sveltia CMS y `static/admin/`. Editaba los Markdown de `src/content/`,
que desde la fase 4 no lee nadie: guardaba cambios que no salían en pantalla, y
además tapaba la ruta nueva.
Y de paso, la prueba de contacto que fallaba en la tanda completa y pasaba a
solas. No era aislamiento: `page.goto` vuelve al cargar, no al hidratar, y al
hidratar Svelte reescribe el valor de cada `input` con el del componente. Lo
tecleado antes de ese instante se perdía, y solo le pasaba al primer campo y
solo con la máquina cargada.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 weeks ago
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Las sesiones abiertas siguen valiendo, y es lo correcto: el rol se lee de la
|
|
|
|
|
* base en cada petición —la sesión solo guarda a quién pertenece—, así que dar
|
|
|
|
|
* o quitar el permiso surte efecto en la siguiente página que se pida, sin
|
|
|
|
|
* tener que echar a nadie fuera.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
await c.end();
|