DELETE /api/project?name=X — deletes the .db file */
| 1238 | |
| 1239 | /* DELETE /api/project?name=X — deletes the .db file */ |
| 1240 | static void handle_delete_project(cbm_http_server_t *srv, cbm_http_conn_t *c, |
| 1241 | const cbm_http_req_t *req) { |
| 1242 | char name[256] = {0}; |
| 1243 | if (!cbm_http_query_param(req->query, "name", name, (int)sizeof(name)) || name[0] == '\0') { |
| 1244 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"missing name\"}"); |
| 1245 | return; |
| 1246 | } |
| 1247 | |
| 1248 | char db_path[1024]; |
| 1249 | db_path_for_project(name, db_path, sizeof(db_path)); |
| 1250 | if (db_path[0] == '\0') { |
| 1251 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1252 | return; |
| 1253 | } |
| 1254 | |
| 1255 | if (unlink(db_path) != 0) { |
| 1256 | if (errno == ENOENT) { |
| 1257 | unwatch_project(srv, name); |
| 1258 | cbm_http_replyf(c, 404, g_cors_json, "{\"error\":\"project not found\"}"); |
| 1259 | return; |
| 1260 | } |
| 1261 | cbm_http_replyf(c, 500, g_cors_json, "{\"error\":\"failed to delete\"}"); |
| 1262 | return; |
| 1263 | } |
| 1264 | |
| 1265 | /* Also remove WAL and SHM files if they exist */ |
| 1266 | char wal_path[1040], shm_path[1040]; |
| 1267 | snprintf(wal_path, sizeof(wal_path), "%s-wal", db_path); |
| 1268 | snprintf(shm_path, sizeof(shm_path), "%s-shm", db_path); |
| 1269 | (void)unlink(wal_path); |
| 1270 | (void)unlink(shm_path); |
| 1271 | |
| 1272 | unwatch_project(srv, name); |
| 1273 | cbm_log_info("ui.project.deleted", "name", name); |
| 1274 | cbm_http_replyf(c, 200, g_cors_json, "{\"deleted\":true}"); |
| 1275 | } |
| 1276 | |
| 1277 | /* GET /api/project-health?name=X — checks db integrity */ |
| 1278 | static void handle_project_health(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
no test coverage detected