feat(schema): ingredient.section_heading (Migration 012 + Type)

Fuegt das nullable Feld section_heading zur ingredient-Tabelle hinzu
(Migration 012), erweitert den Ingredient-Typ und aktualisiert alle drei
Return-Stellen in parseIngredient. Downstream-Sites (repository, Editor,
Tests) bleiben rot – werden in Task 2+ behoben.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-19 14:49:42 +02:00
parent ad5a6afcd9
commit 72816d6b35
3 changed files with 8 additions and 3 deletions

View File

@@ -0,0 +1,4 @@
-- Nullable -- old rows keep NULL, new rows may have a section heading.
-- Rendering rule: if section_heading is set (not NULL and not empty),
-- a new section with this title starts at this ingredient row.
ALTER TABLE ingredient ADD COLUMN section_heading TEXT;

View File

@@ -105,16 +105,16 @@ export function parseIngredient(raw: string, position = 0): Ingredient {
if (tail.length > 0) {
const quantity = clampQuantity(UNICODE_FRACTION_MAP[firstChar]);
const { unit, name } = splitUnitAndName(tail);
return { position, quantity, unit, name, note, raw_text: rawText };
return { position, quantity, unit, name, note, raw_text: rawText, section_heading: null };
}
}
const qtyPattern = /^((?:\d+[.,]?\d*(?:\s*[-]\s*\d+[.,]?\d*)?)|(?:\d+\/\d+))\s+(.+)$/;
const qtyMatch = qtyPattern.exec(working);
if (!qtyMatch) {
return { position, quantity: null, unit: null, name: working, note, raw_text: rawText };
return { position, quantity: null, unit: null, name: working, note, raw_text: rawText, section_heading: null };
}
const quantity = clampQuantity(parseQuantity(qtyMatch[1]));
const { unit, name } = splitUnitAndName(qtyMatch[2]);
return { position, quantity, unit, name, note, raw_text: rawText };
return { position, quantity, unit, name, note, raw_text: rawText, section_heading: null };
}

View File

@@ -5,6 +5,7 @@ export type Ingredient = {
name: string;
note: string | null;
raw_text: string;
section_heading: string | null;
};
export type Step = {