diff --git a/.cursor/skills/abshode-domain-lookup/learned-notes.md b/.cursor/skills/abshode-domain-lookup/learned-notes.md index 5ecfc78..8a4d3ea 100644 --- a/.cursor/skills/abshode-domain-lookup/learned-notes.md +++ b/.cursor/skills/abshode-domain-lookup/learned-notes.md @@ -4,6 +4,7 @@ - YYYY-MM-DD | موضوع | مسیر فایل(ها) | نکتهٔ ۱ خطی - 2026-10-05 | شایگان حسابداری | `ConfigService::accountingProvider` همیشه shayegan + `ShayeganSyncService` | Ws: `2.180.4.172:2030` (عمومی) / `192.168.109.222:2030` (داخلی); SQL Config P-SERVER/CYPRSD04; ارسال وقتی mapping کامل باشد +- 2026-10-17 | لاگ ترافیک شایگان | `ShayeganClient::request` | `Log::info` با کلید `shayegan.http_request` / `shayegan.http_response`; رمز `***`; خاموش: setting `shayegan_log_traffic=0` - 2026-09-06 | گیفت‌کارت | `database/migrations/2026_09_06_000001_create_giftcards_tables.php` | create جداول giftcards و giftcard_codes اگر نباشند؛ drop در down ندارد - 2026-09-08 | خطای «محدودیت فیلد قیمت» در گیفت‌کارت | `app/Exceptions/Handler.php` + `GiftCardController::redeem` | پیام عمومی MySQL ۱۲۶۴ (Out of range) است؛ معمولاً `amount`/`total=count*amount` از ظرفیت ستون بیشتر است، نه باگ فرم ادمین - 2026-09-08 | widen مبلغ گیفت‌کارت | `migrations/2026_09_08_000001_widen_giftcard_amount_columns.php` + `deploy_safe_schema.sql` | `amount`/`total` → DECIMAL(20,4) تا مبالغ ≥۱۰۰ میلیون ریال جا شود diff --git a/app/Services/ShayeganClient.php b/app/Services/ShayeganClient.php index becfe4d..ec2e1da 100644 --- a/app/Services/ShayeganClient.php +++ b/app/Services/ShayeganClient.php @@ -124,6 +124,14 @@ class ShayeganClient $url = $this->endpointUrl($endpoint, $query); $timeout = max(5, $this->config->getInt('shayegan_timeout_seconds', 30)); + $this->logTraffic('request', [ + 'style' => $style, + 'endpoint' => $endpoint, + 'url' => $url, + 'timeout_seconds' => $timeout, + 'payload' => $this->redactPayload($payload), + ]); + try { $response = Http::timeout($timeout) ->withHeaders(['Content-Type' => 'application/json', 'Accept' => 'application/json']) @@ -139,34 +147,69 @@ class ShayeganClient $error = $this->extractErrorMessage($json); if ($status >= 400) { - return [ + $result = [ 'ok' => false, 'message' => $error !== '' ? $error : ('HTTP ' . $status), 'http_status' => $status, 'body' => $json, ]; + $this->logTraffic('response', [ + 'style' => $style, + 'endpoint' => $endpoint, + 'url' => $url, + 'ok' => false, + 'http_status' => $status, + 'error_message' => $error, + 'body' => $this->redactBodyForLog($json), + ]); + + return $result; } if ($error !== '') { - return [ + $result = [ 'ok' => false, 'message' => $error, 'http_status' => $status, 'body' => $json, ]; + $this->logTraffic('response', [ + 'style' => $style, + 'endpoint' => $endpoint, + 'url' => $url, + 'ok' => false, + 'http_status' => $status, + 'error_message' => $error, + 'body' => $this->redactBodyForLog($json), + ]); + + return $result; } - return [ + $result = [ 'ok' => true, 'message' => 'OK', 'http_status' => $status, 'body' => $json, ]; + $this->logTraffic('response', [ + 'style' => $style, + 'endpoint' => $endpoint, + 'url' => $url, + 'ok' => true, + 'http_status' => $status, + 'error_message' => '', + 'body' => $this->redactBodyForLog($json), + ]); + + return $result; } catch (\Illuminate\Http\Client\ConnectionException $e) { Log::warning('shayegan.timeout_or_connection', [ 'endpoint' => $endpoint, 'style' => $style, + 'url' => $url, 'message' => $e->getMessage(), + 'payload' => $this->redactPayload($payload), ]); return [ @@ -179,7 +222,10 @@ class ShayeganClient } catch (\Throwable $e) { Log::warning('shayegan.request_failed', [ 'endpoint' => $endpoint, + 'style' => $style, + 'url' => $url, 'message' => $e->getMessage(), + 'payload' => $this->redactPayload($payload), ]); return [ @@ -263,4 +309,33 @@ class ShayeganClient return $payload; } + + /** + * @param array $context + */ + private function logTraffic(string $phase, array $context): void + { + if ($this->config->getInt('shayegan_log_traffic', 1) === 0) { + return; + } + + Log::info('shayegan.http_' . $phase, $context); + } + + /** + * @param array $body + * @return array + */ + private function redactBodyForLog(array $body): array + { + if (isset($body['Result']) && is_array($body['Result'])) { + $count = count($body['Result']); + $body['Result'] = array_slice($body['Result'], 0, 2); + if ($count > 2) { + $body['Result_truncated'] = $count - 2; + } + } + + return $body; + } }