# GET /v2/account-history/monthly

<div id="bkmrk-" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### Route Info

<div id="bkmrk-method-endpoint-cont" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;"><table border="1" style="width: 100%; border-collapse: collapse; text-align: center;"><tbody><tr style="background: #f5f5f5; font-weight: bold;"><td>Method</td><td>Endpoint</td><td>Controller</td><td>Middleware</td></tr><tr><td>GET</td><td>/v2/account-history/monthly</td><td>AccountHistoryController@getMonthlyBalance</td><td>authWithJwt</td></tr></tbody></table>

  </div>### شرح عملکرد (Functionality)

این API برای دریافت مانده حساب **ماهانه** طراحی شده است و دارای مکانیزم هوشمند (Read-Through Cache) است:

<div id="bkmrk-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%DA%A9%D8%B4%3A-%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7-%D8%B3%D8%B9%DB%8C-" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">1. **بررسی کش:** ابتدا سعی می‌کند داده را از Redis بخواند.
2. **محاسبه خودکار (Auto-Calculation):** اگر داده در کش نباشد، سیستم به طور خودکار متد `calculateAndStoreMonthlyBalance` را اجرا می‌کند تا داده‌های آن سال تولید و ذخیره شوند.
3. **بازخوانی:** پس از محاسبه، مجدداً داده را از کش می‌خواند و برمی‌گرداند.

</div>توجه: اگر کش خالی باشد، پاسخ این سرویس ممکن است کمی طول بکشد (به اندازه زمان محاسبه مانده سالانه)

<div id="bkmrk--1" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### ورودی (Query Parameters)

```
?colleague_id=108&year=1403&month=2
```

#### قوانین اعتبارسنجی (Validation Rules)

<div id="bkmrk-colleague_id%3A-%D8%A7%D9%84%D8%B2%D8%A7%D9%85%DB%8C" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- **colleague\_id:** الزامی | integer | موجود در جدول `colleagues`.
- **year:** الزامی | integer | بازه 1300 تا 1500.
- **month:** الزامی | integer | بازه 1 تا 12 (نیاز به ارسال صفر قبل عدد نیست، سیستم خودکار Pad می‌کند).

  </div>### منطق اجرا (Execution Logic)

<div id="bkmrk-%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C-%D9%88%D8%B1%D9%88%D8%AF%DB%8C%E2%80%8C%D9%87%D8%A7." style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- اعتبارسنجی ورودی‌ها. 
    - خطا → 400 (VALIDATION\_ERROR).
- تبدیل ماه ورودی به فرمت دورقمی (مثلاً `2` به `02`).
- فراخوانی سرویس `getMonthlyBalanceFromCache`.
- **Logic داخل سرویس:**
    1. ساخت کلید Redis.
    2. چک کردن وجود کلید. اگر بود → بازگشت (Meta: `cached: true`).
    3. اگر نبود → اجرای متد محاسبه (Calculation).
    4. چک کردن مجدد Redis. اگر بود → بازگشت (Meta: `cached: false, calculated: true`).
    5. اگر باز هم نبود → بازگشت آرایه خطا (CACHE\_MISS).
- اگر خروجی سرویس حاوی `error` باشد → پاسخ **404**.
- در غیر این صورت → پاسخ **200**.

  </div>### پاسخ موفق (200 OK)

#### حالت ۱: داده در کش موجود بود (Cache Hit)

```
{
  "payload": {
    "credit": 500000,
    "debit": 0,
    "balance": 500000
  },
  "meta": {
    "colleague_id": 108,
    "year": 1403,
    "month": "02",
    "cached": true,
    "timestamp": "2025-12-01T16:00:00+03:30"
  }
}
```

#### حالت ۲: داده محاسبه شد (Cache Miss -&gt; Calculated)

```
{
  "payload": {
    "credit": 500000,
    "debit": 0,
    "balance": 500000
  },
  "meta": {
    "colleague_id": 108,
    "year": 1403,
    "month": "02",
    "cached": false,
    "calculated": true,
    "timestamp": "2025-12-01T16:00:05+03:30"
  }
}
```

<div id="bkmrk--2" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### پاسخ‌های خطا (Error Responses)

#### خطای اعتبارسنجی (400)

```
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The month must be at least 1."
  },
  "meta": { ... }
}
```

#### خطای عدم یافتن/محاسبه (404)

زمانی رخ می‌دهد که حتی پس از تلاش برای محاسبه، داده‌ای در کش ذخیره نشود.

```
{
  "error": {
    "code": "CACHE_MISS",
    "message": "Balance not found in cache and calculation failed"
  },
  "meta": {
    "colleague_id": 108,
    "year": 1403,
    "month": "02",
    "cached": false,
    "timestamp": "..."
  }
}
```

#### خطای سرور (500)

```
{
  "error": {
    "code": "INTERNAL_ERROR",
```