fix: build-edn fails to export :build/class-properties that roundtrip

When running `bb dev:cli export-edn --roundtrip` on a graph with
included test, :build/class-properties sort order kept changing
because built-in properties order is lost on export
This commit is contained in:
Gabriel Horner
2026-05-17 01:26:33 -04:00
parent 9ac459cc76
commit c89c7eaacc
3 changed files with 34 additions and 2 deletions

1
.gitignore vendored
View File

@@ -45,6 +45,7 @@ resources/electron.js
/libs/dist/
charlie/
.vscode
/.claude/settings.local.json
/.preprocessor-cljs
docker
android/app/src/main/assets/capacitor.plugin.json

View File

@@ -384,8 +384,16 @@
(into {}))
new-properties-tx (vec
(mapcat (partial build-property-tx properties' page-uuids all-idents property-db-ids class-property-orders options)
properties'))]
new-properties-tx))
properties'))
;; Apply the topological :block/order to properties that already exist in
;; the target DB (e.g. built-ins) so per-class property order survives a
;; round-trip alongside the user-defined properties built above.
existing-property-orders-tx
(->> class-property-orders
(keep (fn [[ident order]]
(when-not (contains? properties' ident)
{:db/ident ident :block/order order}))))]
(into new-properties-tx existing-property-orders-tx)))
(defn- build-class-extends [{:build/keys [class-parent class-extends]} class-db-ids]
(when-let [class-extends' (if class-parent

View File

@@ -926,6 +926,29 @@
(is (= (set original-property-history) property-history)
"Original property history equals exported property history")))
;; When a built-in property appears in :build/class-properties alongside
;; user-defined properties, the per-class order must survive a round-trip
(deftest import-graph-preserves-class-properties-order-with-built-in
(let [original-data
{:properties {:user.property/url {:logseq.property/type :default}
:user.property/about {:logseq.property/type :default}}
:classes {:user.class/UrlFirst {:build/class-properties [:user.property/url :logseq.property/status]}
:user.class/StatusFirst {:build/class-properties [:logseq.property/status :user.property/about]}}}
conn (db-test/create-conn-with-import-map original-data)
;; Simulate a UI-built graph where the user positioned :logseq.property/status
;; ahead of the user-defined properties referenced from the same classes.
_ (d/transact! conn [{:db/ident :logseq.property/status :block/order "a0"}])
export-map (sqlite-export/build-export @conn {:export-type :graph})
valid-result (sqlite-export/validate-export export-map)
_ (assert (not (:error valid-result)) "No error when importing export-map into new graph")
export-map2 (sqlite-export/build-export (:db valid-result) {:export-type :graph})]
(is (= [:logseq.property/status :user.property/about]
(get-in export-map [:classes :user.class/StatusFirst :build/class-properties]))
"Original export reflects the built-in's UI-set order")
(is (= nil
(sqlite-export/diff-exports export-map export-map2))
"No diff between original export and export after importing into a new graph")))
(deftest import-graph-with-different-property-value-cases
(let [pvalue-uuid1 (random-uuid)
original-data