diff --git a/.ai_agency/memory/backlog.json b/.ai_agency/memory/backlog.json index 16ef298..2f7c9c8 100644 --- a/.ai_agency/memory/backlog.json +++ b/.ai_agency/memory/backlog.json @@ -399,14 +399,33 @@ { "index": 2, "name": "implement_wallet_deduction_in_orders_service", "description": "Deduct user walletBalance and create WalletTransaction in OrdersService.create", "status": "done" }, { "index": 3, "name": "wire_checkout_page_wallet_sync", "description": "Send paymentMethod in API call and trigger fetchProfile() in CheckoutPage.tsx", "status": "done" } ] + }, + { + "id": "EPIC-11-TASK-01", + "title": "Pet Supplement Consumption Tracking & Depletion Monitor Fix", + "description": "Ensure updatePet and setPets in usePetStore update and preserve pet consumptions array locally upon order placement so AI depletion monitor displays remaining supplement levels for active pets.", + "architectural_layer": "state_management", + "assigned_role": "06_dev_frontend", + "priority": "HIGH", + "status": "completed", + "max_files_allowed": 4, + "estimated_minutes": 20, + "dependency_task_ids": ["EPIC-10-TASK-01"], + "acceptance_criteria": [ + "ثبت واقعی میزان مکمل‌های خریده‌شده در پایش موجودی پت (usePetStore)", + "نمایش لحظه‌ای مکمل‌های خریده‌شده، درصد باقیمانده و تخمین اتمام مصرف پت در پروفایل" + ], + "sub_steps": [ + { "index": 1, "name": "update_pet_store_consumptions_persistence", "description": "Always update local pets array in updatePet and preserve consumptions in setPets", "status": "done" } + ] } ], "metadata": { - "total": 20, - "completed": 20, + "total": 21, + "completed": 21, "in_progress": 0, "pending": 0, - "generated_at": "2026-07-26T20:40:00Z", - "decomposition_pass": 8 + "generated_at": "2026-07-26T20:45:00Z", + "decomposition_pass": 9 } } \ No newline at end of file diff --git a/.ai_agency/memory/state.json b/.ai_agency/memory/state.json index 12d2c33..0b0d350 100644 --- a/.ai_agency/memory/state.json +++ b/.ai_agency/memory/state.json @@ -7,12 +7,12 @@ "status": "COMPLETE", "checkpoint": { "active_agent": "01_auditor", - "current_ticket_id": "EPIC-10-TASK-01", + "current_ticket_id": "EPIC-11-TASK-01", "sub_step": { - "index": 3, - "total": 3, - "name": "wire_checkout_page_wallet_sync", - "description": "Full-stack wallet balance deduction and charity donation total persistence in PostgreSQL complete and 100% verified" + "index": 1, + "total": 1, + "name": "update_pet_store_consumptions_persistence", + "description": "Pet supplement consumption tracking and AI stock monitor persistence complete and 100% verified" } }, "review_phase": { diff --git a/frontend/application/components/CheckoutPage.tsx b/frontend/application/components/CheckoutPage.tsx index 6a2935a..82b8d0f 100644 --- a/frontend/application/components/CheckoutPage.tsx +++ b/frontend/application/components/CheckoutPage.tsx @@ -125,8 +125,9 @@ export default function CheckoutPage() { await fetchProfile(); // 4. Update pet consumptions and charity contributions for active pet - if (activePet) { - const newConsumptions = [...(activePet.consumptions || [])]; + const targetPet = activePet || usePetStore.getState().pets[0]; + if (targetPet) { + const newConsumptions = [...(targetPet.consumptions || [])]; items.forEach(item => { const existing = newConsumptions.find(c => c.productId === item.product.id); @@ -142,7 +143,7 @@ export default function CheckoutPage() { } }); - updatePet(activePet.id, { + updatePet(targetPet.id, { consumptions: newConsumptions }); } diff --git a/frontend/application/lib/store/usePetStore.ts b/frontend/application/lib/store/usePetStore.ts index 538ebef..cb25a52 100644 --- a/frontend/application/lib/store/usePetStore.ts +++ b/frontend/application/lib/store/usePetStore.ts @@ -135,6 +135,10 @@ export const usePetStore = create()( return pets.find((p) => p.id === activePetId) || null; }, updatePet: async (id, updates) => { + set((state) => ({ + pets: state.pets.map((p) => (p.id === id ? { ...p, ...updates } : p)), + })); + const { useUserStore } = await import("./userStore"); const isLoggedIn = useUserStore.getState().isLoggedIn; @@ -154,10 +158,6 @@ export const usePetStore = create()( console.error("Failed to update pet via backend API:", error); toast.error("خطا در ویرایش اطلاعات پت در سرور"); } - } else { - set((state) => ({ - pets: state.pets.map((p) => (p.id === id ? { ...p, ...updates } : p)), - })); } }, addReminder: async (petId, reminder) => { @@ -191,34 +191,38 @@ export const usePetStore = create()( } }, setPets: (backendPets) => { - const mappedPets: PetProfile[] = backendPets.map(bp => ({ - id: bp.id, - name: bp.name, - type: bp.type as any, - breed: bp.breed, - age: Number(bp.age), - weight: Number(bp.weight), - activityLevel: bp.activityLevel as any, - medicalConditions: bp.medicalConditions?.map((mc: any) => mc.condition) || [], - image: bp.imageUrl || undefined, - reminders: bp.reminders?.map((r: any) => ({ - id: r.id, - title: r.title, - time: r.time, - frequency: r.frequency as any, - productId: r.productId, - completedDates: r.completions?.map((c: any) => c.completedDate) || [] - })) || [], - logs: bp.healthLogs?.map((hl: any) => ({ - id: hl.id, - date: hl.loggedDate, - appetite: hl.appetite as any, - energy: hl.energy as any, - digestion: hl.digestion as any, - note: hl.note || undefined - })) || [], - consumptions: [] - })); + const currentLocalPets = get().pets; + const mappedPets: PetProfile[] = backendPets.map(bp => { + const existingLocal = currentLocalPets.find(lp => lp.id === bp.id); + return { + id: bp.id, + name: bp.name, + type: bp.type as any, + breed: bp.breed, + age: Number(bp.age), + weight: Number(bp.weight), + activityLevel: bp.activityLevel as any, + medicalConditions: bp.medicalConditions?.map((mc: any) => mc.condition) || [], + image: bp.imageUrl || undefined, + reminders: bp.reminders?.map((r: any) => ({ + id: r.id, + title: r.title, + time: r.time, + frequency: r.frequency as any, + productId: r.productId, + completedDates: r.completions?.map((c: any) => c.completedDate) || [] + })) || [], + logs: bp.healthLogs?.map((hl: any) => ({ + id: hl.id, + date: hl.loggedDate, + appetite: hl.appetite as any, + energy: hl.energy as any, + digestion: hl.digestion as any, + note: hl.note || undefined + })) || [], + consumptions: existingLocal?.consumptions || [] + }; + }); set({ pets: mappedPets, activePetId: get().activePetId && mappedPets.some(p => p.id === get().activePetId) ? get().activePetId : (mappedPets[0]?.id || null) }); }, }),