POST /api/adr — save ADR content. Body: {"project":"...","content":"..."} */
| 819 | |
| 820 | /* POST /api/adr — save ADR content. Body: {"project":"...","content":"..."} */ |
| 821 | static void handle_adr_save(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
| 822 | if (req->body_len == 0 || req->body_len > 16384) { |
| 823 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"invalid body\"}"); |
| 824 | return; |
| 825 | } |
| 826 | |
| 827 | yyjson_doc *doc = yyjson_read(req->body, req->body_len, 0); |
| 828 | if (!doc) { |
| 829 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"invalid json\"}"); |
| 830 | return; |
| 831 | } |
| 832 | |
| 833 | yyjson_val *root = yyjson_doc_get_root(doc); |
| 834 | yyjson_val *v_proj = yyjson_obj_get(root, "project"); |
| 835 | yyjson_val *v_content = yyjson_obj_get(root, "content"); |
| 836 | if (!v_proj || !yyjson_is_str(v_proj) || !v_content || !yyjson_is_str(v_content)) { |
| 837 | yyjson_doc_free(doc); |
| 838 | cbm_http_replyf(c, 400, g_cors_json, "{\"error\":\"missing project or content\"}"); |
| 839 | return; |
| 840 | } |
| 841 | |
| 842 | const char *proj = yyjson_get_str(v_proj); |
| 843 | const char *content = yyjson_get_str(v_content); |
| 844 | |
| 845 | char db_path[1024]; |
| 846 | db_path_for_project(proj, db_path, sizeof(db_path)); |
| 847 | |
| 848 | cbm_store_t *store = cbm_store_open_path(db_path); |
| 849 | yyjson_doc_free(doc); |
| 850 | if (!store) { |
| 851 | cbm_http_replyf(c, 500, g_cors_json, "{\"error\":\"cannot open store\"}"); |
| 852 | return; |
| 853 | } |
| 854 | |
| 855 | int rc = cbm_store_adr_store(store, proj, content); |
| 856 | cbm_store_close(store); |
| 857 | |
| 858 | if (rc == CBM_STORE_OK) { |
| 859 | cbm_http_replyf(c, 200, g_cors_json, "{\"saved\":true}"); |
| 860 | } else { |
| 861 | cbm_http_replyf(c, 500, g_cors_json, "{\"error\":\"save failed\"}"); |
| 862 | } |
| 863 | } |
| 864 | |
| 865 | /* ── Background indexing ──────────────────────────────────────── */ |
| 866 |
no test coverage detected