fix(settings): PHP sync for runtime can_edit after deploy
Force can_edit=1 for Montzar/price runtime keys via settings:deploy and settings:sync-runtime-can-edit, so tenant DB stays correct even when an older deploy SQL is still on the server. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\SettingsRuntimeCanEditSync;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
@@ -100,6 +101,8 @@ class DeploySettingsConstCommand extends Command
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->syncRuntimeCanEdit($db);
|
||||
|
||||
$this->info(" done: {$db}");
|
||||
}
|
||||
|
||||
@@ -129,6 +132,38 @@ class DeploySettingsConstCommand extends Command
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function syncRuntimeCanEdit(string $database): void
|
||||
{
|
||||
try {
|
||||
$sync = app(SettingsRuntimeCanEditSync::class);
|
||||
$sync->useDatabase($database);
|
||||
$updated = $sync->sync();
|
||||
$this->line(" runtime can_edit sync: {$updated} row(s) updated");
|
||||
|
||||
$status = $sync->statusMap();
|
||||
if ($status !== []) {
|
||||
$preview = collect($status)
|
||||
->map(fn ($canEdit, $key) => "{$key}={$canEdit}")
|
||||
->implode(', ');
|
||||
$this->line(" runtime keys: {$preview}");
|
||||
}
|
||||
|
||||
$violations = $sync->violations();
|
||||
if ($violations !== []) {
|
||||
$this->warn(' WARN: runtime keys still can_edit≠1: '.implode(', ', array_keys($violations)));
|
||||
}
|
||||
|
||||
$fee = \App\Models\Setting::query()
|
||||
->where('key', 'fee_deduct_from_gold')
|
||||
->first(['key', 'can_edit']);
|
||||
if ($fee) {
|
||||
$this->line(" check fee_deduct_from_gold can_edit={$fee->can_edit}");
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->warn(' runtime can_edit sync skipped: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function findMysqlBinary(): ?string
|
||||
{
|
||||
$process = new Process(['command', '-v', 'mysql']);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\SettingsRuntimeCanEditSync;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncRuntimeSettingsCanEditCommand extends Command
|
||||
{
|
||||
protected $signature = 'settings:sync-runtime-can-edit
|
||||
{database? : نام دیتابیس (پیشفرض DB_DATABASE)}';
|
||||
|
||||
protected $description = 'تثبیت can_edit=1 برای کلیدهای runtime tenant (Montzar، up/down_price، …)';
|
||||
|
||||
public function handle(SettingsRuntimeCanEditSync $sync): int
|
||||
{
|
||||
$database = trim((string) ($this->argument('database') ?: config('database.connections.'.config('database.default').'.database', '')));
|
||||
if ($database === '') {
|
||||
$this->error('DB_DATABASE خالی است یا database را بدهید.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$sync->useDatabase($database);
|
||||
$updated = $sync->sync();
|
||||
$this->info("DB {$database}: {$updated} row(s) updated");
|
||||
|
||||
foreach ($sync->statusMap() as $key => $canEdit) {
|
||||
$this->line(" {$key} => can_edit={$canEdit}");
|
||||
}
|
||||
|
||||
$violations = $sync->violations();
|
||||
if ($violations !== []) {
|
||||
$this->error('هنوز can_edit≠1: '.implode(', ', array_keys($violations)));
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info('OK — همه کلیدهای runtime can_edit=1');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* تثبیت can_edit=1 برای کلیدهای runtime tenant (Montzar، up/down_price، …).
|
||||
* بعد از deploy_settings_const.sql هم اجرا میشود تا حتی با SQL قدیمی روی سرور درست بماند.
|
||||
*/
|
||||
class SettingsRuntimeCanEditSync
|
||||
{
|
||||
/** @return list<string> */
|
||||
public function keys(): array
|
||||
{
|
||||
return SuperAdminProgramSettingsOverlay::RUNTIME_KEYS;
|
||||
}
|
||||
|
||||
public function sync(): int
|
||||
{
|
||||
$keys = $this->keys();
|
||||
if ($keys === []) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Setting::query()
|
||||
->whereIn('key', $keys)
|
||||
->where(function ($query) {
|
||||
$query->where('can_edit', '!=', 1)
|
||||
->orWhereNull('can_edit');
|
||||
})
|
||||
->update(['can_edit' => 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed> key => can_edit for rows still not 1
|
||||
*/
|
||||
public function violations(): array
|
||||
{
|
||||
$keys = $this->keys();
|
||||
if ($keys === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Setting::query()
|
||||
->whereIn('key', $keys)
|
||||
->where(function ($query) {
|
||||
$query->where('can_edit', '!=', 1)
|
||||
->orWhereNull('can_edit');
|
||||
})
|
||||
->orderBy('key')
|
||||
->pluck('can_edit', 'key')
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed> key => can_edit for all runtime keys present in DB
|
||||
*/
|
||||
public function statusMap(): array
|
||||
{
|
||||
return Setting::query()
|
||||
->whereIn('key', $this->keys())
|
||||
->orderBy('key')
|
||||
->pluck('can_edit', 'key')
|
||||
->all();
|
||||
}
|
||||
|
||||
public function useDatabase(string $database): void
|
||||
{
|
||||
$connection = (string) config('database.default', 'mysql');
|
||||
config(["database.connections.{$connection}.database" => $database]);
|
||||
DB::purge($connection);
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,9 @@ php artisan settings:deploy
|
||||
| `2019`/`2021` No بعد از baseline | baseline قدیمی → `fake_package_migrations.sql` |
|
||||
| `Unknown host HOST` | از `.env` بخوان نه placeholder |
|
||||
| `Unknown column 'total_referrals'` | `git pull` + `php artisan migrate` (ensure_total_referrals) |
|
||||
| `montzar_*` هنوز `can_edit=0` در Navicat | **`git pull` روی server** سپس `php artisan deploy:tenant` — باید `runtime can_edit sync` و `montzar_token=1` چاپ شود |
|
||||
| گروه Montzar در تنظیمات عادی نیست | **`git pull` + build ادمین** (`ed326a4+`) + `price_provider=montzar` در سوپرادمین |
|
||||
| کلید runtime در سوپرادمین نیست (عمدی) | API `19d28f2+` + `npm run replicas:sync`؛ web سوپرادمین هم `git pull` + build |
|
||||
| `Unknown column 'order_limit_enabled'` / محدودیت سفارش ذخیره نمیشود | `git pull` + `php artisan migrate` (ensure_products_baseline_columns) |
|
||||
| `Unknown column 'product_id'` روی `wallets` / `/customer/me` | `mysql ... < database/sql/gholaktala_upgrade.sql` سپس merge settings |
|
||||
| upgrade کامل قلک طلا | `bash database/sql/run_gholaktala_upgrade.sh` |
|
||||
|
||||
@@ -2168,6 +2168,10 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN (
|
||||
'up_price', 'down_price', 'price_extreme_date', 'do_send_liman'
|
||||
);
|
||||
|
||||
SELECT `key`, `can_edit` FROM `settings`
|
||||
WHERE `key` IN ('montzar_token', 'montzar_diff', 'montzar_open_buy')
|
||||
ORDER BY `key`;
|
||||
|
||||
COMMIT;
|
||||
|
||||
SELECT 'deploy_settings_const.sql finished' AS status;
|
||||
|
||||
@@ -1593,6 +1593,15 @@ WHERE `key` = 'accounting_provider'
|
||||
AND TRIM(COALESCE(`value`, '')) IN ('', 'none')
|
||||
AND EXISTS (SELECT 1 FROM (SELECT `value` FROM `settings` WHERE `key` = 'send_to_tahesab') AS s WHERE s.`value` IN ('true', '1', 'yes'));
|
||||
|
||||
-- آخرین override: کلیدهای runtime همیشه can_edit=1 (tenant-only)
|
||||
UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN (
|
||||
'montzar_last_product_log', 'montzar_order_response',
|
||||
'montzar_live_price', 'montzar_mazaneh', 'montzar_diff',
|
||||
'montzar_truly_buy_mazaneh', 'montzar_truly_sell_mazaneh',
|
||||
'montzar_token', 'montzar_closed',
|
||||
'up_price', 'down_price', 'price_extreme_date', 'do_send_liman'
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
SELECT 'deploy_settings_const.sql finished' AS status;
|
||||
|
||||
Reference in New Issue
Block a user