Refaktor v2 — další safe cleanup a kandidáti

Stav dokumentu: Archiv — sekce 1 (mechanický cleanup), sekce 3 (infrastruktura včetně 3.2 ruční matice helperů) a bezpečná část 2.3 (catalog preview) byly dokončeny v době přesunu do done/. Středně rizikový backlog §2 (UI extrakce z /byliny, rizikové SQL) je přenesen do aktivního refaktor-v3.md (sekce „Převzatý backlog z archivu refaktor v2“). Navazuje na refaktoring-100-safe.md.

Cíl: pokračovat ve zmenšování velkých souborů, čištění importů a sjednocování helperů bez změny veřejného chování.

Zásada: každý bod implementovat samostatně, s malým diffem, npm run typecheck, npm run build a ruční kontrolou diffu. U UI extrakcí přidat alespoň screenshot kontrolu hlavních stránek.


0. Aktuální poznámka k workspace

Refaktor v2 neslučovat do jednoho commitu s nesouvisejícími produktovými změnami (např. probíhající úpravy /sezona, regionu nebo exportů), aby byl diff čitelný a snadno revertovatelný.


1. Mechanický cleanup s nízkým rizikem

1.1 Cílené importy místo barrel claim-labels

Po rozdělení app/lib/claim-labels.ts zůstaly některé call-sites na původním barrel importu. Není nutné to dělat plošně, ale při dotyku souboru přesměrovat import na konkrétní doménový modul.

