Přeskočit obsah

Scénáře

Pět situací, které znáš z praxe. U každé: jak to bolí dneska, proč to bolí, jak by to bylo potom — a co to stálo.

Tohle je ta část dokumentace, po které by mělo být jasné, jestli to celé má smysl.


1. „Ten produkt potřebujeme ještě ve dvou kategoriích"

Jak to znáš

Klient zavolá v pátek odpoledne. Trek Marlin 7 má být kromě „Horských kol" taky v „Akce" a v „Dárkové tipy". Do pondělí.

Ty se podíváš do databáze a vidíš category_id. Jedno číslo. Jeden sloupec.

Odteď existují dvě cesty a obě jsou špatně:

Vytvořím kopii produktu ve druhé kategorii. Funguje to okamžitě.

Za tři měsíce má klient jiné skladové zásoby na každé kopii, jinou cenu a Google indexoval obojí jako duplicitní obsah. Nikdo neví, která kopie je ta pravá, protože obě vypadají stejně.

Přidám vazební tabulku product_category. Což znamená přepsat výpisy, filtr, drobečkovou navigaci, sitemapu a export do feedu — protože všechny počítaly s tím, že kategorie je jedna.

Klient nechápe, proč „přidat produkt do kategorie" trvá tři dny.

Proč to bolí

Protože struktura webu byla od začátku strom. Stromem myslím: každá věc má právě jedno místo, kde žije. Je to nejpřirozenější model na světě — až do chvíle, kdy realita řekne „tahle věc je na třech místech zároveň".

A realita to řekne vždycky. Vždycky. U každého projektu, který je složitější než firemní web se čtyřmi stránkami.

Zajímavé je, že s tím stromem pak bojuješ. Uděláš si vedle něj druhou, paralelní strukturu — tagy, „doporučené produkty", ruční seznam v adminu — a od té chvíle máš dvě struktury, které si můžou protiřečit.

Jak by to bylo

Obsah není strom, ale graf s pojmenovanými typy vazeb. Rozdíl je v tom slově „pojmenovanými" — není to volný chaos, kde všechno souvisí se vším. Vazby mají druhy a každý druh má jiná pravidla:

druh vazby co znamená kolik jich může být
owns vlastní, patří to pod to právě jeden vlastník
references odkazuje se na to kolik chceš
classifies zařazuje do kategorie kolik chceš
navigates je to v menu kolik chceš
routes-to vede sem tahle URL podle pravidel

Produkt ve třech kategoriích je tři hrany classifies. Není to hack, není to výjimka a nemusí se kvůli tomu nic přepisovat. Bylo to počítáno od začátku.

A protože každá hrana má svůj druh, systém pořád ví, co smí co. Smazání komponenty smaže to, co komponenta vlastní. Nesmaže produkt, který jenom zobrazuje.

Z debaty (S2)

Když se celý obsah natlačí do stromu stránky, vzniknou kopie produktů, paralelní taxonomie, synchronizační logika a nejasné publikování.

Ale ani obecný graf nestačí — bez vlastnických hran není jasné, co maže odstranění komponenty a kdo určuje pořadí. Proto typovaný graf, v němž některé podgrafy mají vynucenou stromovou strukturu.

Co to stálo

Musíš dopředu vědět, jaké druhy vazeb ve tvém projektu existují. Ne konkrétní vazby — ty přibývají za běhu — ale druhy.

To je práce navíc na začátku a nedá se odbýt, protože špatně navržený druh vazby se pak předělává hůř než chybějící sloupec.


2. „Od půlnoci je web pomalý"

Jak to znáš

ERP pošle v noci import. 12 000 produktů, změnily se ceny a skladovost. Import proběhne v pořádku.

Ráno je web na kolenou. Protože import na konci udělal to jediné, co je bezpečné: cache:clear.

Takže od šesti ráno, kdy chodí první návštěvníci, se každá stránka počítá znovu. Databáze má load 40. Trvá to čtyřicet minut a pak je zas dobře. Do zítřejší noci.

Proč to bolí

Tohle už víš z předchozí stránky: systém neví, co se změnou souvisí, tak radši zahodí všechno.

Ale je tu druhá vrstva problému, která je zákeřnější. Zkusíš to zlepšit — napíšeš si mazání „jen toho, co souvisí". A buď to zapomeneš někde aktualizovat, nebo se spleteš. Výsledkem je stará cena na jedné stránce v hloubi webu, kterou objevíš za dva měsíce, protože si stěžoval zákazník.

Což je horší než pomalé ráno. Pomalé ráno je vidět. Stará cena není.

Jak by to bylo

Systém si při každém sestavení stránky zapíše, z čeho ji poskládal. Ne jako komentář pro člověka, ale jako seznam, se kterým se dá počítat:

