Refaktor v3 — další vrstva kvality (mimo jádro v2)
Stav dokumentu: Částečně — kódové sliby v3 z roku 2026 jsou v hlavní větvi splněny (
npm run verify= typecheck + ESLint + Vitest + build; CI voláverify). Otevřené zůstávají jen body závislé na regresní matici / produktové akceptaci (P2.3 SQL, volitelnýPageDecor, případné další dělení DB). Archiv v2: refaktor-v2.md.
Cíl: shrnout další směry — větší soubory mimo kartu byliny, DB vrstvu kolem detailu, opakující se UI vzory, tooling (lint/test/CI), přístupnost, výkon a provoz workeru — tak, aby šly brát po jednom malém diffu s npm run verify.
Zásada: stejně jako u archivu refaktoring-100-safe.md a v2 — žádné „big bang“ commity; u vizuálu a SQL vždy explicitní akceptace a kontrola regrese.
0. Vztah k předchozím refaktorům
- v1 (100% safe): sdílené helpery, labely, parsery — hotové v archivu refaktoring-100-safe.md; neměnit zpětně bez důvodu.
- v2 (archiv): mechanický cleanup §1, infrastruktura §3, bezpečná část §2.3 (preview) — refaktor-v2.md. Otevřený backlog z původního §2 je v sekci „Převzatý backlog…“ níže.
- v3: rozšířit stejný přístup na ostatní velké soubory a na procesní zlepšení (lint, testy, CI, observabilita).
Převzatý backlog z archivu refaktor v2 (§2 — /byliny a herbs.server.ts)
Zdroj archivu: refaktor-v2.md. Hotový bezpečný přesun preview helperů (herb-catalog-preview.server.ts) zůstává popsán v archivu v §2.3; zde jen otevřené kroky.
P2.1 Rozdělit app/routes/byliny.$slug.tsx po sekcích
Hotovo: sekce v app/components/herb-detail/ (hero, harvest, storage, processing, spiritual, science, images, safety, …); složení stránky v herb-detail-page.tsx (HerbDetailPage); route skládá meta, loader a předá data do HerbDetailPage.
Bezpečnostní pravidla (splněno v implementaci):
- Postupně extrahované sekce; props podle loader dat.
- Neměněny texty ani pořadí sekcí v rámci refaktoru.
P2.2 Rozdělit app/routes/byliny.tsx na filtr panel a výsledky
Hotovo: app/components/catalog-filter-form.tsx, catalog-intro.tsx, catalog-herb-results.tsx; výpočet „jsou aktivní filtry“ v app/lib/catalog-page-helpers.ts (catalogHasActiveFilters, typ CatalogLoaderFilterSnapshot) + Vitest catalog-page-helpers.test.ts.
P2.3 Rizikové úpravy app/db/herbs.server.ts (SQL / filtry)
- Přepis nebo přeskupení
herbIdsMatchingCatalogFilters. - Skládání SQL fragmentů jinak než dnes.
- Změna logiky
science,studyType,month + part.
Stav: záměrně neprovedeno v rámci v3 bez datové / URL → ID matice nebo cílených integračních testů na D1. Parsery URL (parseMonthParam, parseCatalogPmSlugs, …) mají Vitest v app/lib/*.test.ts.
1. Velké soubory a routy (kromě přeneseného backlogu P2.x)
1.1 app/routes/sezona.$month.tsx (~300+ řádků)
Hotovo: tabulka bylin v app/components/sezona/sezona-month-herbs-table.tsx (SezonaMonthHerbsTable); měsíční chipy, regiony a části v app/components/sezona/sezona-month-filters.tsx (SezonaMonthFilters); dekor (SoftBlob/LeafSprig), drobečky a úvodní blok v app/components/sezona/sezona-month-intro.tsx (SezonaMonthIntro); horní blok (obal relative + intro + filtry) v sezona-month-top.tsx (SezonaMonthTop); prázdný stav bez řádků v app/components/sezona/sezona-month-empty.tsx (SezonaMonthEmpty); meta měsíce v app/lib/sezona-month-meta.ts + sezona-month-meta.test.ts; meta přehledu /sezona v app/lib/sezona-index-meta.ts + sezona-index-meta.test.ts; hlavička přehledu /sezona v app/components/sezona/sezona-index-header.tsx (SezonaIndexHeader); mřížka měsíců přehledu v app/components/sezona/sezona-index-month-grid.tsx (SezonaIndexMonthGrid); odkazy do katalogu (?region, /byliny?month + part) v app/lib/sezona-month-catalog-links.ts + sezona-month-catalog-links.test.ts — beze změny URL, query, textů a Tailwindu v extrahovaných blocích.
1.2 app/db/herb-detail.server.ts (~470 řádků)
Hotovo (bezsqlářský krok): čisté helpery resolveHerbImageSrc a parseRecipeStepsJson v app/lib/herb-detail-helpers.ts (receptové kroky přes sdílené parseJsonStringArray v app/lib/json-string-array.ts); server modul je importuje. SQL texty a bindy beze změny.
1.3 Další DB moduly střední velikosti
Částečně: sdílená normalizace slugů v app/lib/catalog-slug-normalize.ts (normalizeCatalogSlug) — používá topics.server.ts přes normalizeTopicSlug v topic-slug.ts, processing-methods.server.ts a aliasová routa byliny-na-zpracovani.$slug. Vitest catalog-slug-normalize.test.ts. Parsování JSON polí řetězců v app/lib/json-string-array.ts (parseJsonStringArray) — spiritual-guides.server.ts a receptové kroky přes herb-detail-helpers / omitEmptyTrimmed; Vitest json-string-array.test.ts. Fragmenty SQL pro měsíc/region sezóny přesunuty do app/db/sezona-harvest-sql.server.ts (harvestCoversMonthSql, herbInRegionSql) — import v sezona.server.ts; texty SQL beze změny. Další rozdělení herbs.server.ts / sjednocení s katalogem — backlog; zásada „žádný přepis WHERE bez matice“ platí.
1.4 Komponenty s vlastní logikou
Hotovo (drobně): app/components/ritual-guide-steps.tsx — počáteční hydrated pro jednokrokové návody bez zbytečného setState v efektu; u více kroků zůstává obnova z sessionStorage v useEffect (s vědomým eslint-disable pro pravidlo set-state-in-effect v tomto souboru).
1.5 app/routes/home.tsx
Hotovo: blok „Sběr právě teď“ v app/components/home/home-sezona-teaser.tsx (HomeSezonaTeaser); celá úvodní karta (dekor, nadpis, lead, teaser, CTA katalog) v app/components/home/home-hero-card.tsx (HomeHeroCard) — beze změny textů, URL a Tailwindu.
1.6 Přehledové katalogové routy
Hotovo: úvodní bloky a mřížky karet mimo loader/meta u /ritualy (RitualyIndexIntro, RitualyIndexGuideGrid), /region (RegionIndexIntro, RegionIndexGrid), /symptomy (SymptomyIndexIntro včetně GET formuláře q, SymptomyIndexTopicGrid), /zpracovani (ZpracovaniIndexIntro, ZpracovaniIndexMethodGrid), /recepty (ReceptyIndexIntro, ReceptyIndexRecipeGrid). Routy jen skládají meta, loader a layout main.
1.7 Roadmap a dokumentace
Hotovo: obsah /roadmap v app/components/roadmap/roadmap-content.tsx (RoadmapContent); přehled /dokumentace v app/components/dokumentace/dokumentace-index-content.tsx (DokumentaceIndexContent); detail /dokumentace/:slug (drobečky + karta Markdown) v dokumentace-doc-view.tsx (DokumentaceDocView). Logika meta / loader a registry dokumentů zůstávají v routách.
1.8 Detail regionu a tématu (symptomu)
Hotovo: /region/:slug — RegionDetailIntro, RegionDetailHerbGrid (app/components/region/); /symptomy/:slug — SymptomyDetailIntro, SymptomyDetailHerbSection (app/components/symptomy/). Štítek regions.type sjednocen v app/lib/region-type-label.ts (regionTypeLabel) — používá RegionIndexGrid a RegionDetailIntro.
1.9 Detail rituálu a způsobu zpracování
Hotovo: /ritualy/:slug — RitualyDetailIntro, RitualyDetailBody (app/components/ritualy/); /zpracovani/:slug — celý obsah stránky (včetně jednoho obalu relative) v zpracovani-detail-content.tsx (ZpracovaniDetailContent).
2. Opakující se UI a kořen aplikace
2.1 app/root.tsx — navigace a šablona
Hotovo: helper mainNavLinkClass(isActive); odkaz Přeskočit na obsah (#main-content); obal {children} má id="main-content" a tabIndex={-1}.
2.2 Dekor a layout bloky
Neprovedeno (volitelné): tenký PageDecor — riziko změny hloubky DOM; až bude potřeba, samostatný diff se screenshotem.
3. Meta a obsah — konzistence (bez velkých SEO featur)
Hotovo: v app/lib/site-meta.ts konstanty SITE_BRAND_NAME, SITE_TITLE_SUFFIX, SITE_TITLE_PIPE_BRAND ( | …); websiteSocialMeta používá značku z konstanty. Titulky a popisy v meta u hlavních rout (/, /byliny, /sezona, /symptomy, /ritualy, /region, /zpracovani, /recepty, /roadmap, /dokumentace) sjednoceny přes tyto konstanty (beze změny zobrazovaného textu oproti předchozím řetězcům). Vitest: app/lib/site-meta.test.ts.
4. Tooling: lint, formát, testy, CI
4.1 ESLint (+ TypeScript plugin)
Hotovo: eslint.config.mjs — @eslint/js, typescript-eslint, eslint-plugin-react-hooks; ignorované generované a build cesty.
4.2 Automatické testy
Hotovo: Vitest (vitest.config.ts), testy app/lib/month-param.test.ts, catalog-filter-params.test.ts, region-param.test.ts, site-meta.test.ts, topic-slug.test.ts, sezona-month-meta.test.ts, sezona-index-meta.test.ts, sezona-month-catalog-links.test.ts, catalog-page-helpers.test.ts, catalog-slug-normalize.test.ts, json-string-array.test.ts.
4.3 CI
Hotovo: .github/workflows/ci.yml spouští npm run verify (včetně cache npm dle setup-node).
5. Worker a provoz (workers/)
Hotovo (minimum): v workers/app.ts u scheduled runHerbMaintenance strukturovaný jednořádkový JSON log (level, component, trigger, ok, …) místo volného výpisu objektu. HTTP endpoint /__internal/herb-maintenance nadále vrací JSON tělo.
6. Výkon a assety
Částečně: Google Fonts v root.tsx už používají display=swap v URL; širší self-host / subset — samostatný úkol. Obrázky R2 / CLS — navázat na bezpecnost-a-media-stitky.md.
7. Repozitář a generované soubory
Beze změny kódu: pravidlo z v2 §3.3 platí (build/, .react-router/types, .wrangler/, worker-configuration.d.ts dle politiky — typicky necommitovat). Po merge konfliktech ověřit git ls-files.
8. Co zatím nedělat jako součást v3 refaktoru
- Neměnit veřejné URL, slugy dokumentace ani sitemap logiku bez tasku a datové kontroly.
- Nezasahovat do obsahu Markdownu v
docs/kvůli „úklidu“ — může změnit veřejné/dokumentace/:slug. - Neinstalovat lint + přepsat celý
app/v jednom PR s DB refaktorem.
Doporučené pořadí (indikativní)
Stabilizovat otevřené body P2.x(P2.1–P2.2 hotovo; P2.3 čeká na matici).Jedna bezpečná extrakce z.sezona.$month.tsxPrvní bezsqlářský split z.herb-detail.server.tsMalý helper pro NavLink třídy v.root.tsxSamostatný PR: ESLint základ.Samostatný PR: Vitest + testy parserů.
Akceptace dokumentu samotného
- Po implementaci doplněn stavový řádek a checklisty výše.
- Při zařazení do rozcestníku aktualizovat README.md v
docs/tasks/(řádek refaktor-v3).