mirror of
https://github.com/penpot/penpot.git
synced 2025-04-29 21:46:21 +02:00
✨ Add dbg panel to enable a team feature flag (#5940)
* ✨ Add dbg panel to enable and disable team feature flags * 📎 Rename debug to skip-check and do not parse & cast the feature value
This commit is contained in:
parent
88669d2e0f
commit
ab7781b4fa
4 changed files with 161 additions and 38 deletions
|
@ -151,6 +151,78 @@ Debug Main Page
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<input type="submit" value="Submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="widget">
|
||||||
|
<h2>Feature Flags</h2>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Enable</legend>
|
||||||
|
<desc>Add a feature flag to a team</desc>
|
||||||
|
<form method="post" action="/dbg/actions/add-team-feature">
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" style="width:300px" name="team-id" placeholder="team-id" />
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" style="width:100px" name="feature" placeholder="feature" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="check-feature">Skip feature check</label>
|
||||||
|
<input id="check-feature" type="checkbox" name="skip-check" />
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
Do not check if the feature is supported
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="force-version">Are you sure?</label>
|
||||||
|
<input id="force-version" type="checkbox" name="force" />
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
This is a just a security double check for prevent non intentional submits.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<input type="submit" value="Submit" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Disable</legend>
|
||||||
|
<desc>Remove a feature flag from a team</desc>
|
||||||
|
<form method="post" action="/dbg/actions/remove-team-feature">
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" style="width:300px" name="team-id" placeholder="team-id" />
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" style="width:100px" name="feature" placeholder="feature" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="check-feature">Skip feature check</label>
|
||||||
|
<input id="check-feature" type="checkbox" name="skip-check" />
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
Do not check if the feature is supported
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="force-version">Are you sure?</label>
|
||||||
|
<input id="force-version" type="checkbox" name="force" />
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
This is a just a security double check for prevent non intentional submits.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<input type="submit" value="Submit" />
|
<input type="submit" value="Submit" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -430,6 +430,50 @@
|
||||||
::yres/body "OK"}))
|
::yres/body "OK"}))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- add-team-feature
|
||||||
|
[{:keys [params] :as request}]
|
||||||
|
(let [team-id (some-> params :team-id d/parse-uuid)
|
||||||
|
feature (some-> params :feature str)
|
||||||
|
skip-check (contains? params :skip-check)]
|
||||||
|
|
||||||
|
(when-not (contains? params :force)
|
||||||
|
(ex/raise :type :validation
|
||||||
|
:code :missing-force
|
||||||
|
:hint "missing force checkbox"))
|
||||||
|
|
||||||
|
(when (nil? team-id)
|
||||||
|
(ex/raise :type :validation
|
||||||
|
:code :invalid-team-id
|
||||||
|
:hint "provided invalid team id"))
|
||||||
|
|
||||||
|
(srepl/enable-team-feature! team-id feature :skip-check skip-check)
|
||||||
|
|
||||||
|
{::yres/status 200
|
||||||
|
::yres/headers {"content-type" "text/plain"}
|
||||||
|
::yres/body "OK"}))
|
||||||
|
|
||||||
|
(defn- remove-team-feature
|
||||||
|
[{:keys [params] :as request}]
|
||||||
|
(let [team-id (some-> params :team-id d/parse-uuid)
|
||||||
|
feature (some-> params :feature str)
|
||||||
|
skip-check (contains? params :skip-check)]
|
||||||
|
|
||||||
|
(when-not (contains? params :force)
|
||||||
|
(ex/raise :type :validation
|
||||||
|
:code :missing-force
|
||||||
|
:hint "missing force checkbox"))
|
||||||
|
|
||||||
|
(when (nil? team-id)
|
||||||
|
(ex/raise :type :validation
|
||||||
|
:code :invalid-team-id
|
||||||
|
:hint "provided invalid team id"))
|
||||||
|
|
||||||
|
(srepl/disable-team-feature! team-id feature :skip-check skip-check)
|
||||||
|
|
||||||
|
{::yres/status 200
|
||||||
|
::yres/headers {"content-type" "text/plain"}
|
||||||
|
::yres/body "OK"}))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; OTHER SMALL VIEWS/HANDLERS
|
;; OTHER SMALL VIEWS/HANDLERS
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -500,6 +544,10 @@
|
||||||
{:handler (partial resend-email-notification cfg)}]
|
{:handler (partial resend-email-notification cfg)}]
|
||||||
["/actions/reset-file-version"
|
["/actions/reset-file-version"
|
||||||
{:handler (partial reset-file-version cfg)}]
|
{:handler (partial reset-file-version cfg)}]
|
||||||
|
["/actions/add-team-feature"
|
||||||
|
{:handler (partial add-team-feature)}]
|
||||||
|
["/actions/remove-team-feature"
|
||||||
|
{:handler (partial remove-team-feature)}]
|
||||||
["/file/export" {:handler (partial export-handler cfg)}]
|
["/file/export" {:handler (partial export-handler cfg)}]
|
||||||
["/file/import" {:handler (partial import-handler cfg)}]
|
["/file/import" {:handler (partial import-handler cfg)}]
|
||||||
["/file/data" {:handler (partial file-data-handler cfg)}]
|
["/file/data" {:handler (partial file-data-handler cfg)}]
|
||||||
|
|
|
@ -10,12 +10,15 @@
|
||||||
(:require
|
(:require
|
||||||
[app.binfile.common :as bfc]
|
[app.binfile.common :as bfc]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
|
[app.common.features :as cfeat]
|
||||||
[app.common.files.validate :as cfv]
|
[app.common.files.validate :as cfv]
|
||||||
[app.db :as db]
|
[app.db :as db]
|
||||||
[app.features.components-v2 :as feat.comp-v2]
|
[app.features.components-v2 :as feat.comp-v2]
|
||||||
[app.main :as main]
|
[app.main :as main]
|
||||||
[app.rpc.commands.files :as files]
|
[app.rpc.commands.files :as files]
|
||||||
[app.rpc.commands.files-snapshot :as fsnap]
|
[app.rpc.commands.files-snapshot :as fsnap]
|
||||||
|
[app.srepl.helpers :as h]
|
||||||
[app.util.time :as dt]))
|
[app.util.time :as dt]))
|
||||||
|
|
||||||
(def ^:dynamic *system* nil)
|
(def ^:dynamic *system* nil)
|
||||||
|
@ -85,6 +88,44 @@
|
||||||
WHERE file_id = ANY(?)
|
WHERE file_id = ANY(?)
|
||||||
AND id IS NOT NULL")
|
AND id IS NOT NULL")
|
||||||
|
|
||||||
|
(defn enable-team-feature!
|
||||||
|
[team-id feature & {:keys [skip-check] :or {skip-check false}}]
|
||||||
|
(when (and (not skip-check) (not (contains? cfeat/supported-features feature)))
|
||||||
|
(ex/raise :type :assertion
|
||||||
|
:code :feature-not-supported
|
||||||
|
:hint (str "feature '" feature "' not supported")))
|
||||||
|
|
||||||
|
(let [team-id (h/parse-uuid team-id)]
|
||||||
|
(db/tx-run! main/system
|
||||||
|
(fn [{:keys [::db/conn]}]
|
||||||
|
(let [team (-> (db/get conn :team {:id team-id})
|
||||||
|
(update :features db/decode-pgarray #{}))
|
||||||
|
features (conj (:features team) feature)]
|
||||||
|
(when (not= features (:features team))
|
||||||
|
(db/update! conn :team
|
||||||
|
{:features (db/create-array conn "text" features)}
|
||||||
|
{:id team-id})
|
||||||
|
:enabled))))))
|
||||||
|
|
||||||
|
(defn disable-team-feature!
|
||||||
|
[team-id feature & {:keys [skip-check] :or {skip-check false}}]
|
||||||
|
(when (and (not skip-check) (not (contains? cfeat/supported-features feature)))
|
||||||
|
(ex/raise :type :assertion
|
||||||
|
:code :feature-not-supported
|
||||||
|
:hint (str "feature '" feature "' not supported")))
|
||||||
|
|
||||||
|
(let [team-id (h/parse-uuid team-id)]
|
||||||
|
(db/tx-run! main/system
|
||||||
|
(fn [{:keys [::db/conn]}]
|
||||||
|
(let [team (-> (db/get conn :team {:id team-id})
|
||||||
|
(update :features db/decode-pgarray #{}))
|
||||||
|
features (disj (:features team) feature)]
|
||||||
|
(when (not= features (:features team))
|
||||||
|
(db/update! conn :team
|
||||||
|
{:features (db/create-array conn "text" features)}
|
||||||
|
{:id team-id})
|
||||||
|
:disabled))))))
|
||||||
|
|
||||||
(defn search-file-snapshots
|
(defn search-file-snapshots
|
||||||
"Get a seq parirs of file-id and snapshot-id for a set of files
|
"Get a seq parirs of file-id and snapshot-id for a set of files
|
||||||
and specified label"
|
and specified label"
|
||||||
|
|
|
@ -161,44 +161,6 @@
|
||||||
(enable-objects-map-feature-on-file! file-id opts)
|
(enable-objects-map-feature-on-file! file-id opts)
|
||||||
(enable-pointer-map-feature-on-file! file-id opts))
|
(enable-pointer-map-feature-on-file! file-id opts))
|
||||||
|
|
||||||
(defn enable-team-feature!
|
|
||||||
[team-id feature]
|
|
||||||
(when-not (contains? cfeat/supported-features feature)
|
|
||||||
(ex/raise :type :assertion
|
|
||||||
:code :feature-not-supported
|
|
||||||
:hint (str "feature '" feature "' not supported")))
|
|
||||||
|
|
||||||
(let [team-id (h/parse-uuid team-id)]
|
|
||||||
(db/tx-run! main/system
|
|
||||||
(fn [{:keys [::db/conn]}]
|
|
||||||
(let [team (-> (db/get conn :team {:id team-id})
|
|
||||||
(update :features db/decode-pgarray #{}))
|
|
||||||
features (conj (:features team) feature)]
|
|
||||||
(when (not= features (:features team))
|
|
||||||
(db/update! conn :team
|
|
||||||
{:features (db/create-array conn "text" features)}
|
|
||||||
{:id team-id})
|
|
||||||
:enabled))))))
|
|
||||||
|
|
||||||
(defn disable-team-feature!
|
|
||||||
[team-id feature]
|
|
||||||
|
|
||||||
(when-not (contains? cfeat/supported-features feature)
|
|
||||||
(ex/raise :type :assertion
|
|
||||||
:code :feature-not-supported
|
|
||||||
:hint (str "feature '" feature "' not supported")))
|
|
||||||
|
|
||||||
(let [team-id (h/parse-uuid team-id)]
|
|
||||||
(db/tx-run! main/system
|
|
||||||
(fn [{:keys [::db/conn]}]
|
|
||||||
(let [team (-> (db/get conn :team {:id team-id})
|
|
||||||
(update :features db/decode-pgarray #{}))
|
|
||||||
features (disj (:features team) feature)]
|
|
||||||
(when (not= features (:features team))
|
|
||||||
(db/update! conn :team
|
|
||||||
{:features (db/create-array conn "text" features)}
|
|
||||||
{:id team-id})
|
|
||||||
:disabled))))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; NOTIFICATIONS
|
;; NOTIFICATIONS
|
||||||
|
|
Loading…
Add table
Reference in a new issue