[verified] Harden Etsy MCP validation and scheduled token refresh
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 38s
Deploy HickLab3D Dashboard / Deploy to production (push) Successful in 38s
This commit is contained in:
@@ -26,7 +26,7 @@ class DashboardSchedule
|
||||
'name' => 'Integration cache refresh',
|
||||
'feature' => 'Integrations',
|
||||
'command' => 'integrations:refresh',
|
||||
'description' => 'Refreshes cached Etsy, Parcel2Go, BamBuddy and dryer data so dashboard pages load instantly. Migrated from the previous hard-coded schedule entry — frequency and withoutOverlapping(5) behavior unchanged.',
|
||||
'description' => 'Refreshes cached Parcel2Go, BamBuddy and dryer data. Etsy runs separately through etsy:sync; the 30-second cadence and withoutOverlapping(5) guard are unchanged.',
|
||||
'default_frequency' => 'every_30_seconds',
|
||||
'overlap_minutes' => 5,
|
||||
'manual' => true,
|
||||
@@ -46,16 +46,16 @@ class DashboardSchedule
|
||||
'command' => 'etsy:sync',
|
||||
'description' => 'Forces a fresh pull of Etsy receipts and active listings into the same IntegrationCache entries the Etsy page reads, independent of the bundled integrations:refresh job so it can be tuned or disabled on its own.',
|
||||
'default_frequency' => 'every_15_minutes',
|
||||
'overlap_minutes' => null,
|
||||
'overlap_minutes' => 5,
|
||||
'manual' => true,
|
||||
],
|
||||
'etsy_token_refresh' => [
|
||||
'name' => 'Etsy token refresh',
|
||||
'feature' => 'Etsy',
|
||||
'command' => 'etsy:refresh-token',
|
||||
'description' => 'Proactively refreshes the Etsy OAuth access token (tokens last ~1 hour) so the connection stays alive even during quiet periods with no receipts or listings activity to trigger an on-demand refresh.',
|
||||
'default_frequency' => 'every_45_minutes',
|
||||
'overlap_minutes' => null,
|
||||
'description' => 'Checks every five minutes by default and refreshes only when expiry is within ten minutes. Disabling or slowing this job can leave idle tokens expired; on-demand reads also refresh expired tokens.',
|
||||
'default_frequency' => 'every_5_minutes',
|
||||
'overlap_minutes' => 5,
|
||||
'manual' => true,
|
||||
],
|
||||
];
|
||||
@@ -104,7 +104,22 @@ class DashboardSchedule
|
||||
->all();
|
||||
|
||||
File::ensureDirectoryExists(dirname(self::runtimeSettingsPath()));
|
||||
File::put(self::runtimeSettingsPath(), json_encode($payload, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
|
||||
$lock = fopen(self::runtimeSettingsPath().'.lock', 'c');
|
||||
if ($lock === false) {
|
||||
throw new \RuntimeException('Unable to open schedule settings lock.');
|
||||
}
|
||||
try {
|
||||
if (! flock($lock, LOCK_EX)) {
|
||||
throw new \RuntimeException('Unable to lock schedule settings.');
|
||||
}
|
||||
$stored = File::exists(self::runtimeSettingsPath())
|
||||
? json_decode(File::get(self::runtimeSettingsPath()), true, 512, JSON_THROW_ON_ERROR)
|
||||
: [];
|
||||
File::replace(self::runtimeSettingsPath(), json_encode(array_replace(is_array($stored) ? $stored : [], $payload), JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
|
||||
} finally {
|
||||
flock($lock, LOCK_UN);
|
||||
fclose($lock);
|
||||
}
|
||||
}
|
||||
|
||||
public static function register(): void
|
||||
|
||||
Reference in New Issue
Block a user