feat: add PATCH /projects/{id} for partial updates
- Added PATCH endpoint for projects (supports name and/or description)
- Added test_patch_project test case
- Verify folder_id already supported in POST /api/v1/projects/{project_id}/documents
This commit is contained in:
@@ -96,6 +96,36 @@ async def update_project(
|
||||
return ProjectResponse.model_validate(project)
|
||||
|
||||
|
||||
@router.patch("/{project_id}", response_model=ProjectResponse)
|
||||
async def patch_project(
|
||||
request: Request,
|
||||
project_id: str,
|
||||
payload: ProjectUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Partial update of project name and/or description."""
|
||||
agent = await get_current_agent(request, db)
|
||||
result = await db.execute(
|
||||
select(Project).where(
|
||||
Project.id == project_id,
|
||||
Project.agent_id == agent.id,
|
||||
Project.is_deleted == False,
|
||||
)
|
||||
)
|
||||
project = result.scalar_one_or_none()
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
|
||||
if payload.name is not None:
|
||||
project.name = payload.name
|
||||
if payload.description is not None:
|
||||
project.description = payload.description
|
||||
project.updated_at = datetime.utcnow()
|
||||
|
||||
await db.flush()
|
||||
return ProjectResponse.model_validate(project)
|
||||
|
||||
|
||||
@router.delete("/{project_id}", status_code=204)
|
||||
async def delete_project(
|
||||
request: Request,
|
||||
|
||||
@@ -62,6 +62,40 @@ async def test_update_project(client):
|
||||
assert response.json()["name"] == "Updated"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_patch_project(client):
|
||||
"""Test PATCH endpoint for partial project update."""
|
||||
token = await get_token(client)
|
||||
create_resp = await client.post(
|
||||
"/api/v1/projects",
|
||||
json={"name": "Original", "description": "Original desc"},
|
||||
headers={"Authorization": f"Bearer {token}"}
|
||||
)
|
||||
proj_id = create_resp.json()["id"]
|
||||
|
||||
# PATCH name only
|
||||
response = await client.patch(
|
||||
f"/api/v1/projects/{proj_id}",
|
||||
json={"name": "Patched Name"},
|
||||
headers={"Authorization": f"Bearer {token}"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == "Patched Name"
|
||||
assert data["description"] == "Original desc"
|
||||
|
||||
# PATCH description only
|
||||
response = await client.patch(
|
||||
f"/api/v1/projects/{proj_id}",
|
||||
json={"description": "Patched desc"},
|
||||
headers={"Authorization": f"Bearer {token}"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == "Patched Name"
|
||||
assert data["description"] == "Patched desc"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_soft_delete_project(client):
|
||||
token = await get_token(client)
|
||||
|
||||
Reference in New Issue
Block a user