fix(sync-api): normalizar client_updated_at ISO-8601 a datetime MySQL
La app envía client_updated_at como ISO-8601 con milisegundos y Z (2026-07-21T10:10:25.006Z). MySQL rechaza ese literal en columnas DATETIME/TIMESTAMP → SQLSTATE[22007] y la operación /sync fallaba (inspection.create, etc.). Se normaliza con Carbon a 'Y-m-d H:i:s' en la zona horaria de la app, una sola vez en handle(), antes de cada handler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,20 @@ class SyncController extends Controller
|
|||||||
{
|
{
|
||||||
$uuid = $op['uuid'];
|
$uuid = $op['uuid'];
|
||||||
|
|
||||||
|
// The client sends `client_updated_at` as ISO-8601 with milliseconds and a
|
||||||
|
// trailing Z (e.g. 2026-07-21T10:10:25.006Z). MySQL's DATETIME/TIMESTAMP
|
||||||
|
// columns reject that literal, so normalise it to `Y-m-d H:i:s` (UTC) once
|
||||||
|
// here, before it reaches any handler. Invalid/empty values become null.
|
||||||
|
if (! empty($op['client_updated_at'])) {
|
||||||
|
try {
|
||||||
|
$op['client_updated_at'] = Carbon::parse($op['client_updated_at'])
|
||||||
|
->timezone(config('app.timezone'))
|
||||||
|
->format('Y-m-d H:i:s');
|
||||||
|
} catch (\Throwable) {
|
||||||
|
$op['client_updated_at'] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Op-level idempotency: if this operation was already applied, replay its result.
|
// Op-level idempotency: if this operation was already applied, replay its result.
|
||||||
$prior = SyncLog::where('op_uuid', $uuid)
|
$prior = SyncLog::where('op_uuid', $uuid)
|
||||||
->where('entity', $op['entity'])->where('op', $op['op'])->first();
|
->where('entity', $op['entity'])->where('op', $op['op'])->first();
|
||||||
|
|||||||
Reference in New Issue
Block a user