From 3ee7b74152afe0f26e9f7fd7d60c84ae82874a60 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sat, 21 Mar 2026 23:15:08 +1300 Subject: [PATCH] fix(api): stabilize palette and preset endpoints Made-with: Cursor --- src/controllers/palette.py | 19 +++++++------------ src/controllers/preset.py | 39 ++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/controllers/palette.py b/src/controllers/palette.py index fd1d9c7..8a42218 100644 --- a/src/controllers/palette.py +++ b/src/controllers/palette.py @@ -17,9 +17,9 @@ async def list_palettes(request): @controller.get('/') async def get_palette(request, id): """Get a specific palette by ID.""" - palette = palettes.read(id) - if palette: - return json.dumps({"colors": palette, "id": str(id)}), 200, {'Content-Type': 'application/json'} + if str(id) in palettes: + palette = palettes.read(id) + return json.dumps({"colors": palette or [], "id": str(id)}), 200, {'Content-Type': 'application/json'} return json.dumps({"error": "Palette not found"}), 404 @controller.post('') @@ -30,11 +30,8 @@ async def create_palette(request): colors = data.get("colors", None) # Palette no longer needs a name; only colors are stored. palette_id = palettes.create("", colors) - palette = palettes.read(palette_id) or {} - # Include the ID in the response payload so clients can link it. - palette_with_id = {"id": str(palette_id)} - palette_with_id.update(palette) - return json.dumps(palette_with_id), 201, {'Content-Type': 'application/json'} + created_colors = palettes.read(palette_id) or [] + return json.dumps({"id": str(palette_id), "colors": created_colors}), 201, {'Content-Type': 'application/json'} except Exception as e: return json.dumps({"error": str(e)}), 400 @@ -47,10 +44,8 @@ async def update_palette(request, id): if "name" in data: data.pop("name", None) if palettes.update(id, data): - palette = palettes.read(id) or {} - palette_with_id = {"id": str(id)} - palette_with_id.update(palette) - return json.dumps(palette_with_id), 200, {'Content-Type': 'application/json'} + colors = palettes.read(id) or [] + return json.dumps({"id": str(id), "colors": colors}), 200, {'Content-Type': 'application/json'} return json.dumps({"error": "Palette not found"}), 404 except Exception as e: return json.dumps({"error": str(e)}), 400 diff --git a/src/controllers/preset.py b/src/controllers/preset.py index c31a90e..e263af2 100644 --- a/src/controllers/preset.py +++ b/src/controllers/preset.py @@ -36,11 +36,11 @@ async def list_presets(request, session): } return json.dumps(scoped), 200, {'Content-Type': 'application/json'} -@controller.get('/') +@controller.get('/') @with_session -async def get_preset(request, id, session): +async def get_preset(request, session, preset_id): """Get a specific preset by ID (current profile only).""" - preset = presets.read(id) + preset = presets.read(preset_id) current_profile_id = get_current_profile_id(session) if preset and str(preset.get("profile_id")) == str(current_profile_id): return json.dumps(preset), 200, {'Content-Type': 'application/json'} @@ -70,12 +70,12 @@ async def create_preset(request, session): except Exception as e: return json.dumps({"error": str(e)}), 400 -@controller.put('/') +@controller.put('/') @with_session -async def update_preset(request, id, session): +async def update_preset(request, session, preset_id): """Update an existing preset (current profile only).""" try: - preset = presets.read(id) + preset = presets.read(preset_id) current_profile_id = get_current_profile_id(session) if not preset or str(preset.get("profile_id")) != str(current_profile_id): return json.dumps({"error": "Preset not found"}), 404 @@ -87,21 +87,36 @@ async def update_preset(request, id, session): data = {} data = dict(data) data["profile_id"] = str(current_profile_id) - if presets.update(id, data): - return json.dumps(presets.read(id)), 200, {'Content-Type': 'application/json'} + if presets.update(preset_id, data): + return json.dumps(presets.read(preset_id)), 200, {'Content-Type': 'application/json'} return json.dumps({"error": "Preset not found"}), 404 except Exception as e: return json.dumps({"error": str(e)}), 400 -@controller.delete('/') +@controller.delete('/') @with_session -async def delete_preset(request, id, session): +async def delete_preset(request, *args, **kwargs): """Delete a preset (current profile only).""" - preset = presets.read(id) + # Be tolerant of wrapper/arg-order variations. + session = None + preset_id = None + if len(args) > 0: + session = args[0] + if len(args) > 1: + preset_id = args[1] + if 'session' in kwargs and kwargs.get('session') is not None: + session = kwargs.get('session') + if 'preset_id' in kwargs and kwargs.get('preset_id') is not None: + preset_id = kwargs.get('preset_id') + if 'id' in kwargs and kwargs.get('id') is not None and preset_id is None: + preset_id = kwargs.get('id') + if preset_id is None: + return json.dumps({"error": "Preset ID is required"}), 400 + preset = presets.read(preset_id) current_profile_id = get_current_profile_id(session) if not preset or str(preset.get("profile_id")) != str(current_profile_id): return json.dumps({"error": "Preset not found"}), 404 - if presets.delete(id): + if presets.delete(preset_id): return json.dumps({"message": "Preset deleted successfully"}), 200 return json.dumps({"error": "Preset not found"}), 404