diff --git a/backend/src/app/features/fdata.clj b/backend/src/app/features/fdata.clj index 992d76af94..17ec7b1ec2 100644 --- a/backend/src/app/features/fdata.clj +++ b/backend/src/app/features/fdata.clj @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.exceptions :as ex] [app.common.files.helpers :as cfh] + [app.common.files.migrations :as fmg] [app.common.logging :as l] [app.common.types.path :as path] [app.db :as db] @@ -160,13 +161,7 @@ object)) (update-container [container] - ;; NOTE: if we found a pointer and it is not modified, we - ;; skip updating objects for not creating additional - ;; pointers - (if (and (pmap/pointer-map? container) - (not (pmap/modified? container))) - container - (d/update-when container :objects d/update-vals update-object)))] + (d/update-when container :objects d/update-vals update-object))] (-> file (update :data (fn [data] @@ -174,3 +169,26 @@ (update :pages-index d/update-vals update-container) (d/update-when :components d/update-vals update-container)))) (update :features conj "fdata/path-data")))) + +(defn disable-path-data + [file & _opts] + (letfn [(update-object [object] + (if (or (cfh/path-shape? object) + (cfh/bool-shape? object)) + (update object :content vec) + object)) + + (update-container [container] + (d/update-when container :objects d/update-vals update-object))] + + (when-let [conn db/*conn*] + (db/delete! conn :file-migration {:file-id (:id file) + :name "0003-convert-path-content"})) + (-> file + (update :data (fn [data] + (-> data + (update :pages-index d/update-vals update-container) + (d/update-when :components d/update-vals update-container)))) + (update :features disj "fdata/path-data") + (update :migrations disj "0003-convert-path-content") + (vary-meta update ::fmg/migrated disj "0003-convert-path-content")))) diff --git a/backend/src/app/rpc/commands/files_create.clj b/backend/src/app/rpc/commands/files_create.clj index 0502ff4872..eeafddd0ce 100644 --- a/backend/src/app/rpc/commands/files_create.clj +++ b/backend/src/app/rpc/commands/files_create.clj @@ -111,18 +111,21 @@ ::quotes/profile-id profile-id ::quotes/project-id project-id}) - ;; FIXME: IMPORTANT: this code can have race - ;; conditions, because we have no locks for updating - ;; team so, creating two files concurrently can lead - ;; to lost team features updating + ;; FIXME: IMPORTANT: this code can have race conditions, because + ;; we have no locks for updating team so, creating two files + ;; concurrently can lead to lost team features updating - ;; When newly computed features does not match exactly with - ;; the features defined on team row, we update it - (when (not= features (:features team)) - (let [features (db/create-array conn "text" features)] + (when-let [features (-> features + (set/difference (:features team)) + (set/difference cfeat/no-team-inheritable-features) + (not-empty))] + (let [features (->> features + (set/union (:features team)) + (db/create-array conn "text"))] (db/update! conn :team {:features features} - {:id team-id}))) + {:id (:id team)} + {::db/return-keys false}))) (-> (create-file cfg params) (vary-meta assoc ::audit/props {:team-id team-id})))) diff --git a/backend/src/app/rpc/commands/files_update.clj b/backend/src/app/rpc/commands/files_update.clj index 73b4afd3d8..866e67b1f5 100644 --- a/backend/src/app/rpc/commands/files_update.clj +++ b/backend/src/app/rpc/commands/files_update.clj @@ -177,12 +177,19 @@ :stored-revn (:revn file)})) ;; When newly computed features does not match exactly with - ;; the features defined on team row, we update it. - (when (not= features (:features team)) - (let [features (db/create-array conn "text" features)] + ;; the features defined on team row, we update it + (when-let [features (-> features + (set/difference (:features team)) + (set/difference cfeat/no-team-inheritable-features) + (not-empty))] + (let [features (->> features + (set/union (:features team)) + (db/create-array conn "text"))] (db/update! conn :team {:features features} - {:id (:id team)}))) + {:id (:id team)} + {::db/return-keys false}))) + (mtx/run! metrics {:id :update-file-changes :inc (count changes)}) diff --git a/common/src/app/common/features.cljc b/common/src/app/common/features.cljc index 11177f56c3..5665a9b434 100644 --- a/common/src/app/common/features.cljc +++ b/common/src/app/common/features.cljc @@ -59,12 +59,18 @@ ;; A set of features enabled by default (def default-features #{"fdata/shape-data-type" + "fdata/path-data" "styles/v2" "layout/grid" "components/v2" "plugins/runtime" "design-tokens/v1"}) +;; A set of features that should not be propagated to team on creating +;; or modifying a file +(def no-team-inheritable-features + #{"fdata/path-data"}) + ;; A set of features which only affects on frontend and can be enabled ;; and disabled freely by the user any time. This features does not ;; persist on file features field but can be permanently enabled on diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index 2d738fbfc5..46e20537c7 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -1309,6 +1309,8 @@ (defmethod migrate-data "0003-convert-path-content" [data _] + (some-> cfeat/*new* (swap! conj "fdata/path-data")) + (letfn [(update-object [object] (if (or (cfh/bool-shape? object) (cfh/path-shape? object))