Refaktoring 100% safe — přehlednost projektu
Stav dokumentu: Hotovo (archiv
docs/tasks/done/) — kroky 1–6 hotové: sdílené parsování měsíce vapp/lib/month-param.ts, sdílené formátování rozsahu měsíců vapp/lib/month-format-cs.ts, čisté helpery katalogové stránky vapp/lib/catalog-page-helpers.ts, parsery katalogových filtrů vapp/lib/catalog-filter-params.ts, rozdělené label slovníky vapp/lib/labels/a cílený import cleanup v aktivně měněných souborech.
Cíl: postupně udělat projekt přehlednější a profesionálnější čistě mechanickými refaktory, které jsou ověřitelné přes TypeScript a build.
Rozsah: React Router/Vite aplikace (app/), sdílené knihovní helpery (app/lib/), částečně Cloudflare worker soubory pouze pokud půjde o přesun bez změny runtime chování. Dokumentace a task přehledy se mohou aktualizovat průběžně.
Mimo scope: změny SQL logiky, migrací, rout/URL, veřejné copy, CSS tříd, vizuálního návrhu, dependency upgrade, přidání nové funkčnosti, změna seed dat, mazání existujícího obsahu.
Bezpečnostní pravidla (návrhová — pro budoucí kroky stejného typu)
Každý další krok ve stylu „100 % safe“ by měl splnit:
- Před změnou je čistý
git status --short, nebo jsou cizí změny jasně oddělené. - Změna je jeden mechanický typ refaktoru: přesun, přejmenování interního helperu, barrel re-export, odstranění lokální duplicity.
- Nemění se texty viditelné návštěvníkům, názvy CSS tříd, pořadí renderovaných bloků, SQL podmínky, URL parametry ani data.
- Po změně projde
npm run typecheckanpm run build. - Diff je zkontrolovaný ručně: očekávané jsou přesuny a importy, ne nové chování.
- Jeden dokončený refaktor = jeden malý commit.
Audit: bezpeční kandidáti
| Oblast | Současný stav | Proč je refaktor bezpečný |
|---|---|---|
| Parsování měsíce | parseMonthParam je duplicitně v app/routes/byliny.tsx, app/routes/sezona.$month.tsx, app/routes/co-sbirat.$month.tsx. | Jde o čistou funkci bez I/O; lze přesunout beze změny implementace. |
| Formátování měsíců na kartě byliny | monthLabel a formatHarvestMonths jsou lokální v app/routes/byliny.$slug.tsx, vedle existujících měsíčních helperů v app/lib/. | Jde o čisté mapování čísla měsíce na text; lze přesunout s totožnými výstupy. |
Helpery katalogu /byliny | app/routes/byliny.tsx kombinuje loader, meta, UI a čisté helpery (catalogDescription, herbListCountPhrase, buildBylinySearch, QUICK_CHIPS). | Přesun helperů a konstant nemění JSX ani loader data. |
| Parsování katalogových filtrů | app/db/herbs.server.ts obsahuje DB dotazy i URL/parser helpery (parseTopicScopeParam, parseScienceCatalogFilter, parseScienceMinTier, parseCatalogPmSlugs). | Parsery jsou čisté; herbs.server.ts může exporty zachovat přes re-export, aby se nemusely měnit call-sites naráz. |
| Label slovníky | app/lib/claim-labels.ts má cca 350 řádků a míchá témata, vědu, bezpečnost, obrázky, recepty a zpracování. | Lze rozdělit po doménách a ponechat claim-labels.ts jako barrel re-export, takže existující importy zůstanou funkční. |
Checklist
1. Sdílené parsování měsíce
Soubory:
-
Vytvořit:
app/lib/month-param.ts -
Upravit:
app/routes/byliny.tsx -
Upravit:
app/routes/sezona.$month.tsx -
Upravit:
app/routes/co-sbirat.$month.tsx -
Přesunout současnou implementaci
parseMonthParambeze změny logiky doapp/lib/month-param.ts. -
Exportovat ji jako
parseMonthParam(raw: string | null | undefined): number | null. -
Nahradit lokální kopie importem ve třech routách.
-
Ověřit ručně zachované chování:
null,undefined,"","0","13","abc"vracínull;"1","01","12"vrací platný měsíc. -
Spustit
npm run typecheck. -
Spustit
npm run build.
2. Sdílené formátování rozsahu měsíců
Soubory:
-
Upravit:
app/lib/month-labels-cs.tsnebo vytvořitapp/lib/month-format-cs.ts -
Upravit:
app/routes/byliny.$slug.tsx -
Přesunout lokální
monthLabelaformatHarvestMonthsz detailu byliny do sdíleného helperu. -
Zachovat přesné výstupy včetně malých písmen a pomlčky: například
1→leden,1–3→leden–březen. -
V detailu byliny ponechat jen import a volání helperu.
-
Spustit
npm run typecheck. -
Spustit
npm run build.
3. Vyčistit route /byliny od čistých helperů
Soubory:
-
Vytvořit:
app/lib/catalog-page-helpers.ts -
Upravit:
app/routes/byliny.tsx -
Přesunout
catalogDescription,herbListCountPhrase,buildBylinySearch,hasTighterScienceMinFilteraQUICK_CHIPSdoapp/lib/catalog-page-helpers.ts. -
Neměnit žádný text v
QUICK_CHIPSani žádné parametry generovaných odkazů. -
V
app/routes/byliny.tsxnahradit lokální definice importem. -
Zkontrolovat diff: v JSX se nemají změnit Tailwind třídy, texty ani pořadí elementů.
-
Spustit
npm run typecheck. -
Spustit
npm run build.
4. Oddělit parsery katalogových filtrů od DB dotazů
Soubory:
-
Vytvořit:
app/lib/catalog-filter-params.ts -
Upravit:
app/db/herbs.server.ts -
Volitelně upravit později:
app/routes/byliny.tsx -
Přesunout typy
TopicScopeFilter,ScienceCatalogFilter,ScienceMinTiera parseryparseTopicScopeParam,parseScienceCatalogFilter,parseSpiritualCatalogFlag,parseScienceMinTier,parseCatalogPmSlugs. -
V
app/db/herbs.server.tszachovat kompatibilní re-exporty, aby stávající importy z rout zůstaly funkční. -
Nepřesouvat SQL builder
herbIdsMatchingCatalogFiltersv tomto kroku. -
Zkontrolovat diff: SQL řetězce a bind pořadí musí zůstat beze změny.
-
Spustit
npm run typecheck. -
Spustit
npm run build.
5. Rozdělit claim-labels.ts přes barrel export
Soubory:
-
Vytvořit:
app/lib/labels/topic-labels.ts -
Vytvořit:
app/lib/labels/science-labels.ts -
Vytvořit:
app/lib/labels/safety-labels.ts -
Vytvořit:
app/lib/labels/media-processing-labels.ts -
Upravit:
app/lib/claim-labels.ts -
Rozdělit konstanty a label funkce podle domén, ale neměnit hodnoty slovníků.
-
Ponechat
app/lib/claim-labels.tsjako barrel soubor sexport * from "./labels/...". -
Neaktualizovat plošně existující importy v celé aplikaci v tom samém kroku; kompatibilita barrel exportu je hlavní bezpečnostní pojistka.
-
Zkontrolovat diff slovníků: žádná česká hodnota ani fallback chování se nesmí změnit.
-
Spustit
npm run typecheck. -
Spustit
npm run build.
6. Volitelný import cleanup po stabilizaci
Soubory:
-
Upravit jen call-sites, které už používají rozdělené helpery.
-
Až budou předchozí kroky v main větvi, přesměrovat nové nebo aktivně měněné soubory na cílenější importy (
app/lib/labels/...,app/lib/catalog-filter-params). -
Nedělat plošný import churn přes celý projekt bez funkčního důvodu.
-
Spustit
npm run typecheck. -
Spustit
npm run build.
Věci záměrně nezařazené jako 100% safe
- Přepis SQL v
app/db/herbs.server.tsneboapp/db/herb-detail.server.ts— vysoká hodnota, ale snadno změní výsledky katalogu. - Extrakce velkých JSX sekcí z
app/routes/byliny.$slug.tsx— mechanicky možná, ale bez screenshot/regresních testů může nechtěně změnit render. - Úpravy veřejné copy a odstranění technických textů — existuje samostatný task odstraneni-technicke-copy-pro-navstevniky.md, ale jde o produktovou změnu, ne čistý refaktor.
- Dependency upgrade, přidání lint/test stacku nebo změny build nástrojů — užitečné později, ale není to bezrizikový refaktor.
- Mazání
console.logve workeru — může změnit observabilitu údržbového endpointu.
Akceptace celého projektu
-
app/routes/byliny.tsx,app/routes/byliny.$slug.tsx,app/db/herbs.server.tsaapp/lib/claim-labels.tsjsou menší nebo mají jasnější odpovědnosti. - Veřejné stránky mají stejné routy, texty, metadata, třídy a datové výsledky jako před refaktorem.
-
npm run typecheckanpm run buildprochází po každém dokončeném kroku. - Každý krok je samostatně revertovatelný.