Datový model

Stav dokumentu: Hotovo jako referenční popis schématu — při migraci aktualizovat text tak, aby odpovídal migrations/*.sql.

1. herbs

CREATE TABLE herbs (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  local_name TEXT NOT NULL,
  latin_name TEXT NOT NULL,
  family TEXT,
  plant_type TEXT,
  short_description TEXT,
  full_description TEXT,
  identification_notes TEXT,
  confusion_risk_notes TEXT,
  safety_level TEXT DEFAULT 'unknown',
  beginner_friendly INTEGER DEFAULT 0,
  is_published INTEGER DEFAULT 0,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL
);

Migrace 0007_herb_similar_and_safety_notes.sql doplňuje na herbs volitelné sloupce drug_interactions_note, phototoxicity_note (souhrnné texty MVP1 §1.11) a vytváří tabulku herb_similar (odkazy na podobné publikované byliny).

2. herb_names

CREATE TABLE herb_names (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  name TEXT NOT NULL,
  language TEXT,
  region_id INTEGER,
  type TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (region_id) REFERENCES regions(id)
);

3. regions

CREATE TABLE regions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  type TEXT NOT NULL,
  parent_region_id INTEGER,
  country_code TEXT,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL,
  FOREIGN KEY (parent_region_id) REFERENCES regions(id)
);

4. herb_regions

CREATE TABLE herb_regions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  region_id INTEGER NOT NULL,
  occurrence_status TEXT DEFAULT 'unknown',
  notes TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (region_id) REFERENCES regions(id)
);

5. habitats

CREATE TABLE habitats (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  description TEXT
);

6. plant_parts

CREATE TABLE plant_parts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  description TEXT
);

7. harvest_periods

CREATE TABLE harvest_periods (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  plant_part_id INTEGER NOT NULL,
  region_id INTEGER,
  month_from INTEGER NOT NULL,
  month_to INTEGER NOT NULL,
  season TEXT,
  growth_phase TEXT,
  best_time_of_day TEXT,
  weather_notes TEXT,
  harvest_notes TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (plant_part_id) REFERENCES plant_parts(id),
  FOREIGN KEY (region_id) REFERENCES regions(id)
);

8. processing_methods

CREATE TABLE processing_methods (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  short_description TEXT,
  full_description TEXT,
  difficulty_level TEXT,
  required_equipment TEXT,
  safety_notes TEXT,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL
);

Veřejná část webu načítá katalog z této tabulky na /zpracovani a /zpracovani/:slug; na kartě byliny se k vazbám z herb_processing_methods přidávají i short_description / full_description příslušné metody. Ukázkové delší texty pro prvních pět metod z seedu doplňuje migrace 0008_processing_method_encyclopedia.sql. Úplný výčet způsobů podle produktové specifikace (10-product-spec.md §7) zřizuje migrace 0009_processing_methods_product_spec.sql (u nových řádků je zatím obvykle jen krátký popis).

8.1. Slugy katalogu (processing_methods.slug)

SlugNázev (UI)Odpovídá §7 produktovky
cajČajčaj / nálev
odvarOdvarodvar
macerat-studenyMacerát za studenamacerát za studena
tinkturaTinkturatinktura
glyceritGlyceritglycerit
olejBylinný olejbylinný olej
mastMastmast
balzamBalzámbalzám
sirupSirupsirup
medMedbylinný med
ocetBylinný ocetbylinný ocet
vinoBylinné vínobylinné víno
likerBylinný likérbylinný likér
vykurovadloVykuřovadlovykuřovadlo
svazekBylinný svazekbylinný svazek
koupelKoupelkoupel
obkladObkladobklad
inhalaceInhalaceinhalace
prasekPrášekprášek
kapsleKapslekapsle
esenceEsenceesence
hydrolatHydroláthydrolát
esencialni-olejEsenciální olejesenciální olej
fermentaceFermentacefermentace
kulinarskeKulinářské použitíkulinářské použití
salatSalátnavíc v datech (syrová příprava); obecné kulinářské užití má slug kulinarske

Filtr katalogu bylin: query param pm=<slug> (viz 23-api-and-routes.md).

9. herb_processing_methods

CREATE TABLE herb_processing_methods (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  processing_method_id INTEGER NOT NULL,
  plant_part_id INTEGER,
  suitability TEXT DEFAULT 'unknown',
  purpose TEXT,
  traditional_use INTEGER DEFAULT 0,
  scientific_use INTEGER DEFAULT 0,
  safety_notes TEXT,
  recipe_notes TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (processing_method_id) REFERENCES processing_methods(id),
  FOREIGN KEY (plant_part_id) REFERENCES plant_parts(id)
);

10. topics

CREATE TABLE topics (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  type TEXT NOT NULL,
  parent_topic_id INTEGER,
  description TEXT,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL,
  FOREIGN KEY (parent_topic_id) REFERENCES topics(id)
);

11. herb_topic_links

CREATE TABLE herb_topic_links (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  topic_id INTEGER NOT NULL,
  link_type TEXT NOT NULL,
  evidence_level TEXT DEFAULT 'unknown',
  source_type TEXT,
  notes TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (topic_id) REFERENCES topics(id)
);

Tabulka a základní seed témat / vazeb jsou v migraci 0011_herb_topic_links_seed.sql.

12. spiritual_uses

CREATE TABLE spiritual_uses (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  title TEXT NOT NULL,
  category TEXT,
  description TEXT NOT NULL,
  cultural_context TEXT,
  use_form TEXT,
  related_topic_id INTEGER,
  claim_strength TEXT,
  source_note TEXT,
  claim_nature TEXT,
  facets TEXT,
  is_published INTEGER DEFAULT 0,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (related_topic_id) REFERENCES topics(id)
);

Sloupce claim_nature (typ tvrzení dle §1) a facets (JSON pole slugů podtypů dle §2) přidává migrace 0010_spiritual_nature_facets.sql. Povolené hodnoty a české popisky: app/lib/spiritual-content-labels.ts (návrhová povaha záznamu) a app/lib/claim-labels.ts (síla tvrzení / legacy claim_strength, vazby téma–bylina, vědecké řádky v UI).

13. scientific_evidence

CREATE TABLE scientific_evidence (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  plant_part_id INTEGER,
  topic_id INTEGER,
  active_compound TEXT,
  claim_summary TEXT NOT NULL,
  evidence_level TEXT NOT NULL,
  study_type TEXT NOT NULL,
  source_title TEXT,
  source_url TEXT,
  doi TEXT,
  publication_year INTEGER,
  authors TEXT,
  journal TEXT,
  limitations TEXT,
  dosage_notes TEXT,
  preparation_form TEXT,
  is_published INTEGER DEFAULT 0,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (plant_part_id) REFERENCES plant_parts(id),
  FOREIGN KEY (topic_id) REFERENCES topics(id)
);

14. images

CREATE TABLE images (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER,
  r2_key TEXT NOT NULL,
  public_url TEXT,
  image_type TEXT NOT NULL,
  alt_text TEXT,
  caption TEXT,
  photographer TEXT,
  license TEXT,
  source_url TEXT,
  width INTEGER,
  height INTEGER,
  sort_order INTEGER DEFAULT 0,
  created_at TEXT NOT NULL,
  FOREIGN KEY (herb_id) REFERENCES herbs(id)
);

Veřejné zobrazení: má-li řádek vyplněné public_url, použije se přímo (externí host). Jinak Worker servíruje objekt z R2 podle r2_key na cestě /media/<r2_key> (složky v klíči musí odpovídat objektům v bucketu). Pro čistě externí obrázky může r2_key sloužit jen jako stabilní identifikátor (např. prefix external/…), viz seed v migraci 0002.

15. safety_warnings

CREATE TABLE safety_warnings (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  warning_type TEXT NOT NULL,
  severity TEXT NOT NULL,
  title TEXT NOT NULL,
  description TEXT NOT NULL,
  source_url TEXT,
  created_at TEXT NOT NULL,
  FOREIGN KEY (herb_id) REFERENCES herbs(id)
);

16. storage_methods a herb_storage (skladování, MVP1 §1.5)

Katalog typických postupů uchování a vazba na bylinu (doplněno v migraci 0003_storage.sql).

CREATE TABLE storage_methods (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  short_description TEXT,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL
);

CREATE TABLE herb_storage (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  storage_method_id INTEGER NOT NULL,
  plant_part_id INTEGER,
  shelf_life_note TEXT,
  light_sensitivity TEXT,
  moisture_sensitivity TEXT,
  safety_note TEXT,
  sort_order INTEGER DEFAULT 0,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (storage_method_id) REFERENCES storage_methods(id),
  FOREIGN KEY (plant_part_id) REFERENCES plant_parts(id)
);

17. herb_similar (podobné byliny, MVP1 §1.2)

Navázání publikovaných bylin navzájem; na kartě se zobrazí jen cílové byliny s is_published = 1. Migrace: 0007_herb_similar_and_safety_notes.sql.

CREATE TABLE herb_similar (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  herb_id INTEGER NOT NULL,
  related_herb_id INTEGER NOT NULL,
  sort_order INTEGER NOT NULL DEFAULT 0,
  note TEXT,
  FOREIGN KEY (herb_id) REFERENCES herbs(id),
  FOREIGN KEY (related_herb_id) REFERENCES herbs(id),
  UNIQUE (herb_id, related_herb_id)
);