| 1238 | } |
| 1239 | |
| 1240 | void DataStorageController::HandlePATCH_nodes_uid(const httplib::Request& req, httplib::Response& res) |
| 1241 | { |
| 1242 | if (!m_Bridge.HasDataStorage()) |
| 1243 | { |
| 1244 | this->SendErrorResponse(res, 503, ErrorResponse::DataStorageNotAvailable(req.path)); |
| 1245 | return; |
| 1246 | } |
| 1247 | |
| 1248 | const std::string uid = req.path_params.at("uid"); |
| 1249 | if (!ValidateUid(uid)) |
| 1250 | { |
| 1251 | this->SendErrorResponse(res, 400, ErrorResponse::InvalidRequest("Invalid UID format", req.path)); |
| 1252 | return; |
| 1253 | } |
| 1254 | |
| 1255 | // Check if node exists |
| 1256 | auto existingNode = m_Bridge.GetNode(uid); |
| 1257 | if (!existingNode.has_value()) |
| 1258 | { |
| 1259 | this->SendErrorResponse(res, 404, ErrorResponse::NodeNotFound(uid, req.path)); |
| 1260 | return; |
| 1261 | } |
| 1262 | |
| 1263 | // Parse request body |
| 1264 | nlohmann::json updates; |
| 1265 | try |
| 1266 | { |
| 1267 | updates = nlohmann::json::parse(req.body); |
| 1268 | } |
| 1269 | catch (const nlohmann::json::parse_error& e) |
| 1270 | { |
| 1271 | this->SendErrorResponse(res, 400, ErrorResponse::InvalidRequest("Invalid JSON: " + std::string(e.what()), req.path)); |
| 1272 | return; |
| 1273 | } |
| 1274 | |
| 1275 | // PATCH /nodes/{uid} only supports reparenting via "parent_uid" |
| 1276 | if (!updates.is_object() || !updates.contains("parent_uid")) |
| 1277 | { |
| 1278 | this->SendErrorResponse(res, 400, ErrorResponse::InvalidRequest( |
| 1279 | "PATCH /nodes/{uid} only supports reparenting. " |
| 1280 | "Provide 'parent_uid' in the request body (use null for root level).", req.path)); |
| 1281 | return; |
| 1282 | } |
| 1283 | |
| 1284 | // Validate parent_uid value: must be null (move to root) or an existing node UID |
| 1285 | if (!updates["parent_uid"].is_null()) |
| 1286 | { |
| 1287 | if (!updates["parent_uid"].is_string()) |
| 1288 | { |
| 1289 | this->SendErrorResponse(res, 400, ErrorResponse::InvalidRequest( |
| 1290 | "Invalid 'parent_uid': must be a string UID or null.", req.path)); |
| 1291 | return; |
| 1292 | } |
| 1293 | const std::string parentUid = updates["parent_uid"].get<std::string>(); |
| 1294 | if (!ValidateUid(parentUid)) |
| 1295 | { |
| 1296 | this->SendErrorResponse(res, 400, ErrorResponse::InvalidRequest("Invalid parent_uid format", req.path)); |
| 1297 | return; |