Přeskočit na obsah

Schválení přes druhou cestu negeneruje slug → profil 404

import { Aside } from ‘@astrojs/starlight/components’;

Admin schválí umělce, klikne na jeho veřejný profil → „Stránka nenalezena” (404). Profil přitom v DB existuje, je approved=true, není smazaný ani blokovaný.

Veřejný profil se routuje na /autor/<url_slug>. Schválený umělec měl url_slug prázdný, takže odkaz vedl na /autor/ (prázdný segment) → žádná shoda routy → 404.

Proč byl slug prázdný: existovaly dvě cesty schvalování, a jen jedna generovala slug.

// Cesta A — dedikovaný approve endpoint (pending-artists POST): slug SE generoval ✓
if (!artist.url_slug) {
updates.url_slug = await generateUniqueArtistSlug(db, artist);
}
// Cesta B — obecný edit uživatele (users PUT): slug se NEgeneroval ✗
if (admin_approved !== undefined) {
updates.admin_approved = admin_approved;
if (admin_approved) {
updates.approved_at = new Date().toISOString();
// ... žádné slug-gen → zůstane prázdné
}
}

Admin schválil umělce přes editační formulář (Cesta B, PUT), ne přes dedikované tlačítko „schválit” (Cesta A). Pravidlo „při schválení vygeneruj slug” žilo jen v jedné z obou cest.

Slug-gen vytáhnout do jednoho sdíleného helperu a zavolat ze všech approve cest:

// lib/slug.ts — jediný zdroj pravdy
export async function generateUniqueArtistSlug(db, p) {
const base = slugify(p.pseudonym || `${p.first_name}-${p.last_name}`)
|| `artist-${p.id.slice(0, 8)}`;
let slug = base, suffix = 1;
while (true) {
const { data } = await db.from('profiles')
.select('id').eq('url_slug', slug).neq('id', p.id).limit(1);
if (!data?.length) break;
slug = `${base}-${++suffix}`;
}
return slug;
}
// Cesta B (users PUT) — doplněno
if (admin_approved) {
const target = await loadProfile(user_id);
if (target?.role === 'artist' && !target.url_slug) {
updates.url_slug = await generateUniqueArtistSlug(db, target);
}
}

Cesta A přepsána na stejný helper. Náprava dat: backfill slugů pro už schválené umělce s prázdným url_slug.

Jak se tomu vyvarovat v jiných systémech

Sekce “Jak se tomu vyvarovat v jiných systémech”
  • Detection: najdi všechny zápisy stavového flagu (approved = true, status = 'active', published = true) a ověř, že každá cesta dělá i navazující odvozené kroky (slug, počítadla, notifikace). Pokud je odvozený krok jen u jedné, máš drift.
  • Anti-pattern: stejné netriviální pravidlo zkopírované do druhé cesty (copy-paste), nebo přítomné jen v „hlavní” cestě a chybějící v „edit/admin override” cestě.
  • Lepší přístup: (1) jeden sdílený helper volaný ze všech cest; (2) ještě lépe DB trigger / generated column, pokud jde o čistě datové odvození (slug z jména) — pak je nezávislé na aplikační cestě; (3) test: schval entitu každou cestou a ověř, že odvozená pole (slug) jsou vyplněná.

Sister bugs / související

Sekce “Sister bugs / související”
Přidal aiarchitekt.cz · 26. 5. 2026 2:00
Provozuje aiarchitekt.cz