fix: SQLAlchemy JSON mutation detection for saved ideas and approved examples

SQLAlchemy doesn't detect in-place mutations on JSON columns (same object
reference). Fixed all JSON write operations to create new list/dict objects:
- save_idea: [new_idea] + old_ideas instead of ideas.insert()
- delete_idea: new filtered list
- mark_idea_used: new list with copied dicts
- approve_post: dict(examples) for content_rules

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michele
2026-04-06 02:13:23 +02:00
parent de769aca71
commit e77705d33b

View File

@@ -334,7 +334,7 @@ def approve_post(
}) })
# Keep only last 5 # Keep only last 5
examples["approved_examples"] = approved_examples[-5:] examples["approved_examples"] = approved_examples[-5:]
character.content_rules = examples character.content_rules = dict(examples) # new dict for SQLAlchemy change detection
character.updated_at = datetime.utcnow() character.updated_at = datetime.utcnow()
db.commit() db.commit()
@@ -487,7 +487,7 @@ def save_idea(
.filter(SystemSetting.key == "saved_ideas", SystemSetting.user_id == current_user.id) .filter(SystemSetting.key == "saved_ideas", SystemSetting.user_id == current_user.id)
.first() .first()
) )
ideas = setting.value if setting and isinstance(setting.value, list) else [] old_ideas = list(setting.value) if setting and isinstance(setting.value, list) else []
new_idea = { new_idea = {
"id": str(uuid.uuid4())[:8], "id": str(uuid.uuid4())[:8],
@@ -496,13 +496,13 @@ def save_idea(
"saved_at": datetime.utcnow().isoformat() + "Z", "saved_at": datetime.utcnow().isoformat() + "Z",
"used": False, "used": False,
} }
ideas.insert(0, new_idea) new_ideas = [new_idea] + old_ideas # new list — forces SQLAlchemy to detect change
if setting: if setting:
setting.value = ideas setting.value = new_ideas
setting.updated_at = datetime.utcnow() setting.updated_at = datetime.utcnow()
else: else:
db.add(SystemSetting(key="saved_ideas", value=ideas, user_id=current_user.id)) db.add(SystemSetting(key="saved_ideas", value=new_ideas, user_id=current_user.id))
db.commit() db.commit()
return new_idea return new_idea
@@ -522,11 +522,11 @@ def delete_idea(
if not setting or not isinstance(setting.value, list): if not setting or not isinstance(setting.value, list):
raise HTTPException(status_code=404, detail="Idea not found") raise HTTPException(status_code=404, detail="Idea not found")
ideas = [i for i in setting.value if i.get("id") != idea_id] new_ideas = [i for i in setting.value if i.get("id") != idea_id]
if len(ideas) == len(setting.value): if len(new_ideas) == len(setting.value):
raise HTTPException(status_code=404, detail="Idea not found") raise HTTPException(status_code=404, detail="Idea not found")
setting.value = ideas setting.value = new_ideas # new list object for SQLAlchemy change detection
setting.updated_at = datetime.utcnow() setting.updated_at = datetime.utcnow()
db.commit() db.commit()
return {"ok": True} return {"ok": True}
@@ -547,13 +547,19 @@ def mark_idea_used(
if not setting or not isinstance(setting.value, list): if not setting or not isinstance(setting.value, list):
raise HTTPException(status_code=404, detail="Idea not found") raise HTTPException(status_code=404, detail="Idea not found")
updated = []
found = False
for idea in setting.value: for idea in setting.value:
if idea.get("id") == idea_id: copy = dict(idea)
idea["used"] = True if copy.get("id") == idea_id:
break copy["used"] = True
else: found = True
updated.append(copy)
if not found:
raise HTTPException(status_code=404, detail="Idea not found") raise HTTPException(status_code=404, detail="Idea not found")
setting.value = updated # new list for SQLAlchemy change detection
setting.updated_at = datetime.utcnow() setting.updated_at = datetime.utcnow()
db.commit() db.commit()
return {"ok": True} return {"ok": True}