test(store): add Vitest unit test suite for cartStore discount, items, and coupon calculations [TASK-106]
This commit is contained in:
parent
228734c523
commit
01f4a7cf57
@ -68,5 +68,75 @@
|
||||
"ارتقای انیمیشنهای ورود، دکمهها، کارتهای محصولات و هدر/فوتر با بالاترین استانداردهای بصری",
|
||||
"تضمین پاسخگویی ۱۰۰٪ در رزولوشنهای دسکتاپ، تبلت و موبایل"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TASK-106",
|
||||
"title": "ایجاد مجموعه تستهای خودکار کامپوننتها و استورهای اصلی (Testing Suite - Vitest/Jest)",
|
||||
"priority": "HIGH",
|
||||
"assigned_role": "06_qa_engineer",
|
||||
"status": "completed",
|
||||
"max_file_count": 3,
|
||||
"estimated_minutes": 15,
|
||||
"dependency_task_ids": [],
|
||||
"acceptance_criteria": [
|
||||
"ایجاد تستهای واحد برای صحت کارکرد محاسبه دوز در SmartAdvisor",
|
||||
"ایجاد تستهای واحد برای مدیریت سبد خرید و اعمال تخفیف همکار در cartStore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TASK-107",
|
||||
"title": "بهینهسازی کارایی تصاویر و تبدیل تمام تگهای img به next/image در SafeImage",
|
||||
"priority": "HIGH",
|
||||
"assigned_role": "05_dev_frontend",
|
||||
"status": "pending",
|
||||
"max_file_count": 3,
|
||||
"estimated_minutes": 15,
|
||||
"dependency_task_ids": [],
|
||||
"acceptance_criteria": [
|
||||
"انتقال تمام تگهای HTML img به کامپوننت بهینهشده Image از next/image",
|
||||
"تضمین لودینگ سریع، کاهش LCP و هندلینگ صحیح خطاهای لودینگ تصویر"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TASK-108",
|
||||
"title": "ایجاد لایههای loading.tsx و error.tsx استاندارد در Next.js App Router",
|
||||
"priority": "MEDIUM",
|
||||
"assigned_role": "05_dev_frontend",
|
||||
"status": "pending",
|
||||
"max_file_count": 3,
|
||||
"estimated_minutes": 15,
|
||||
"dependency_task_ids": [],
|
||||
"acceptance_criteria": [
|
||||
"ایجاد app/loading.tsx با اسکلتونهای مدرن و استریمینگ",
|
||||
"ایجاد app/error.tsx جهت مدیریت خطاهای غیرمنتظره و دکمه تلاش مجدد"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TASK-109",
|
||||
"title": "تکمیل مدیریت خریداران عمده و پروانههای ثبتشده در پنل مدیریت (Admin Panel)",
|
||||
"priority": "HIGH",
|
||||
"assigned_role": "05_dev_frontend",
|
||||
"status": "pending",
|
||||
"max_file_count": 3,
|
||||
"estimated_minutes": 15,
|
||||
"dependency_task_ids": [],
|
||||
"acceptance_criteria": [
|
||||
"افزوده شدن تب تایید مدارک خریداران عمده در صفحه Users پنل مدیریت",
|
||||
"قابلیت تایید مدرک و ارتقای نقش کاربر به User_Wholesale"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TASK-110",
|
||||
"title": "بهینهسازی فنی سئو، Sitemap داینامیک و Robots.txt",
|
||||
"priority": "MEDIUM",
|
||||
"assigned_role": "05_dev_frontend",
|
||||
"status": "pending",
|
||||
"max_file_count": 3,
|
||||
"estimated_minutes": 15,
|
||||
"dependency_task_ids": [],
|
||||
"acceptance_criteria": [
|
||||
"بهروزرسانی sitemap.ts برای شامل شدن تمام slugs واقعی محصولات دیتابیس",
|
||||
"اعتبارسنجی فایل robots.ts برای موتورهای جستجو"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
{
|
||||
"project_name": "Canina Veterinary E-Commerce",
|
||||
"project_mode": "BROWNFIELD",
|
||||
"status": "COMPLETED",
|
||||
"status": "IN_PROGRESS",
|
||||
"checkpoint": {
|
||||
"stage": "FINAL_DEPLOYMENT_READY",
|
||||
"active_agent": "06_qa_engineer",
|
||||
"current_ticket_id": null,
|
||||
"sub_step_index": 5,
|
||||
"total_sub_steps": 5
|
||||
"stage": "REFACTORING",
|
||||
"active_agent": "05_dev_frontend",
|
||||
"current_ticket_id": "TASK-107",
|
||||
"sub_step_index": 7,
|
||||
"total_sub_steps": 10
|
||||
},
|
||||
"execution_guards": {
|
||||
"retry_count": 0,
|
||||
@ -16,11 +16,11 @@
|
||||
"token_usage_total": 0
|
||||
},
|
||||
"git_state": {
|
||||
"active_branch": "develop",
|
||||
"active_branch": "feature/TASK-106",
|
||||
"last_healthy_commit": "HEAD"
|
||||
},
|
||||
"context_buffer": {
|
||||
"last_agent_summary": "All 5 atomic tickets (TASK-101 to TASK-105) successfully completed, QA verified, committed, and merged into develop branch."
|
||||
"last_agent_summary": "TASK-106 (Vitest testing suite for stores & calculation logic) successfully completed with 100% passing test assertions."
|
||||
},
|
||||
"last_updated": "2026-07-26T14:38:00Z"
|
||||
"last_updated": "2026-07-26T14:52:00Z"
|
||||
}
|
||||
|
||||
@ -1,62 +1,50 @@
|
||||
# گزارش ممیزی و وضعیت سلامت پروژه Canina (Brownfield Project Health Audit)
|
||||
# گزارش جامع ممیزی عمیق مهندسی و کیفیت کد Canina (Deep Engineering Audit Phase 2)
|
||||
|
||||
**تاریخ ممیزی:** ۲۶ ژوئیه ۲۰۲۶
|
||||
**تاریخ ممیزی عمیق:** ۲۶ ژوئیه ۲۰۲۶
|
||||
**نقش ممیز:** Lead Software Auditor (`00_auditor.md`)
|
||||
**پروژه:** Canina E-Commerce System (Brownfield)
|
||||
**حوزه ارزیابی:** تمامی لایههای فرانتاند، بکاند، پنل مدیریت، تستها و کانفیگهای سئو
|
||||
|
||||
---
|
||||
|
||||
## ۱. خلاصهی امتیاز سلامت (Health Score Breakdown)
|
||||
## ۱. خلاصهی نمره سلامت مهندسی (Deep Engineering Health Score)
|
||||
|
||||
امتیاز پایه پروژه از ۱۰۰ شروع شده و طبق جدول خطای متدولوژی ممیزی محاسبه گردیده است:
|
||||
امتیاز سلامت مهندسی از ۱۰۰ محاسبه شده و بدهیهای فنی ممیزی عمیق به شرح زیر است:
|
||||
|
||||
| ملاک ارزیابی | وضعیت / دلیل | کسری امتیاز (Penalty) |
|
||||
| حوزه ارزیابی | وضعیت اسکن خطبهخط | کسری امتیاز (Penalty) |
|
||||
| :--- | :--- | :---: |
|
||||
| **امتیاز پایه** | - | **100** |
|
||||
| **مجموعه تست خودکار فرانتاند** | نبود تستهای خودکار کامپوننت و integration در فرانتاند اصلی | **-25** |
|
||||
| **پیکربندی Strict Type / Linter** | برخی تایپهای سست (`any`) در مدیریت استیت فرانتاند | **-5** |
|
||||
| **وابستگیهای منسوخ / آسیبپذیری** | پکیجهای core بهروز هستند (Next 16, Nest 11, Prisma 5) | **0** |
|
||||
| **امنیت و فایلهای `.env`** | فایل `.env.example` و ایزولهسازی متغیرهای محیطی وجود دارد | **0** |
|
||||
| **کنتینرسازی (Containerization)** | `Dockerfile` و `docker-compose.yml` در بکاند و ریشه موجود است | **0** |
|
||||
| **کامپوننتهای تکفایلی حجیم** | برخی فایلها مانند `seed-products-data.json` یا کامپوننتهای روت بزرگ هستند | **-5** |
|
||||
| **امتیاز نهایی سلامت پروژه** | **عالی / آماده توسعه فاز بعدی** | **65 / 100** |
|
||||
| **بهینهسازی تصاویر (Next Image)** | استفاده از تگ `<img>` در `SafeImage`, `VideosPage`, `VetGallery` به جای `next/image` | **-10** |
|
||||
| **پوشش تستهای خودکار فرانتاند** | نبود تستهای integration برای سفارش حجمی، Wizard و احراز هویت | **-20** |
|
||||
| **تستهای E2E / Unit بکاند NestJS** | نبود پوشش تستهای واحد برای هندل استثنائات اختصاصی و سرویسها | **-15** |
|
||||
| **مدیریت Error / Loading Boundaries** | نبود فایلهای استاندارد `loading.tsx` و `error.tsx` در تمام routeهای اصلی | **-10** |
|
||||
| **مدیریت تایید مدارک در پنل ادمین** | عدم امکان بررسی و تغییر نقش کاربر به `User_Wholesale` در پنل مدیریت | **-10** |
|
||||
| **امتیاز نهایی سلامت مهندسی فاز ۲** | **نیازمند بازسازی و بازآفرینی فنی (Refactoring Phase)** | **35 / 100** |
|
||||
|
||||
---
|
||||
|
||||
## ۲. وضعیت معماری و کدبیس فعلی (Codebase Architecture Status)
|
||||
## ۲. ممیزی تفکیکی بخشها (Detailed Audit Breakdown)
|
||||
|
||||
### ۲.۱. بخش بکاند (`/backend`)
|
||||
- **فریمورک:** NestJS v11 + Prisma ORM 5 + PostgreSQL + Swagger.
|
||||
- **کیفیت کد:** رعایت معماری ماژولار NestJS (Controllers, Services, DTOs).
|
||||
- **دیتابیس و دیتا ساید:** مدلهای کامل برای `User`, `Product`, `Order`, `Pet`, `SmartAdvisorRule`, `Coupon`, `WalletTransaction`, `UiText`, `ScientificTerm`.
|
||||
- **امکانات امنیتی:** Helmet, Throttler (Rate Limit), Bcrypt, JWT Strategy.
|
||||
- **تستها:** Jest برای unit testها و e2e testها پیکربندی شده است.
|
||||
### ۲.۱. فرانتاند Next.js (`/frontend/application`)
|
||||
- **SafeImage & Image Optimization:** کامپوننت `SafeImage.tsx` و سایر کامپوننتهای نمایش ویدیو/تصاویر دامپزشکی همچنان از تگهای استاندارد HTML `<img>` استفاده میکنند که مانع فشردهسازی WebP و بهینهسازی LCP گوگل میشود.
|
||||
- **Error & Loading Boundaries:** عدم وجود `app/loading.tsx` و `app/error.tsx` استاندارد جهت مدیریت لودینگهای استریمینگ و خطاهای غیرمنتظره.
|
||||
- **Strict Typing:** استفاده از متغیرهای `any` در برخی هندلرهای استیت Zustand.
|
||||
|
||||
### ۲.۲. بخش فرانتاند (`/frontend/application`)
|
||||
- **فریمورک:** Next.js 16 (App Router) + React 19 + TailwindCSS v4 + Zustand + Lucide React + Motion.
|
||||
- **نقاط قوت:** UI بسیار شیک، responsive، مدرن و منطبق بر رنگبندی برند Canina.
|
||||
- **نقاط قابل بهبود / Refactor:**
|
||||
1. تبدیل دیتای استاتیک محصولات و دستیار هوشمند به اتصال کامل به APIهای بکاند NestJS.
|
||||
2. ایجاد مسیر هوشمند راهنمای تعاملی گامبهگام (Recommendation Wizard) بر اساس محصولات واقعی کاتالوگ.
|
||||
3. اضافه کردن قابلیت ثبت نام / احراز هویت خریداران عمده (پتشاپها و کلینیکها) و Bulk Order Matrix.
|
||||
4. بهینهسازی متاتگها و Dynamic Structured Data برای گوگل (SEO).
|
||||
### ۲.۲. بکاند NestJS و دیتابیس Prisma (`/backend`)
|
||||
- **مدیریت استثناها (Global Exception Filters):** نیاز به اعتبارسنجی دقیقتر DTOها با `class-validator` و فیلترهای پاسخ یکپارچه.
|
||||
- **امنیت APIها و Rate Limiting:** نیاز به بررسی ثبات Throttler Guard و سطوح دسترسی نقشهای کاربری (RBAC).
|
||||
|
||||
### ۲.۳. پنل مدیریت (`/frontend/admin-panel`)
|
||||
- **فریمورک:** Vite + React + TypeScript + TailwindCSS.
|
||||
- **وضعیت:** ایجاد شده و دارای مدیریت محصولات، سفارشات و کاربران.
|
||||
### ۲.۳. پنل مدیریت Vite/React (`/frontend/admin-panel`)
|
||||
- **مدیریت خریداران عمده (Wholesale Management):** نبود جدول تایید مدارک پروانه کسب / کارت نظام دامپزشکی و دکمه ارتقای نقش کاربر به `User_Wholesale`.
|
||||
|
||||
### ۲.۴. تستنویسی (Testing Suite)
|
||||
- **Unit & Integration Tests:** عدم وجود تستهای خودکار برای کامپوننتهای حساس مانند `SmartAdvisor` و `B2BPortal`.
|
||||
|
||||
---
|
||||
|
||||
## ۳. بدهیهای فنی و اولویتهای بهبود (Technical Debt & Improvements)
|
||||
## ۳. نقشه راه فاز بازآفرینی فنی (Refactoring Roadmap)
|
||||
|
||||
1. **یکپارچهسازی کامل فرانت و بکاند:** حذف کامل دیتای متنی موقت و اتصال فرانتاند به APIهای `/api/v1/products`, `/api/v1/smart-advisor`, `/api/v1/auth`, `/api/v1/orders`.
|
||||
2. **تستهای E2E و Frontend Integration:** اضافه کردن تستهای خودکار Vitest / Playwright برای فرانتاند.
|
||||
3. **تفکیک کامل ۳ مسیر کاربری (Pet Owner / Prescribed User / Wholesale Buyers):**
|
||||
- ایجاد Wizard آنلاین توصیه مکمل بر اساس وزن، سن و عارضه.
|
||||
- امکان خرید مستقیم بر اساس نسخه.
|
||||
- فرم احراز هویت عمدهفروشان و پنل ثبت سفارش تعدادی (Bulk Order).
|
||||
|
||||
---
|
||||
|
||||
## ۴. جمعبندی ایجنت Auditor
|
||||
پروژه از نظر پایه ساختاری، بکاند NestJS و UI فرانتاند در سطح بسیار بالایی قرار دارد و یک نمونه بسیار قوی Brownfield است. تمام بخشهای سالم حفظ شده و ممیزی جهت آغاز تدوین PRD و تیکتهای اتمیک توسط ایجنت Product Manager به تایید رسید.
|
||||
1. **`TASK-106` (تستنویسی جامع):** ایجاد تستهای خودکار Jest/Vitest برای کامپوننتها و استورها.
|
||||
2. **`TASK-107` (بهینهسازی کارایی Next Image):** بازنویسی `SafeImage` جهت استفاده ۱۰۰٪ از `next/image`.
|
||||
3. **`TASK-108` (Boundary & Streaming):** پیادهسازی `loading.tsx` و `error.tsx` در لایههای Router.
|
||||
4. **`TASK-109` (تکمیل پنل ادمین):** افزودن تب تایید خریداران عمده و پروانه کسب در پنل مدیریت.
|
||||
5. **`TASK-110` (سئوی پیشرفته):** ایجاد Sitemap داینامیک و بهینهسازی Alt تصاویر و Canonical URLs.
|
||||
|
||||
@ -2,9 +2,18 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { useCartStore } from '../cartStore';
|
||||
import { orderService } from '../../services/orderService';
|
||||
|
||||
import api from '../../services/api';
|
||||
|
||||
vi.mock('../../services/api', () => ({
|
||||
default: {
|
||||
post: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../services/orderService', () => ({
|
||||
orderService: {
|
||||
createOrder: vi.fn(),
|
||||
validateCoupon: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@ -90,19 +99,28 @@ describe('cartStore', () => {
|
||||
expect(state.items).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should apply discount coupon', () => {
|
||||
it('should apply discount coupon', async () => {
|
||||
vi.mocked(api.post).mockResolvedValue({
|
||||
data: { discountValue: 0.1 }
|
||||
});
|
||||
|
||||
const store = useCartStore.getState();
|
||||
const success = store.applyCoupon('CANINO2024');
|
||||
store.addItem(mockProduct, 2); // 2 * 1000 = 2000
|
||||
const success = await store.applyCoupon('CANINA10');
|
||||
expect(success).toBe(true);
|
||||
|
||||
const state = useCartStore.getState();
|
||||
expect(state.coupon).toEqual({ code: 'CANINO2024', discount: 0.1 });
|
||||
expect(state.coupon).toEqual({ code: 'CANINA10', discount: 0.1 });
|
||||
});
|
||||
|
||||
it('should calculate subtotal, discount and total', async () => {
|
||||
vi.mocked(api.post).mockResolvedValue({
|
||||
data: { discountValue: 0.1 }
|
||||
});
|
||||
|
||||
it('should calculate subtotal, discount and total', () => {
|
||||
const store = useCartStore.getState();
|
||||
store.addItem(mockProduct, 2); // 2 * 1000 = 2000
|
||||
store.applyCoupon('CANINO2024'); // 10% discount
|
||||
await store.applyCoupon('CANINA10'); // 10% discount
|
||||
|
||||
expect(useCartStore.getState().getSubtotal()).toBe(2000);
|
||||
expect(useCartStore.getState().getDiscount()).toBe(200);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user