mirror of
https://github.com/penpot/penpot.git
synced 2026-08-10 14:59:08 +00:00
⚡ Fetch team organization in a single batch
This commit is contained in:
parent
9875db2f82
commit
87eb72977b
@ -259,6 +259,14 @@
|
||||
(generate-nitrate-uri "api/teams/" team-id)
|
||||
cto/schema:team-with-organization params))
|
||||
|
||||
(defn- get-teams-organizations-api
|
||||
[cfg {:keys [team-ids] :as params}]
|
||||
(let [params (assoc params :request-params {:team-ids team-ids})]
|
||||
(request-to-nitrate cfg :post
|
||||
(generate-nitrate-uri "api/teams/organizations")
|
||||
[:vector cto/schema:team-with-organization]
|
||||
params)))
|
||||
|
||||
(defn- get-organization-membership-api
|
||||
[cfg {:keys [profile-id organization-id] :as params}]
|
||||
(request-to-nitrate cfg :get
|
||||
@ -489,6 +497,7 @@
|
||||
[_ cfg]
|
||||
(when (contains? cf/flags :admin-console)
|
||||
{:get-team-organization (partial get-team-organization-api cfg)
|
||||
:get-teams-organizations (partial get-teams-organizations-api cfg)
|
||||
:set-team-organization (partial set-team-organization-api cfg)
|
||||
:get-organization-membership (partial get-organization-membership-api cfg)
|
||||
:get-organization-membership-by-team (partial get-organization-membership-by-team-api cfg)
|
||||
@ -596,22 +605,25 @@
|
||||
:cause cause)
|
||||
profile)))))
|
||||
|
||||
(defn- apply-organization-info-to-team
|
||||
[team team-with-organization]
|
||||
(let [organization (:organization team-with-organization)]
|
||||
(if (some? organization)
|
||||
(-> (cto/apply-organization team (assoc organization :custom-photo
|
||||
(when-let [logo-id (:logo-id organization)]
|
||||
(generate-public-uri "assets/by-id/" logo-id))))
|
||||
(assoc :is-default (or (:is-default team) (true? (:is-your-penpot team-with-organization)))))
|
||||
team)))
|
||||
|
||||
(defn add-organization-info-to-team
|
||||
"Enriches a team map with organization information from Nitrate.
|
||||
Adds organization-id, organization-name, organization-slug, organization-owner-id, and your-penpot fields.
|
||||
Returns the original team unchanged if the request fails or organization data is nil.
|
||||
Propagates `:nitrate-unavailable` so the request is rejected when Nitrate is unreachable."
|
||||
[cfg team params]
|
||||
(try
|
||||
(let [params (assoc (or params {}) :team-id (:id team))
|
||||
team-with-organization (call cfg :get-team-organization params)
|
||||
organization (:organization team-with-organization)]
|
||||
(if (some? organization)
|
||||
(-> (cto/apply-organization team (assoc organization :custom-photo
|
||||
(when-let [logo-id (:logo-id organization)]
|
||||
(generate-public-uri "assets/by-id/" logo-id))))
|
||||
(assoc :is-default (or (:is-default team) (true? (:is-your-penpot team-with-organization)))))
|
||||
team))
|
||||
(let [params (assoc (or params {}) :team-id (:id team))
|
||||
team-with-organization (call cfg :get-team-organization params)]
|
||||
(apply-organization-info-to-team team team-with-organization))
|
||||
(catch Throwable cause
|
||||
(if (= :nitrate-unavailable (-> cause ex-data :type))
|
||||
(throw cause)
|
||||
@ -621,6 +633,23 @@
|
||||
:cause cause)
|
||||
team)))))
|
||||
|
||||
(defn add-organization-info-to-teams
|
||||
"Enriches teams with organization information using one batched Nitrate request.
|
||||
Teams absent from the Nitrate response are returned unchanged.
|
||||
Rejects the request when Nitrate does not return a valid batch response."
|
||||
[cfg teams params]
|
||||
(let [request-params (assoc (or params {}) :team-ids (mapv :id teams))
|
||||
teams-with-organization (call cfg :get-teams-organizations request-params)]
|
||||
(when (nil? teams-with-organization)
|
||||
(ex/raise :type :nitrate-unavailable
|
||||
:hint "nitrate did not return a valid teams organization response"))
|
||||
(let [organizations-by-team (into {} (map (juxt :id identity)) teams-with-organization)]
|
||||
(mapv (fn [{:keys [id] :as team}]
|
||||
(if-let [team-with-organization (get organizations-by-team id)]
|
||||
(apply-organization-info-to-team team team-with-organization)
|
||||
team))
|
||||
teams))))
|
||||
|
||||
(defn set-team-organization
|
||||
"Associates a team with an organization in Nitrate.
|
||||
Requires organization-id and is-default in params.
|
||||
|
||||
@ -196,11 +196,11 @@
|
||||
::sm/params schema:get-teams}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id] :as params}]
|
||||
(dm/with-open [conn (db/open pool)]
|
||||
(cond->> (get-teams conn profile-id)
|
||||
(contains? cf/flags :admin-console)
|
||||
(map #(nitrate/add-organization-info-to-team cfg % params))
|
||||
(contains? cf/flags :admin-console)
|
||||
(remove #(get-in % [:organization :expired-license])))))
|
||||
(let [teams (get-teams conn profile-id)]
|
||||
(if (contains? cf/flags :admin-console)
|
||||
(->> (nitrate/add-organization-info-to-teams cfg teams params)
|
||||
(remove #(get-in % [:organization :expired-license])))
|
||||
teams))))
|
||||
|
||||
(def ^:private sql:get-owned-teams
|
||||
"SELECT t.id, t.name,
|
||||
|
||||
@ -719,6 +719,67 @@
|
||||
(t/is (not= (:default-team-id profile1) (:id item1))))))
|
||||
|
||||
|
||||
(t/deftest get-teams-fetches-organizations-in-one-batch
|
||||
(let [profile (th/create-profile* 1 {:is-active true})
|
||||
organization-team (th/create-team* 1 {:profile-id (:id profile)})
|
||||
plain-team (th/create-team* 2 {:profile-id (:id profile)})
|
||||
expired-team (th/create-team* 3 {:profile-id (:id profile)})
|
||||
organization-id (uuid/random)
|
||||
calls (atom [])
|
||||
organization {:id organization-id
|
||||
:name "Acme"
|
||||
:slug "acme"
|
||||
:owner-id (:id profile)
|
||||
:avatar-bg-url "https://example.com/avatar.svg"}
|
||||
nitrate-call (fn [_cfg method params]
|
||||
(swap! calls conj [method params])
|
||||
[{:id (:id organization-team)
|
||||
:is-your-penpot false
|
||||
:organization organization}
|
||||
{:id (:id expired-team)
|
||||
:is-your-penpot false
|
||||
:organization (assoc organization :expired-license true)}])
|
||||
params {::th/type :get-teams
|
||||
::rpc/profile-id (:id profile)}]
|
||||
(with-redefs [cf/flags (conj cf/flags :admin-console)
|
||||
nitrate/call nitrate-call]
|
||||
(let [out (th/command! params)
|
||||
teams (:result out)]
|
||||
(t/is (th/success? out))
|
||||
(t/is (= 1 (count @calls)))
|
||||
(t/is (= :get-teams-organizations (ffirst @calls)))
|
||||
(t/is (= #{(:default-team-id profile)
|
||||
(:id organization-team)
|
||||
(:id plain-team)
|
||||
(:id expired-team)}
|
||||
(-> @calls first second :team-ids set)))
|
||||
(t/is (= #{(:default-team-id profile)
|
||||
(:id organization-team)
|
||||
(:id plain-team)}
|
||||
(into #{} (map :id) teams)))
|
||||
(t/is (= organization
|
||||
(->> teams
|
||||
(filter #(= (:id organization-team) (:id %)))
|
||||
first
|
||||
:organization)))))))
|
||||
|
||||
|
||||
(t/deftest get-teams-rejects-invalid-organization-batch-response
|
||||
(let [profile (th/create-profile* 1 {:is-active true})
|
||||
calls (atom [])
|
||||
params {::th/type :get-teams
|
||||
::rpc/profile-id (:id profile)}]
|
||||
(with-redefs [cf/flags (conj cf/flags :admin-console)
|
||||
nitrate/call (fn [_cfg method call-params]
|
||||
(swap! calls conj [method call-params])
|
||||
nil)]
|
||||
(let [out (th/command! params)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (= :nitrate-unavailable (th/ex-type (:error out))))
|
||||
(t/is (= 1 (count @calls)))
|
||||
(t/is (= :get-teams-organizations (ffirst @calls)))))))
|
||||
|
||||
|
||||
(t/deftest team-deletion-1
|
||||
(let [profile1 (th/create-profile* 1 {:is-active true})
|
||||
team (th/create-team* 1 {:profile-id (:id profile1)})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user