Skip to content

Commit 1887b74

Browse files
JiroMusikclaude
andcommitted
Fix all cook/deduction endpoints: use canonical alias matching everywhere
Replaced SQL LIKE pattern matching with isIngredientInInventory() in: - POST /api/recipes/cook (direct cook from Recipes page) - PUT /api/calendar/:id/cook (cook from Calendar) - POST /api/cook/check-opened (opened items check) This ensures renamed inventory items and generic_name matches work correctly during deduction, same as recipe ingredient display. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 47d0433 commit 1887b74

1 file changed

Lines changed: 13 additions & 4 deletions

File tree

server.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,9 @@ app.post('/api/cook/check-opened', async (req, res) => {
10541054
}
10551055

10561056
let remainingToDeduct = deductAmount;
1057-
const rows = db.prepare(`SELECT * FROM items WHERE LOWER(name) LIKE LOWER(?) ESCAPE '\\' OR LOWER(?) LIKE LOWER('%' || name || '%') ORDER BY is_open DESC, expiry_date ASC`).all(`%${escapeLike(ing.name)}%`, ing.name) as any[];
1057+
// Use canonical alias matching
1058+
const allInv = db.prepare('SELECT * FROM items ORDER BY is_open DESC, expiry_date ASC').all() as any[];
1059+
const rows = allInv.filter(inv => isIngredientInInventory(ing.name, [inv]));
10581060

10591061
for (const item of rows) {
10601062
if (remainingToDeduct <= 0) break;
@@ -1372,8 +1374,10 @@ app.put('/api/calendar/:id/cook', async (req, res) => {
13721374
const smallestReq = convertToSmallestUnit(reqAmt, ing.unit);
13731375
let remainingToDeduct = smallestReq.amount;
13741376

1375-
const rows = db.prepare(`SELECT * FROM items WHERE (LOWER(name) LIKE LOWER(?) ESCAPE '\\' OR LOWER(?) LIKE LOWER('%' || name || '%')) AND quantity > 0 ORDER BY is_open DESC, expiry_date ASC`).all(`%${escapeLike(ing.name)}%`, ing.name) as any[];
1376-
1377+
// Use canonical alias matching (same as recipe ingredient checking)
1378+
const allInvItems = db.prepare('SELECT * FROM items WHERE quantity > 0 ORDER BY is_open DESC, expiry_date ASC').all() as any[];
1379+
const rows = allInvItems.filter(inv => isIngredientInInventory(ing.name, [inv]));
1380+
13771381
const matchingRows = rows.filter(row => {
13781382
const invSmallest = convertToSmallestUnit(row.quantity, row.unit);
13791383
return invSmallest.unit === smallestReq.unit;
@@ -1787,18 +1791,23 @@ app.post('/api/recipes/cook', (req, res) => {
17871791
const missing: string[] = [];
17881792

17891793
try {
1794+
const allItems = db.prepare('SELECT * FROM items WHERE quantity > 0').all() as any[];
1795+
17901796
db.transaction(() => {
17911797
for (const ing of usedIngredients) {
1792-
const item = db.prepare("SELECT * FROM items WHERE name LIKE ? ESCAPE '\\' LIMIT 1").get(`%${escapeLike(ing.name)}%`) as any;
1798+
// Use canonical alias matching (same as recipe ingredient checking)
1799+
const item = allItems.find(inv => isIngredientInInventory(ing.name, [inv]));
17931800
if (item) {
17941801
if (item.quantity >= ing.amount) {
17951802
const newQty = item.quantity - ing.amount;
17961803
db.prepare('UPDATE items SET quantity = ? WHERE id = ?').run(newQty, item.id);
1804+
item.quantity = newQty; // update in-memory for subsequent matches
17971805
deducted.push({ ...item, quantity_deducted: ing.amount });
17981806
} else {
17991807
db.prepare('UPDATE items SET quantity = 0 WHERE id = ?').run(item.id);
18001808
deducted.push({ ...item, quantity_deducted: item.quantity });
18011809
missing.push(`${ing.name} (Fehlt: ${ing.amount - item.quantity} ${ing.unit || item.unit || ''})`.trim());
1810+
item.quantity = 0;
18021811
}
18031812
} else {
18041813
missing.push(ing.name);

0 commit comments

Comments
 (0)