feat(coderd): add task prompt modification endpoint (#20811)

This PR adds the backend implementation for modifying task prompts. Part
of https://github.com/coder/internal/issues/1084

## Changes

- New `UpdateTaskPrompt` database query to update task prompts
- New PATCH `/api/v2/tasks/{task}/prompt` endpoint

## Notes

This is part 1 of a 2-part PR stack. The frontend UI will be added in a
follow-up PR based on this branch
(https://github.com/coder/coder/pull/20812).

---

🤖 PR was written by Claude Sonnet 4.5 Thinking using [Coder
Mux](https://github.com/coder/cmux) and reviewed by a human 👩
This commit is contained in:
Danielle Maywood
2025-11-25 11:13:32 +00:00
committed by GitHub
parent afd40436f0
commit 82f525baf3
18 changed files with 659 additions and 37 deletions
+15
View File
@@ -5130,6 +5130,21 @@ func (q *querier) UpdateTailnetPeerStatusByCoordinator(ctx context.Context, arg
return q.db.UpdateTailnetPeerStatusByCoordinator(ctx, arg)
}
func (q *querier) UpdateTaskPrompt(ctx context.Context, arg database.UpdateTaskPromptParams) (database.TaskTable, error) {
// An actor is allowed to update the prompt of a task if they have
// permission to update the task (same as UpdateTaskWorkspaceID).
task, err := q.db.GetTaskByID(ctx, arg.ID)
if err != nil {
return database.TaskTable{}, err
}
if err := q.authorizeContext(ctx, policy.ActionUpdate, task.RBACObject()); err != nil {
return database.TaskTable{}, err
}
return q.db.UpdateTaskPrompt(ctx, arg)
}
func (q *querier) UpdateTaskWorkspaceID(ctx context.Context, arg database.UpdateTaskWorkspaceIDParams) (database.TaskTable, error) {
// An actor is allowed to update the workspace ID of a task if they are the
// owner of the task and workspace or have the appropriate permissions.
+16
View File
@@ -2457,6 +2457,22 @@ func (s *MethodTestSuite) TestTasks() {
check.Args(arg).Asserts(task, policy.ActionUpdate, ws, policy.ActionUpdate).Returns(database.TaskTable{})
}))
s.Run("UpdateTaskPrompt", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
task := testutil.Fake(s.T(), faker, database.Task{})
arg := database.UpdateTaskPromptParams{
ID: task.ID,
Prompt: "Updated prompt text",
}
// Create a copy of the task with the updated prompt
updatedTask := task
updatedTask.Prompt = arg.Prompt
dbm.EXPECT().GetTaskByID(gomock.Any(), task.ID).Return(task, nil).AnyTimes()
dbm.EXPECT().UpdateTaskPrompt(gomock.Any(), arg).Return(updatedTask.TaskTable(), nil).AnyTimes()
check.Args(arg).Asserts(task, policy.ActionUpdate).Returns(updatedTask.TaskTable())
}))
s.Run("GetTaskByWorkspaceID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
task := testutil.Fake(s.T(), faker, database.Task{})
task.WorkspaceID = uuid.NullUUID{UUID: uuid.New(), Valid: true}