fix(settings): drop program-settings last-good cache and prefer montzar

Stale Redis overlay and SMS-origin-first fetch kept feature flags like customer_special_pricing false after SuperAdmin turned them on. Always fetch live and try adm.montzar.ir first.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-29 22:39:08 +03:30
co-authored by Cursor
parent cecb84bad9
commit 63195718a2
4 changed files with 66 additions and 73 deletions
@@ -2,22 +2,12 @@
namespace App\Services;
use Illuminate\Support\Facades\Cache;
/**
* تنظیمات پیشرفته سوپرادمین برای ConfigService و get_settings.
* در هر درخواست یک بار fetch می‌شود؛ آخرین پاسخ سالم برای قطعی لحظه‌ای کش می‌ماند.
* هر درخواست HTTP یک بار از سوپرادمین می‌خواند (memo فقط داخل همان درخواست) — بدون کش Redis.
*/
class SuperAdminProgramSettingsOverlay
{
/**
* آخرین پاسخ سالم سوپرادمین — فقط کلیدهای دسترسی (SUPERADMIN_OWNED_KEYS).
* پاسخ remote ممکن است کلیدهای دیگری هم داشته باشد؛ آن‌ها ذخیره و اعمال نمی‌شوند.
*/
private const LAST_GOOD_CACHE_KEY = 'superadmin:program_settings:last_good';
private const LAST_GOOD_CACHE_MINUTES = 1440;
/**
* فقط این ۱۴ دسترسی از سوپرادمین خوانده می‌شود.
* هر کلید دیگری (قیمت، ساعت کاری، برندینگ، …) مال پنل خانگی است.
@@ -73,26 +63,22 @@ class SuperAdminProgramSettingsOverlay
private static bool $loaded = false;
/** پاک کردن کش last-good و memo درخواست — برای دکمهٔ همگام‌سازی تنظیمات پیشرفته */
/** پاک کردن memo درخواست — برای دکمهٔ همگام‌سازی / بروزرسانی */
public function flushCache(): void
{
self::$memo = null;
self::$loaded = false;
try {
Cache::forget(self::LAST_GOOD_CACHE_KEY);
} catch (\Throwable $e) {
// کش در دسترس نیست
}
}
/**
* کش را پاک می‌کند و دوباره از سوپرادمین می‌خواند.
* دوباره از سوپرادمین می‌خواند (بدون کش پایدار).
*
* @return array{ok: bool, count: int, items: array<string, string>, source: string}
* @return array{ok: bool, count: int, items: array<string, string>, source: string, meta?: array<string, mixed>}
*/
public function refreshFromSuperAdmin(): array
{
$this->flushCache();
$client = app(SuperAdminProgramSettingsClient::class);
$map = $this->catalogMap();
if ($map === null) {
return [
@@ -100,6 +86,7 @@ class SuperAdminProgramSettingsOverlay
'count' => 0,
'items' => [],
'source' => 'unavailable',
'meta' => $client->lastFetchMeta(),
];
}
@@ -120,6 +107,7 @@ class SuperAdminProgramSettingsOverlay
'count' => count($items),
'items' => $items,
'source' => 'superadmin',
'meta' => $client->lastFetchMeta(),
];
}
@@ -170,17 +158,6 @@ class SuperAdminProgramSettingsOverlay
$items = app(SuperAdminProgramSettingsClient::class)->fetchItems();
if ($items !== null) {
$this->rememberLastGood($items);
} else {
$items = $this->lastGoodItems();
if ($items !== null) {
\Illuminate\Support\Facades\Log::warning('SuperAdmin program-settings using last-good cache', [
'count' => count($items),
]);
}
}
if ($items === null) {
self::$memo = null;
@@ -216,39 +193,6 @@ class SuperAdminProgramSettingsOverlay
return $map;
}
/** @param array<int, array<string, mixed>> $items */
private function rememberLastGood(array $items): void
{
$owned = array_values(self::ownedItemsMap($items));
if ($owned === []) {
return;
}
try {
Cache::put(
self::LAST_GOOD_CACHE_KEY,
$owned,
now()->addMinutes(self::LAST_GOOD_CACHE_MINUTES)
);
} catch (\Throwable $e) {
// کش در دسترس نیست — همان رفتار قبلی
}
}
/**
* @return array<int, array<string, mixed>>|null
*/
private function lastGoodItems(): ?array
{
try {
$cached = Cache::get(self::LAST_GOOD_CACHE_KEY);
} catch (\Throwable $e) {
return null;
}
return is_array($cached) && $cached !== [] ? $cached : null;
}
/**
* @return array<int, array<string, mixed>>
*/