feat(tasks): POST /api/tasks/:id/consolidate + separate body/description fields
New endpoint manually triggers a consolidation pass for a single task. Bypasses the auto_consolidate_tasks setting since the user is asking explicitly. Returns the task with the freshly-written body and consolidated_at timestamp. Also un-aliases description and body in the create/update task routes (was: description folded into body as legacy fallback). With separate fields under the task-as-durable-record design, both flow through as distinct kwargs to create_note / update_note.
This commit is contained in:
@@ -89,7 +89,11 @@ async def list_tasks_route():
|
|||||||
async def create_task_route():
|
async def create_task_route():
|
||||||
uid = get_current_user_id()
|
uid = get_current_user_id()
|
||||||
data = await request.get_json()
|
data = await request.get_json()
|
||||||
body = data.get("body", "") or data.get("description", "")
|
# Description (user-stated goal) and body (machine-maintained summary) are
|
||||||
|
# separate fields under the task-as-durable-record design. Don't fold one
|
||||||
|
# into the other.
|
||||||
|
body = data.get("body", "")
|
||||||
|
description = data.get("description")
|
||||||
tags = data.get("tags", [])
|
tags = data.get("tags", [])
|
||||||
|
|
||||||
due_date = parse_iso_date(data.get("due_date"), "due_date")
|
due_date = parse_iso_date(data.get("due_date"), "due_date")
|
||||||
@@ -120,6 +124,7 @@ async def create_task_route():
|
|||||||
uid,
|
uid,
|
||||||
title=data.get("title", ""),
|
title=data.get("title", ""),
|
||||||
body=body,
|
body=body,
|
||||||
|
description=description,
|
||||||
status=status,
|
status=status,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
due_date=due_date,
|
due_date=due_date,
|
||||||
@@ -178,11 +183,12 @@ async def update_task_route(task_id: int):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return jsonify({"error": f"Invalid priority: {data['priority']}"}), 400
|
return jsonify({"error": f"Invalid priority: {data['priority']}"}), 400
|
||||||
|
|
||||||
# Accept both "body" and "description" (prefer body)
|
# Body and description are distinct fields under the task-as-durable-record
|
||||||
|
# design. Don't alias one to the other.
|
||||||
if "body" in data:
|
if "body" in data:
|
||||||
fields["body"] = data["body"]
|
fields["body"] = data["body"]
|
||||||
elif "description" in data:
|
if "description" in data:
|
||||||
fields["body"] = data["description"]
|
fields["description"] = data["description"]
|
||||||
|
|
||||||
if "due_date" in data:
|
if "due_date" in data:
|
||||||
if data["due_date"]:
|
if data["due_date"]:
|
||||||
@@ -276,3 +282,25 @@ async def delete_task_route(task_id: int):
|
|||||||
if not deleted:
|
if not deleted:
|
||||||
return not_found("Task")
|
return not_found("Task")
|
||||||
return "", 204
|
return "", 204
|
||||||
|
|
||||||
|
|
||||||
|
@tasks_bp.route("/<int:task_id>/consolidate", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
async def consolidate_task_route(task_id: int):
|
||||||
|
"""Manually trigger a consolidation pass for a task.
|
||||||
|
|
||||||
|
Bypasses the auto_consolidate_tasks setting (the user is asking
|
||||||
|
explicitly). Returns the task's updated state including the freshly-
|
||||||
|
written body and consolidated_at timestamp.
|
||||||
|
"""
|
||||||
|
uid = get_current_user_id()
|
||||||
|
if not await can_write_note(uid, task_id):
|
||||||
|
return jsonify({"error": "Permission denied"}), 403
|
||||||
|
|
||||||
|
from fabledassistant.services.consolidation import consolidate_task
|
||||||
|
await consolidate_task(uid, task_id)
|
||||||
|
|
||||||
|
note = await get_note(uid, task_id)
|
||||||
|
if note is None:
|
||||||
|
return not_found("Task")
|
||||||
|
return jsonify(note.to_dict())
|
||||||
|
|||||||
Reference in New Issue
Block a user