Kandidáti:

  • app/components/herb-detail-legends.tsxapp/lib/labels/science-labels, app/lib/labels/safety-labels
  • app/components/topic-link-badge.tsxapp/lib/labels/topic-labels
  • app/routes/symptomy._index.tsx a app/routes/symptomy.$slug.tsxapp/lib/labels/topic-labels
  • app/routes/recepty.tsxapp/lib/labels/media-processing-labels
  • app/routes/sezona.$month.tsxapp/lib/labels/safety-labels
  • app/routes/byliny.$slug.tsx → více konkrétních app/lib/labels/*

Stav v repozitáři: Všechny importy v app/ míří na konkrétní moduly app/lib/labels/*. Soubor app/lib/claim-labels.ts zůstává barrel re-exportem (např. pro konzistenci s dokumentací nebo externími odkazy); nové call-site by měly importovat z doménových souborů.

Akceptace:

  • Žádná změna JSX, textů ani fallbacků label funkcí.
  • npm run typecheck
  • npm run build

1.2 Sjednotit param parsery

Projekt už má app/lib/month-param.ts, app/lib/region-param.ts a app/lib/catalog-filter-params.ts. Další cleanup je držet nové URL/query parsery mimo route soubory a mimo DB moduly.

Kandidáti:

  • Zkontrolovat, jestli route soubory neobsahují nové lokální parsery pro slug/query hodnoty.
  • Pokud ano, přesunout je do app/lib/*-param.ts nebo do existujícího doménového parser souboru.

Hotovo:

  • Přidán parseOptionalCatalogSlugParam do app/lib/catalog-filter-params.ts.
  • app/routes/byliny.tsx už pro volitelné katalogové slug filtry nepoužívá inline trim() || null.
  • Záměrně nepřidána nová regex validace, aby se neměnilo chování URL filtrů.

Pozor: nepřesouvat validaci, která je přímo součástí SQL dotazu nebo mění bind pořadí.

Akceptace:

  • npm run typecheck
  • npm run build

1.3 Docs cleanup bez změny produktu

Dokumentace roste rychleji než kód. Bezpečný cleanup je hlavně rozcestník, odkazy a stavové řádky.

Kandidáti:

  • Po dokončení rozpracované sezónní práce doplnit refaktor-v2.md do docs/tasks/README.md (včetně pozdějšího přesunu archivu do docs/tasks/done/).
  • Zkontrolovat odkazy mezi sezónními dokumenty (sezonnost-a-kalendar, sezona-kalendarovy-pohled, sezona-pripominky-a-export, ics-export-sber).
  • Sjednotit stavové řádky: Hotovo, Částečně, Nezapracováno, Návrh.
  • Nepřejmenovávat soubory bez kontroly veřejných /dokumentace/:slug URL.

Hotovo:

  • refaktor-v2.md byl v docs/tasks/README.md; po archivaci viz done/README.md a aktivní backlog v refaktor-v3.md.
  • Sezónní dokumenty mají sjednocený prefix Stav dokumentu a hodnoty z krátkého seznamu stavů.
  • Nebyly přejmenované žádné dokumentační soubory.

Akceptace:

  • Sezónní odkazy vedou na existující .md soubory.
  • npm run typecheck
  • npm run build

2. Refaktor se středním rizikem

Otevřený backlog (§2.1–2.2, riziková část §2.3) je v aktivním dokumentu refaktor-v3.md — sekce „Převzatý backlog z archivu refaktor v2“.

2.3 (archiv) — dokončený bezpečný přesun preview

Soubor herbs.server.ts dál drží katalogový query builder; přepis SQL zůstává rizikový a je popsán ve v3.

Bezpečnější kandidáti:

  • Přesunout preview loader helpery (loadHarvestRangeByHerbId, loadProcessingPreviewByHerbId, attachCatalogPreview) do app/db/herb-catalog-preview.server.ts.
  • Zachovat export listPublishedHerbs ve stejném modulu, pouze importovat preview helper.
  • Neměnit SQL texty ani bind pořadí.

Hotovo:

  • Přidán app/db/herb-catalog-preview.server.ts.
  • app/db/herbs.server.ts dál exportuje listPublishedHerbs a jen importuje attachCatalogPreview.
  • Detailová konverze rowToHerb zůstala lokálně v herbs.server.ts, protože ji používá i getPublishedHerbBySlug.

Akceptace:

  • npm run typecheck
  • npm run build

Rizikové SQL kandidáty (herbIdsMatchingCatalogFilters, skládání fragmentů, logika science / studyType / month + part) — viz refaktor-v3.md.


3. Cleanup infrastruktury a kvality

3.1 Přidat jednotný ověřovací skript

Dnes se opakuje npm run typecheck a npm run build. Malý cleanup by byl přidat skript:

"verify": "npm run typecheck && npm run build"

Riziko: nízké, ale mění package.json a package-lock ne. Ověřit, že skript neběží v CI jinak než čekáme.

Hotovo:

  • Přidán script verify do package.json.
  • package-lock.json se nezměnil.

Akceptace:

  • npm run verify

3.2 Opatrný test harness pro čisté helpery

Projekt nemá samostatný test runner. Přidávat Vitest už je tooling změna, ne čistý refaktor. Mezikrok je dokumentovaná ruční matice níže; samostatný task může později přidat Vitest nebo malý node skript.

Hotovo:

  • Seznam helperů a minimální očekávané chování při úpravách (tabulka níže).
  • Po každé změně některého z uvedených modulů spustit npm run verify (nebo alespoň npm run typecheck).

Ruční matice (smoke — ověřit po úpravě kódu):

FunkceSouborKontrola
parseMonthParamapp/lib/month-param.tsnull pro undefined, '', '0', '13', 'x'; platné '1''12' vracejí číslo (např. '6'6).
formatHarvestMonthsapp/lib/month-format-cs.tsStejný měsíc → jeden název (např. květen–květen); různé měsíce → řetězec s pomlčkou mezi českými názvy.
parseScienceMinTierapp/lib/catalog-filter-params.tsNeznámá nebo prázdná hodnota → preliminary; moderate, strong, review (case-insensitive trim) se zachovají.
parseCatalogPmSlugsapp/lib/catalog-filter-params.tsNeplatné slugy ('', mezery, nepovolené znaky) se vyhodí; duplicity se sloučí; výstup je seřazený.
orderHerbImagesForDisplayMonthapp/lib/herb-images-season.ts0–1 obrázek → pořadí beze změny, orderAdjusted === false; u více obrázků v měsíci se sběrem zkontrolovat, že typy harvest / habitus / detail a shoda popisu s částí rostliny ovlivňují pořadí stabilně (tie-break původní index).

Kandidáti pro budoucí automatické testy (stejný seznam — až zvolíme runner): parseMonthParam, formatHarvestMonths, parseCatalogPmSlugs, parseScienceMinTier, orderHerbImagesForDisplayMonth.

Akceptace:

  • Matice je udržovaná v tomto dokumentu; žádná nová závislost v package.json kvůli refaktoru v2.

3.3 Zkontrolovat generované soubory a ignore pravidla

.gitignore už kryje build, .react-router, *.tsbuildinfo, worker-configuration.d.ts. Cleanup je ověřit, že nic z toho není trackované.

Příkaz:

git ls-files | grep -E '(tsbuildinfo|worker-configuration\.d\.ts|^build/|^\.react-router/|^\.wrangler/)'

(Na stroji s ripgrep lze ekvivalentně rg '…' se stejným výrazem.)

Akceptace:

  • Výstup je prázdný.

4. Co zatím nedělat jako refaktor

  • Nemazat console.log ve workers/app.ts bez rozhodnutí o observabilitě maintenance endpointu.
  • Nepřejmenovávat routy ani dokumentační soubory s veřejným slugem.
  • Nezavádět nový test/lint stack v jednom commitu s refaktorem kódu.
  • Nerozdělovat velké JSX soubory bez screenshot kontroly.
  • Nepřepisovat SQL filtry bez datového regresního testu nebo jasné ruční matice URL → výsledky.

Doporučené pořadí

  1. Cílené importy z claim-labels v souborech, kterých se stejně dotýkáme. (v app/ vyřízeno — viz §1.1)
  2. Docs cleanup po dokončení rozpracované sezónní práce. (viz §1.3)
  3. Preview helpery z herbs.server.ts do samostatného DB modulu. (viz §2.3 bezpečná část)
  4. Jedna malá UI extrakce z byliny.$slug.tsx se screenshot ověřením — refaktor-v3.md (§2.1).
  5. Postupně druhá route (byliny.tsx) nebo větší dělení — pořád s malým diffem; test runner (Vitest) jen jako samostatný úkol mimo refaktor commit — refaktor-v3.md (§2.2 a dál).