I wrote this function to update backlinks and file names on a node-name change. It’s messy and I haven’t tested it much, but maybe it’s a start:
(defun azr/org-roam-modify-title ()
"Modify title of org-roam current node and update all backlinks in roam database."
(interactive)
(unless (org-roam-buffer-p) (error "Not in an org-roam buffer."))
(save-some-buffers t)
(let* ((old-title (org-roam-get-keyword "title"))
(ID (org-entry-get (point) "ID"))
(new-title (read-string "Enter new title: " old-title)))
(org-roam-set-keyword "title" new-title)
(save-buffer)
(let* ((new-slug (org-roam-node-slug (org-roam-node-at-point)))
(new-file-name (replace-regexp-in-string "-.*\\.org" (format "-%s.org" new-slug) (buffer-file-name)))
(new-buffer-name (file-name-nondirectory new-file-name)))
(rename-buffer new-buffer-name)
(rename-file (buffer-file-name) new-file-name 1)
(set-visited-file-name new-file-name)) ; I don't know why this last command is necessary. Getting it from here: https://stackoverflow.com/a/384346/2422698
(save-buffer)
;; Rename backlinks in the rest of the Org-roam database.
(let* ((search (format "[[id:%s][%s]]" ID old-title))
(replace (format "[[id:%s][%s]]" ID new-title))
(rg-command (format "rg -t org -lF %s ~/Org/roam/" search))
(file-list (split-string (shell-command-to-string rg-command))))
(dolist (file file-list)
(let ((file-open (get-file-buffer file)))
(find-file file)
(beginning-of-buffer)
(while (search-forward search nil t)
(replace-match replace))
(save-buffer)
(unless file-open
(kill-buffer)))))))