validate([ 'action' => 'required|in:progress_update,inspection,feature_create,media_upload,task_complete', 'payload' => 'required|array', ]); $pending = PendingSync::create([ 'user_id' => Auth::id() ?? 1, 'action' => $payload['action'], 'payload' => $payload['payload'], ]); return response()->json(['queued' => true]); } public function sync(Request $request) { $user = Auth::user(); $pendings = PendingSync::where('user_id', $user->id)->whereNull('synced_at')->get(); $results = []; foreach ($pendings as $pending) { $result = ['id' => $pending->id, 'action' => $pending->action, 'success' => false, 'error' => null]; try { if ($pending->action === 'progress_update') { $phase = Phase::find($pending->payload['phase_id']); if ($phase) { $phase->progress_percent = $pending->payload['progress']; $phase->save(); $phase->progressUpdates()->create([ 'user_id' => $user->id, 'progress_percent' => $pending->payload['progress'], 'comment' => $pending->payload['comment'] ?? '', 'location' => $pending->payload['location'] ?? null, ]); } $result['success'] = true; } elseif ($pending->action === 'inspection') { $inspection = Inspection::create($pending->payload); $result['success'] = true; $result['data'] = ['inspection_id' => $inspection->id]; } elseif ($pending->action === 'feature_create') { $feature = Feature::create($pending->payload); $result['success'] = true; $result['data'] = ['feature_id' => $feature->id]; } elseif ($pending->action === 'media_upload') { // Assuming payload has: 'file' (base64), 'path', 'model_type', 'model_id' // We'll decode the base64 and store the file if (isset($pending->payload['file'], $pending->payload['path'])) { $decoded = base64_decode($pending->payload['file']); if ($decoded !== false) { $path = Storage::put($pending->payload['path'], $decoded); // Attach to model if model_type and model_id are provided if (isset($pending->payload['model_type'], $pending->payload['model_id'])) { $model = new $pending->payload['model_type']; $model = $model->find($pending->payload['model_id']); if ($model) { $model->media()->create([ 'name' => $pending->payload['name'] ?? 'unnamed', 'path' => $path, 'mime_type' => $pending->payload['mime_type'] ?? 'application/octet-stream', 'disk' => 'public', ]); } } $result['success'] = true; $result['data'] = ['path' => $path]; } else { $result['error'] = 'Failed to decode base64 file'; } } else { $result['error'] = 'Missing file or path in payload'; } } elseif ($pending->action === 'task_complete') { // Example: mark a task as complete (you can adjust as needed) // For now, just log and mark as success \Log::info('Task completed offline', $pending->payload); $result['success'] = true; } else { $result['error'] = 'Unknown action type'; } } catch (\Exception $e) { $result['error'] = $e->getMessage(); } if ($result['success']) { $pending->synced_at = now(); $pending->save(); } $results[] = $result; } return response()->json(['synced' => $results]); } }