Jak jsme převzali velký webový portál v (úplně ne) dobrém stavu

Jak jsme převzali velký webový portál v (úplně ne) dobrém stavu

Přebírání projektu po jiné agentuře nebo týmu je vždycky trochu sázka do loterie. Někdy vyhrajete čistý kód, jindy... jindy otevřete složku app/Http/Controllers a zjistíte, že jste právě vstoupili do vývojářského pekla.

Nedávno jsme dostali do rukou velký portál běžící na Laravelu. Na první pohled fungoval. Na druhý pohled (ten pod kapotu) nám bylo jasné, že nás čeká dlouhá cesta. Tady je výčet toho nejhoršího, co jsme našli, a jak jsme se s tím popasovali.

1. Monstrózní controllery: "Všechno v jednom"

Největší šok přišel u PostController.php. Měl přes 2000 řádků. Tento soubor dělal úplně všechno: validaci dat, složitou byznys logiku, odesílání e-mailů, nahrávání obrázků a dokonce i přímé SQL dotazy přes DB::select.

Ukázka "Fat" Controlleru:

// Takhle prosím NE
public function update(Request $request, $id) {
    // 50 řádků validace přímo v metodě
    if ($request->title == '') { ... } 
    
    // Byznys logika smíchaná s DB
    $post = Post::find($id);
    $post->title = $request->title;
    // ... dalších 100 polí
    
    // Nahrávání souborů bez abstrakce
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('uploads'), $name);
    }
    
    // Odesílání notifikací natvrdo
    Mail::send(...); 
    
    return redirect()->back()->with('success', 'Uloženo!');
}

Náprava: Začali jsme striktně oddělovat logiku. Validaci jsme přesunuli do FormRequest, byznys logiku do Services a pro manipulaci s daty zavedli Actions.

2. Deploy pomocí FTP (Vítejte v roce 2005)

V době Dockeru, CI/CD pipelines a automatizovaného testování nás překvapilo, že se kód nasazoval ručně. Prostě se vzaly soubory a přetáhly se přes FTP klienta na server.

  • Riziko: Stačí jeden výpadek spojení nebo zapomenutý soubor a celý portál spadne.

  • Chaos: Nikdo nevěděl, co je na produkci za verzi kódu, protože se hotfixy dělaly přímo "na živém srdci".

Náprava: Okamžitě jsme zavedli Git (ano, ani ten tam nebyl pořádně používán) a nastavili automatizovaný deploy přes GitHub Actions. Dnes stačí jeden merge do masteru a systém se sám otestuje a nasadí.

3. Ignorování Eloquentu a N+1 problém

Laravel má úžasné ORM (Eloquent), ale autoři se rozhodli, že ho buď nevyužijí, nebo ho využijí špatně. Našli jsme cykly, které v každém kroku sahaly do databáze.

// Klasický N+1 problém u článků
$posts = Post::all(); // 1 dotaz: Vybere všechny články

foreach ($posts as $post) {
    // Pro každý jeden článek se spustí nový dotaz do DB, 
    // aby se zjistilo jméno autora.
    echo $post->author->name; 
}

U portálu s tisíci uživateli to znamenalo tisíce zbytečných dotazů a šílené zpomalení.

Náprava: Použití Eager Loading (User::with('profile')->get()), čímž jsme snížili počet dotazů z 500 na 2.

4. Hardcodované proměnné a chybějící .env

Potřebujete změnit API klíč k platební bráně? Smůla, musíte prohledat 15 souborů a v každém to ručně přepsat. Environmentální proměnné (.env) byly téměř prázdné.

Náprava: Všechny konfigurační hodnoty jsme vyvedli do složky config/ a propojili s .env souborem. Bezpečnost a udržovatelnost vzrostla o 100 %.

5. Detekce chyb: "Uživatelé nám napíšou, až to spadne"

V původním nastavení neexistoval žádný centrální monitoring. Pokud se na webu vyskytla kritická chyba, vývojáři se o ní dozvěděli až ve chvíli, kdy se ozval nespokojený uživatel nebo klient, že mu nefunguje klíčová část portálu. Prohledávání obřích textových logů na serveru přes SSH byla práce pro detektiva na plný úvazek a často připomínala hledání jehly v kupce sena.

Jak to vypadalo v praxi:

V kódu se často objevovaly prázdné try-catch bloky. Ty sice zajistily, že se uživateli nezobrazila chybová hláška, ale problém uvnitř systému prostě "spolkly". Aplikace se tvářila, že je vše v pořádku, zatímco na pozadí tiše selhávaly důležité procesy a logické operace.

Záchranná akce: Nasazení Sentry

Místo hádání a čekání na e-maily od uživatelů jsme vsadili na data. Okamžitě jsme do Laravelu integrovali Sentry. Během prvních deseti minut po nasazení na nás vyskočilo množství unikátních chyb, o kterých nikdo neměl ani tušení, protože byly v kódu umlčené nebo zapadly v nepřehledných souborech na serveru.

Díky centralizovanému trackování teď máme okamžitý přehled o:

  • Identifikaci místa: Víme přesně, na kterém řádku a v jakém souboru k chybě došlo.

  • Souvislostech: Vidíme, při jaké akci uživatele se problém objevil a jaké parametry jej vyvolaly.

  • Prioritách: Systém nám chyby seskupuje, takže hned vidíme, co ovlivňuje nejvíce lidí a co vyžaduje okamžitou pozornost.

Výsledek: Už nečekáme na stížnosti. O chybě víme v reálném čase, často dříve, než si jí uživatel vůbec stihne všimnout. Z reaktivního hašení požárů jsme přešli na proaktivní správu stability celého portálu.

Závěr

Převzít takový projekt je výzva, která prověří vaši trpělivost. Naším cílem nebylo všechno smazat a začít znovu (i když by to bylo snazší), ale postupně refaktorovat kód za pochodu, aby klient nepocítil výpadek a portál začal konečně dýchat.

Dnes už máme controllery pod 100 řádků, automatický deploy a databáze si konečně oddechla.

Co se stane po odeslání?

Jsme tu pro Vás

Vaši zprávu si přečtu přímo já nebo kolega z týmu. Do 24 hodin se vám ozveme zpět, abychom probrali detaily. Žádní obchodní zástupci, ale rovnou technická konzultace k věci, která vás posune dál.

Osobní přístup

Jednáte přímo s vývojáři, ne s account managery.

< 24 h reakční doba

Ozveme se rychle s jasnými dalšími kroky.

Co se stane po odeslání?