# سیاست لاگ‌گذاری (Logging Policy) — Hajibot

هدف: تضمین مشاهده‌پذیری، عیب‌یابی سریع، سنجش KPI، و انطباق امنیتی. این سیاست برای همه محیط‌ها لازم‌الاجرا است و بخشی از معیار پذیرش تحویل محسوب می‌شود.

## اصول پایه
- همواره فعال: لاگ‌گذاری «هرگز» خاموش نمی‌شود. تنها سطح و نمونه‌برداری قابل تنظیم است.
- ساختاری (Structured): خروجی‌ها تا حد امکان JSON‌با کلیدهای ثابت باشند.
- حداقل‌گرایی در حساسیت: هیچ راز/توکن/سکرت/Authorization لاگ نشود؛ PII ماسک شود.
- همبستگی (Correlation): برای هر رخداد `req_id`, `user_id`, `tg_id`, `job_id`/`campaign_id` در کانتکست قرار گیرد.
- زمان‌بندی: همه زمان‌ها UTC؛ از timestamps با دقت میلی‌ثانیه استفاده شود.
- پایداری: خطاها هم با 200 پاسخ ایمن (برای وبهوک تلگرام) ثبت و رصد شوند تا از طوفان retry جلوگیری شود.
 - شفافیت محصولی: برای هر پیام ارسال‌شده به تلگرام، نتیجهٔ `telegraphOk`, `status`, و `reply_markup` لاگ شود تا مشکلات UX فوراً دیده شوند.

## سطوح و استفاده درست
- DEBUG: جزییات توسعه (نمونه‌برداری بالا)، فقط در غیرپروداکشن. در پروداکشن با Sampling محدود.
- INFO: جریان‌های خوش‌مسیر/تغییر وضعیت (created/scheduled/sent/ok).
- WARNING: انحراف قابل بازیابی (fallback فعال شد، JSON نامعتبر ولی با retry حل شد، گیت عضویت رد شد).
- ERROR: شکست عملیات/Exception سرویس بیرونی/Timeout. شامل کد/پیام، بدون استک‌تریس کامل در پروداکشن.
- CRITICAL/ALERT: رخداد P1 (نشت راز، مغایرت پرداخت، ازکارافتادگی عمده).

## کلیدهای متداول کانتکست
```json
{
  "req_id": "uuid",
  "user_id": 123,
  "tg_id": "239053159",
  "job_id": "score#2025-09-15T10:00",
  "campaign_id": 45,
  "module": "valuation|negotiation|...",
  "feature": "instant_push|view_deals|..."
}
```

## سیاست ماژول‌به‌ماژول
### 1) Telegram
- tg.webhook.received (INFO): `{update_id, kind(message|callback), chat_id}`
- tg.secret.invalid (WARNING): `{remote_ip}`
- tg.handler.exception (ERROR): `{class, message_trunc}` + `req_id`
- نکته: همیشه 200 بده، اما لاگ خطا ثبت شود.
 - tg.message.sent (INFO): `{chat_id, message_id?, reply_markup?}`
 - tg.callback.ack (INFO/WARN): `{callback_query_id, ok, description?}`

### 2) AI (Responses API + RAG)
- ai.request (DEBUG/INFO): `{model, module, has_file_search}` (بدون ورودی کامل کاربر)
- ai.response (INFO): `{response_id, latency_ms, token_in, token_out}`
- ai.validation.warn (WARNING): `{reason: invalid_json}`
- ai.retry (INFO): `{attempt}`
- ai.timeout / ai.provider.error (ERROR): `{timeout_ms|http_status|code}`

### 3) Payments (Zarinpal)
- pay.create (INFO): `{payment_id, plan_id, amount_irr, authority}`
- pay.verify.ok (INFO): `{payment_id, authority, ref}`
- pay.verify.failed (WARNING): `{authority, reason}`
- pay.reconcile.closed (INFO): `{count}`
- ممنوع: هرگونه اطلاعات کارت/کاربر درگاه، یا توکن بازرگان.