tahle stránka závisí na:
  entity:produkt:8842        (samotný produkt)
  field:produkt:8842:cena    (a hlavně jeho cena)
  relation:kategorie:7       (a na tom, kdo je v kategorii 7)
  query-index:produkt:cs     (a na seznamu publikovaných produktů)

Když se změní cena, zvýší se čítač u field:produkt:8842:cena. Všechno, co si tenhle údaj poznamenalo, je tím pádem neplatné. Všechno ostatní se nedotkne.

A hlavně: nikdo to nemusel udržovat ručně. Ten seznam vznikl sám tím, že se stránka sestavovala. Nedá se na něj zapomenout, protože ho nikdo nepíše.

Jedna past, která tam pořád je

Kdyby se změnilo jenom „produkt 8842", ale ten produkt zároveň vypadl z kategorie 7 — samotný token produktu nestačí. Musí se zvednout i token té kategorie, jinak výpis pořád ukazuje starou sadu.

Zní to jako drobnost, ale je to přesně ten typ chyby, kvůli kterému lidi rezignují a mažou celou cache. V debatě to má jméno (membership tokeny) a řešení.

Co to stálo

Komponenty nesmí sahat do databáze, jak chtějí. Musí se ptát způsobem, kterému systém rozumí — omezeným dotazem, ne libovolným SQL.

To je největší omezení celé platformy a nedá se obejít. Když se obejde jednou, přestanou platit záruky všude.


3. „Přejmenovali jsme stránku a spadlo SEO"

Jak to znáš

Redaktor přesune „Servis kol" z hlavního menu pod „Služby". Rozumný krok, dává to smysl.

URL se změní z /servis-kol na /sluzby/servis-kol, protože cesta se odvozuje z pozice v menu. Stará URL vrací 404. Google to zjistí za týden. Odkazy z fór, které se sbíraly pět let, vedou do prázdna.

Ty pak ručně doplníš redirect. A za měsíc redaktor přesune něco jiného.

Proč to bolí

Protože URL byla odvozená z něčeho, co se legitimně mění.

Menu je věc, kterou má redaktor právo přeskládat kdykoli. To je jeho práce. Ale adresa stránky je závazek vůči vnějšímu světu — vůči Googlu, vůči lidem, co si to uložili do záložek, vůči tomu, kdo na tebe odkázal.

Jedno se mění často a nezávazně. Druhé se nemá měnit skoro nikdy. A přesto to bylo spojené do jednoho.

Jak by to bylo

URL je samostatná vrstva. Ne odvozenina.

Route je vlastní záznam: pro jazyk cs vede cesta /servis-kol na stránku X. Systém ti při zakládání stránky navrhne cestu podle menu — proč taky ne, většinou je správná — ale jakmile ji jednou potvrdíš, je to samostatný záznam, který si žije vlastním životem.

Přesun v menu potom URL nezmění. Vůbec. Menu se přeskládalo, adresa zůstala.

A když chceš adresu opravdu změnit, je to samostatná operace se čtyřmi kroky, kterou systém provede celou nebo vůbec:

  1. vznikne nová route
  2. stará se změní na redirect
  3. zkontrolují se kolize a redirect smyčky
  4. publikuje se to naráz

Mimochodem, vícejazyčné weby

Česká a anglická cesta se můžou lišit strukturou, ne jen posledním slovem. /o-nas/tym vs. /company/about/team. Když je URL odvozená ze stromu, tohle nejde bez boje.

Co to stálo

Jeden záznam navíc a jedna obrazovka v adminu, kde se URL spravují. Upřímně: ze všech cen v týhle dokumentaci ta nejlevnější.


4. „Spustili jsme redesign a půlka webu se rozsypala"

Jak to znáš

Designér změní odstín modré a velikost mezery v gridu. Malá změna, deset minut práce.

Nasadí se to a rozsype se osm stránek, o kterých nikdo nevěděl, že tu barvu používají jinak. Landing page z loňské kampaně, kterou už dva roky nikdo neotevřel, vypadá zničehonic rozbitě.

Nikdo za to nemůže. Ta změna byla správná. Jen se projevila i tam, kam nikdo nekoukal.

Proč to bolí

Protože publikovaná stránka není hotová věc. Je to recept, který se vaří znovu při každém zobrazení — z aktuálních komponent, aktuálního CSS a aktuálních barev.

Když se změní jakákoli ingredience, změní se i jídlo, které jsi uvařil před rokem a byl s ním spokojený.

Jak by to bylo

Publikace vytvoří release — a ten si připne úplně všechno, z čeho byl web složený. Nejen texty a obrázky, ale i:

  • verzi komponent a rendereru
  • verzi design systému a barev
  • konkrétní revize entit v každém jazyce
  • routovací a redirect tabulku
  • indexy, ze kterých se počítaly výpisy

