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:
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user