### 4) Ads Ingestion & Scoring
- ads.pull.ok (INFO): `{source, count}` | ads.pull.err (ERROR): `{source, code}`
- ads.normalize.rejected (WARNING): `{reason, code?, city?}`
- ads.score.persist (INFO): `{items, under_median_15pct: n, fallback_10pct: n}`

### 5) Push & CTR
- push.schedule (INFO): `{campaign_id, segment_size}`
- push.send.ok/err (INFO/WARNING): `{sent, failed}`
- push.delivered (INFO): `{delivery_count}`
- push.click (INFO): `{push_log_id}` + وقایع `ViewDeal`, `CallFromCard` (INFO)

### 6) Growth (Entitlements & Quotas)
- quota.consume.ok (INFO): `{key, period, used, remaining}`
- quota.consume.deny (WARNING): `{key, period, remaining:0}` (همراه پیام ارتقا)

### 7) Admin & RBAC
- admin.login (INFO): `{actor_id}`
- admin.action (INFO): `{actor_id, resource, action}` (بدون payload حساس)

## PII و امنیت
- شماره موبایل: در لاگ ماسک/هش شود (`+98******1234`).
- نام کاربر: لاگ نشود؛ شناسه کافی است (`user_id`, `tg_id`).
- Token/Secret: هرگز لاگ نشود (حتی در DEBUG). پیش از لاگ‌گذاری header/body را پاک‌سازی کن.

## پیاده‌سازی (Laravel)
- کانتکست: `Log::withContext([...]);`
- نمونه ساختاری:
```php
Log::withContext(['req_id'=>$reqId,'user_id'=>$uid])
   ->info('ai.response', [
     'response_id'=>$rid,
     'latency_ms'=>$lat,
     'token_in'=>$tin,
     'token_out'=>$tout,
   ]);
```
- مدیریت Exception: در catch → `Log::error('ai.provider.error', ['msg'=>$e->getMessage()])` و پاسخ ایمن.
- کانال‌ها: `stack` با `daily` توصیه می‌شود؛ نگه‌داری 14 روز.

## نمونه‌برداری (Sampling)
- رخدادهای پرتکرار (ai.request/response) در پروداکشن با نسبت 1:10 ثبت شوند؛ شمارنده‌های KPI جداگانه محاسبه شوند.

## نگه‌داری و چرخه عمر
- چرخش لاگ روزانه و نگهداری 14 روز (Production). لاگ‌های حاوی PII حداکثر 7 روز.
- فشرده‌سازی و پاکسازی خودکار.

## هشدار و آلارم
- آستانه‌ها:
  - AI p80 latency > 2500ms طی 3 ساعت (WARNING/Alert)
  - Payment verify failed rate > 2% طی 24 ساعت (ALERT)
  - Ads ingestion error rate > 10% طی 1 ساعت (ALERT)
  - 5xx وبهوک تلگرام متوالی > 3 (ALERT)
- کانال آلارم: تلگرام/ایمیل ادمین (مطابق RUNBOOK).

## تست‌پذیری
- در تست‌ها از `Log::shouldReceive` استفاده شود؛ برای مسیرهای بحرانی وجود لاگ INFO/ERROR assert گردد.

## حاکمیت تغییر
- کلیدهای لاگ (مانند `ai.response`, `pay.verify.ok`) «قرارداد» محسوب می‌شوند؛ تغییر آنها نیازمند به‌روزرسانی این سند و تست‌هاست.
- هر PR که رفتار بیرونی/اینترفیس/Job را تغییر می‌دهد، باید بررسی اثر بر لاگ‌ها و KPI را هم شامل شود.

---

به‌صراحت: «تا زمانی که خلاف آن دستور داده نشود، سیستم لاگ باید کامل، دقیق و فعال باشد و خاموش نشود.»
