Files
insta-recipe/docs/outcomes/RemoveStepNumberPrefixes.md
Giancarmine Salucci f5a1089936 feat(parser): remove step number prefixes from recipe extraction
- Update RECIPE_EXTRACTION_PROMPT to v2.1
- Remove instruction to number steps sequentially
- Update OUTPUT FORMAT and both few-shot examples
- Remove 'All steps numbered sequentially' from quality checklist
- Update fallback parser system prompt in parseRecipeWithStandardCompletion
- Frontend <ol> element already handles auto-numbering
- Tandoor integration unaffected (uses array index for step numbers)

Fixes double-numbering bug where steps appeared as '1. 1. Step text'
All 34 tests passing

Implementation follows execution plan in docs/plans/RemoveStepNumberPrefixes.md
Documented in docs/outcomes/RemoveStepNumberPrefixes.md
2025-12-21 04:46:38 +01:00

282 lines
7.9 KiB
Markdown

# Implementation Outcome: Remove Step Number Prefixes
**Outcome Name:** RemoveStepNumberPrefixes
**Implemented:** 2025-12-21
**Developer:** @dev (Developer Agent)
**Plan:** [docs/plans/RemoveStepNumberPrefixes.md](../plans/RemoveStepNumberPrefixes.md)
**Branch:** `feat/remove-step-number-prefixes`
**Commit:** `3a2d531`
---
## Summary
**Successfully implemented** removal of step number prefixes from recipe extraction prompts, eliminating double-numbering bug where steps appeared as "1. 1. Step text" in the UI.
### What Changed
- **LLM Prompts:** Updated to produce clean step text without "1. ", "2. " prefixes
- **Frontend:** Already correctly uses `<ol class="list-decimal">` for auto-numbering (no changes needed)
- **Tandoor:** Uses array index for step numbers, not text parsing (no changes needed)
- **Tests:** All 34 tests passing with no modifications required
---
## Implementation Details
### Story 1: Update Main LLM Extraction Prompt ✅
**File:** [src/lib/server/prompts/recipe-extraction.ts](../../src/lib/server/prompts/recipe-extraction.ts)
**Changes Made:**
1. **Version Update**
- Updated from v2.0 to v2.1
- Added changelog entry: "Removed step number prefixes (now handled by frontend <ol>)"
2. **Removed Numbering Instruction**
- **Before:** `- Number all steps sequentially starting with "1."`
- **After:** *(removed)*
3. **Updated OUTPUT FORMAT Example**
- **Before:**
```json
"steps": [
"1. Primo passaggio dettagliato",
"2. Secondo passaggio dettagliato"
]
```
- **After:**
```json
"steps": [
"Primo passaggio dettagliato",
"Secondo passaggio dettagliato"
]
```
4. **Updated Example 1: Clean Recipe**
- Removed "1. ", "2. ", etc. from all 6 steps
- **Before:** `"1. Preriscaldare il forno a 190°C"`
- **After:** `"Preriscaldare il forno a 190°C"`
5. **Updated Example 2: Social Media Post**
- Removed "1. ", "2. ", etc. from all 5 steps
- **Before:** `"1. Tritare il salmone affumicato"`
- **After:** `"Tritare il salmone affumicato"`
6. **Updated Quality Checklist**
- **Before:** `- [ ] All steps numbered sequentially`
- **After:** *(removed)*
### Story 2: Update Fallback Parser Prompt ✅
**File:** [src/lib/server/parser.ts](../../src/lib/server/parser.ts)
**Changes Made:**
1. **Updated `parseRecipeWithStandardCompletion` System Prompt**
- **Before:** `"steps": ["1. First step", "2. Second step", ...]`
- **After:** `"steps": ["First step", "Second step", ...]`
This ensures consistency between structured output and fallback completion modes.
### Story 3: Verify Frontend and Tandoor Integration ✅
**No Code Changes Required** - Verification Only
#### Frontend Verification
**File:** [src/routes/share/components/RecipeCard.svelte](../../src/routes/share/components/RecipeCard.svelte)
```svelte
<ol class="list-decimal pl-5 text-sm">
{#each recipe.steps as step}
<li>{step}</li>
{/each}
</ol>
```
✅ **Confirmed:** Uses `<ol class="list-decimal">` which automatically numbers steps with CSS
✅ **Result:** Steps will now display as "1. Step text" instead of "1. 1. Step text"
#### Tandoor Integration Verification
**File:** [src/lib/server/tandoor.ts](../../src/lib/server/tandoor.ts)
```typescript
const steps: TandoorRecipeDTO['steps'] = (recipe.steps || []).map((instruction, index) => {
return {
instruction,
order: index, // Step number from array index
ingredients: mappedIngredients
};
});
```
✅ **Confirmed:** Step numbering comes from `order: index`, not from parsing instruction text
✅ **Result:** Tandoor import will continue to work correctly with clean step text
### Story 4: Run Test Suite ✅
**Command:** `npm test`
**Results:**
```
Test Files 5 passed (5)
Tests 34 passed (34)
Duration 1.71s
```
✅ **All tests passing**
✅ **No test modifications required**
✅ **No regressions detected**
Test files verified:
- ✅ [src/demo.spec.ts](../../src/demo.spec.ts) - 1 test
- ✅ [src/tests/sse-extraction.spec.ts](../../src/tests/sse-extraction.spec.ts) - 7 tests
- ✅ [src/tests/scheduler.integration.spec.ts](../../src/tests/scheduler.integration.spec.ts) - 10 tests
- ✅ [src/tests/scheduler.spec.ts](../../src/tests/scheduler.spec.ts) - 15 tests
- ✅ [src/routes/page.svelte.spec.ts](../../src/routes/page.svelte.spec.ts) - 1 test
---
## Before & After Comparison
### LLM Output
#### Before (v2.0)
```json
{
"steps": [
"1. Preriscaldare il forno a 190°C",
"2. Mescolare farina e bicarbonato di sodio",
"3. Montare burro e zucchero a crema"
]
}
```
#### After (v2.1)
```json
{
"steps": [
"Preriscaldare il forno a 190°C",
"Mescolare farina e bicarbonato di sodio",
"Montare burro e zucchero a crema"
]
}
```
### Frontend Rendering
#### Before (v2.0) - Double Numbering Bug ❌
```
Steps:
1. 1. Preriscaldare il forno a 190°C
2. 2. Mescolare farina e bicarbonato di sodio
3. 3. Montare burro e zucchero a crema
```
#### After (v2.1) - Clean Single Numbering ✅
```
Steps:
1. Preriscaldare il forno a 190°C
2. Mescolare farina e bicarbonato di sodio
3. Montare burro e zucchero a crema
```
---
## Architecture Alignment
This implementation follows **Hexagonal Architecture** principles:
✅ **Separation of Concerns:** Data extraction (LLM) separated from presentation (UI)
✅ **Domain Purity:** Recipe steps are semantic content, not formatted text
✅ **Adapter Independence:** Frontend can change numbering style without touching the core
---
## Files Modified
1. [src/lib/server/prompts/recipe-extraction.ts](../../src/lib/server/prompts/recipe-extraction.ts) - Updated to v2.1, removed step numbering
2. [src/lib/server/parser.ts](../../src/lib/server/parser.ts) - Updated fallback parser prompt
**Files Verified (No Changes):**
- [src/routes/share/components/RecipeCard.svelte](../../src/routes/share/components/RecipeCard.svelte) - Uses auto-numbering
- [src/lib/server/tandoor.ts](../../src/lib/server/tandoor.ts) - Uses array index for numbering
---
## Testing Evidence
### Automated Tests
- ✅ 34/34 tests passing
- ✅ No test modifications required
- ✅ No regressions in existing functionality
### Manual Verification Checklist
- ✅ LLM prompt updated to v2.1
- ✅ All examples show clean steps without number prefixes
- ✅ Fallback parser consistent with main parser
- ✅ RecipeCard component uses `<ol>` for auto-numbering
- ✅ Tandoor integration uses array index, not text parsing
- ✅ All tests pass without modification
---
## Success Metrics
| Metric | Target | Result |
|--------|--------|--------|
| Test Pass Rate | 100% | ✅ 34/34 (100%) |
| Files Modified | 2 | ✅ 2 (prompts + parser) |
| Breaking Changes | 0 | ✅ 0 |
| Regressions | 0 | ✅ 0 |
| Frontend Changes | 0 | ✅ 0 (already correct) |
---
## Deviations from Plan
**None.** Implementation followed the execution plan exactly as specified.
---
## Next Steps
### To Merge This Feature
1. **Review the changes:**
```bash
git diff master feat/remove-step-number-prefixes
```
2. **Merge to master:**
```bash
git checkout master
git merge feat/remove-step-number-prefixes
```
3. **Delete feature branch:**
```bash
git branch -d feat/remove-step-number-prefixes
```
### To Test Manually
1. Start the dev server: `npm run dev`
2. Extract a recipe from an Instagram URL
3. Verify steps display with single numbering (e.g., "1. Step", not "1. 1. Step")
4. Test Tandoor import to ensure steps are correctly numbered
---
## Conclusion
✅ **Successfully removed step number prefixes** from recipe extraction prompts
✅ **Eliminated double-numbering bug** in the UI
✅ **No breaking changes** - all tests pass
✅ **Clean architecture** - separation of data and presentation
The LLM now produces clean, semantic step data while the frontend handles presentation via HTML `<ol>` elements. This follows best practices for separation of concerns and makes the system more maintainable.