Když designér změní modrou, nestane se nic. Změnil design systém, ne web. Vznikne nová verze design systému a někdo ji musí vzít a vydat nový release. Tam se to zkontroluje.

Změna barvy tak přestane být redakční úpravou a stane se z ní změna platformy — s vlastním schválením a vlastními vizuálními testy.

Z debaty (S1)

Publikovaná stránka nesmí automaticky převzít novější tokeny jen proto, že se změnil globální theme record. Jinak manifest není neměnný ve skutečném smyslu.

A jako bonus: preview a návrat zpátky

Když existuje release, dostaneš dvě věci skoro zadarmo:

Preview celého webu. Ne náhled jedné stránky — celý web ve stavu, v jakém bude po spuštění. Klient si to proklikne včetně menu a výpisů.

Návrat. Když se něco pokazí, přepneš na předchozí release. Není to obnova ze zálohy, není to přetáčení databáze. Je to přepnutí ukazatele.

Ale pozor na jednu věc

Návrat zpátky není návrat v čase. Je to nová změna, která vrací obsah do dřívější podoby.

Rozdíl je zásadní: kdyby se mezitím změnilo schéma nebo proběhla migrace, která něco zahodila, tak návrat prostě nejde — ta informace už neexistuje. Žádný systém verzí to nezachrání.

Co to stálo

Ukládá se víc dat, protože se drží víc verzí. A někdo musí rozhodnout, jak dlouho se staré releasy uchovávají — což je otázka, na kterou zatím není odpověď.


5. „Za měsíc spouštíme němčinu"

Jak to znáš

Přidá se sloupec. Nebo tabulka page_translations. Nebo se udělá druhá instance webu, protože to je jednodušší.

A pak přijdou otázky, na které nikdo nemá dobrou odpověď:

  • Co když je stránka přeložená jen napůl?
  • Cena je pro všechny jazyky stejná, ale popis ne. Kde to je zapsané?
  • Když němčina není hotová, má se ukázat čeština, nebo 404?
  • Když se ukáže čeština, jaká URL se zobrazí v adresním řádku?

Většinou se to vyřeší tak, že se překlopí, co jde, a zbytek se doplňuje za pochodu. Zákazník na německé verzi občas uvidí český odstavec.

Proč to bolí

Protože jazyk se přidával potom. Do systému, který o něm nevěděl.

A jazyk není vlastnost textu, jazyk je rozměr celého obsahu. Prostupuje vším — dotazy, řazením, URL, publikováním, i tím, jak vypadá layout. Když se přidá dodatečně, musí se vměstnat do děr, které zbyly.

Jak by to bylo

U každého pole se v návrhu řekne, jestli je translated nebo shared. Cena je shared — je jedna pro všechny jazyky. Popis je translated. Tohle není nastavení v adminu, je to součást datového modelu.

Jazyky se publikují nezávisle. Čeština má svůj release, němčina svůj. Když němčina není hotová, česká verze se tím nezdrží.

A fallback — co se ukáže, když překlad chybí — je pravidlo, ne náhoda. Je zapsané, verzované a je součástí releasu.

Tohle je ta věc, kterou ještě nikdo nevyřešil

Když má čeština svůj release a němčina svůj, a německá stránka si přes fallback půjčí český odstavec — který release to vlastně je?

Vydáš češtinu. Německá stránka se tím změní, i když němčinu nikdo nepublikoval. Hranice releasu, která má být uzavřená, je najednou děravá.

V debatě to je účet P, přišel na to Claude v kole 5 — a v kole 7 ho Codex našel nezávisle sám mezi typickými selháními. To z toho dělá doložený problém, ne domněnku.

A má sourozence: německý text bývá o 30 % delší. Komponenta otestovaná v češtině může v němčině přetéct. Fallback tedy může zobrazit text v jazyce, pro který ta varianta nikdy nebyla ověřená (účet T).

Co to stálo

U každého pole musí někdo rozhodnout translated vs. shared — a rozhodnout to dřív, než se do systému nalije obsah. Změnit to zpětně jde, ale je to migrace, ne přepínač.


Co mají ty scénáře společného

Když si je přečteš za sebou, je v nich pořád stejný tvar:

Něco, co se legitimně mění, bylo připnuté k něčemu, co se měnit nemá.

  • kategorie k produktu jedním sloupcem
  • platnost cache k „nevím, radši všechno"
  • URL k pozici v menu
  • vzhled loňské stránky k dnešnímu design systému
  • jazyk k tabulce, která o něm nevěděla

A celá platforma dělá v jádru jedinou věc: rozplétá to. Dává každé z těch věcí vlastní život a vlastní pravidla, a pak mezi nimi vede pojmenovaný vztah místo tichého předpokladu.

To je všechno. Zbytek jsou detaily provedení.


Dál: slovník pojmů, pokud ti některá slova nesedla, nebo architektura, pokud chceš vidět, jak se to rozhodlo.