user()->events()->orderBy('date'); // Delta sync: only events updated since a given timestamp if ($request->has('since')) { $since = $request->date('since'); $query->where('updated_at', '>', $since); } // Cursor-based pagination (default 50, max 200) $limit = min((int) $request->input('limit', 50), 200); return EventResource::collection( $query->cursorPaginate($limit) ); } /** * POST /api/events */ public function store(StoreEventRequest $request): JsonResponse { $event = $request->user()->events()->create([ 'client_id' => $request->validated('id'), 'title' => $request->validated('title'), 'date' => $request->validated('date'), 'emotion' => $request->validated('emotion'), 'custom_color' => $request->validated('customColor'), 'gradient_preset' => $request->validated('gradientPreset'), 'image' => $request->validated('image'), 'note' => $request->validated('note'), ]); return (new EventResource($event)) ->response() ->setStatusCode(201); } /** * GET /api/events/{clientId} */ public function show(Request $request, string $clientId): EventResource { $event = $request->user()->events() ->where('client_id', $clientId) ->firstOrFail(); return new EventResource($event); } /** * PUT /api/events/{clientId} */ public function update(UpdateEventRequest $request, string $clientId): EventResource { $event = $request->user()->events() ->where('client_id', $clientId) ->firstOrFail(); $data = []; $validated = $request->validated(); if (isset($validated['title'])) { $data['title'] = $validated['title']; } if (isset($validated['date'])) { $data['date'] = $validated['date']; } if (isset($validated['emotion'])) { $data['emotion'] = $validated['emotion']; } if (array_key_exists('customColor', $validated)) { $data['custom_color'] = $validated['customColor']; } if (array_key_exists('gradientPreset', $validated)) { $data['gradient_preset'] = $validated['gradientPreset']; } if (array_key_exists('image', $validated)) { $data['image'] = $validated['image']; } if (array_key_exists('note', $validated)) { $data['note'] = $validated['note']; } $event->update($data); return new EventResource($event->fresh()); } /** * DELETE /api/events/{clientId} */ public function destroy(Request $request, string $clientId): JsonResponse { $event = $request->user()->events() ->where('client_id', $clientId) ->firstOrFail(); $event->delete(); return response()->json(null, 204); } /** * POST /api/events/sync * Batch sync: process multiple mutations in one request. */ public function sync(Request $request): JsonResponse { $request->validate([ 'mutations' => ['required', 'array', 'max:100'], 'mutations.*.action' => ['required', 'in:create,update,delete'], 'mutations.*.eventId' => ['required', 'uuid'], 'mutations.*.payload' => ['nullable', 'array'], ]); $user = $request->user(); $results = []; foreach ($request->input('mutations') as $mutation) { $action = $mutation['action']; $clientId = $mutation['eventId']; $payload = $mutation['payload'] ?? []; try { if ($action === 'create') { $event = $user->events()->where('client_id', $clientId)->first(); if (! $event) { $event = $user->events()->create([ 'client_id' => $clientId, 'title' => $payload['title'] ?? 'Untitled', 'date' => $payload['date'] ?? now()->format('Y-m-d'), 'emotion' => $payload['emotion'] ?? 0, 'custom_color' => $payload['customColor'] ?? null, 'gradient_preset' => $payload['gradientPreset'] ?? null, 'image' => $payload['image'] ?? null, 'note' => $payload['note'] ?? null, ]); } $results[] = ['eventId' => $clientId, 'status' => 'ok']; } elseif ($action === 'update') { $event = $user->events()->where('client_id', $clientId)->first(); if ($event) { $data = []; if (isset($payload['title'])) { $data['title'] = $payload['title']; } if (isset($payload['date'])) { $data['date'] = $payload['date']; } if (isset($payload['emotion'])) { $data['emotion'] = $payload['emotion']; } if (array_key_exists('customColor', $payload)) { $data['custom_color'] = $payload['customColor']; } if (array_key_exists('gradientPreset', $payload)) { $data['gradient_preset'] = $payload['gradientPreset']; } if (array_key_exists('image', $payload)) { $data['image'] = $payload['image']; } if (array_key_exists('note', $payload)) { $data['note'] = $payload['note']; } $event->update($data); } $results[] = ['eventId' => $clientId, 'status' => 'ok']; } elseif ($action === 'delete') { $user->events()->where('client_id', $clientId)->delete(); $results[] = ['eventId' => $clientId, 'status' => 'ok']; } } catch (\Throwable $e) { $results[] = ['eventId' => $clientId, 'status' => 'error', 'message' => $e->getMessage()]; } } return response()->json(['results' => $results]); } }