// POST /api/tasks/update — Modify a task // Body: {"id":1, "title":"...", "due_date":..., "completed":true} // All fields except "id" are optional #include "cJSON.h" #include "esp_http_server.h" #include "todo.hpp" #include "types.hpp" internal esp_err_t api_tasks_update_handler(httpd_req_t *req) { httpd_resp_set_type(req, "application/json"); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); char buf[256]; int received = httpd_req_recv(req, buf, sizeof(buf) - 1); if (received <= 0) { httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body"); return ESP_FAIL; } buf[received] = '\0'; cJSON *body = cJSON_Parse(buf); if (!body) { httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); return ESP_FAIL; } cJSON *id_item = cJSON_GetObjectItem(body, "id"); if (!cJSON_IsNumber(id_item)) { cJSON_Delete(body); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing 'id'"); return ESP_FAIL; } task_t *task = find_task((uint16)id_item->valueint); if (!task) { cJSON_Delete(body); httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Task not found"); return ESP_FAIL; } // Update fields if present cJSON *title_item = cJSON_GetObjectItem(body, "title"); if (cJSON_IsString(title_item)) { strlcpy(task->title, title_item->valuestring, sizeof(task->title)); } cJSON *due_date_item = cJSON_GetObjectItem(body, "due_date"); if (cJSON_IsNumber(due_date_item)) { task->due_date = (int64)due_date_item->valuedouble; } cJSON *completed_item = cJSON_GetObjectItem(body, "completed"); if (cJSON_IsBool(completed_item)) { task->completed = cJSON_IsTrue(completed_item); } cJSON_Delete(body); httpd_resp_sendstr(req, "{\"status\":\"ok\"}"); return ESP_OK; } internal const httpd_uri_t api_tasks_update_uri = {.uri = "/api/tasks/update", .method = HTTP_POST, .handler = api_tasks_update_handler, .user_ctx = NULL};