Refactor comments RPC methods to use schema instead of spec

This commit is contained in:
Andrey Antukh 2024-01-26 14:49:23 +01:00
parent 5accbd511f
commit 82b10ecb87

View file

@ -9,7 +9,7 @@
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.spec :as us] [app.common.schema :as sm]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.db :as db] [app.db :as db]
[app.db.sql :as sql] [app.db.sql :as sql]
@ -24,18 +24,21 @@
[app.rpc.retry :as rtry] [app.rpc.retry :as rtry]
[app.util.pointer-map :as pmap] [app.util.pointer-map :as pmap]
[app.util.services :as sv] [app.util.services :as sv]
[app.util.time :as dt] [app.util.time :as dt]))
[clojure.spec.alpha :as s]))
;; --- GENERAL PURPOSE INTERNAL HELPERS ;; --- GENERAL PURPOSE INTERNAL HELPERS
(defn decode-row (defn- decode-row
[{:keys [participants position] :as row}] [{:keys [participants position] :as row}]
(cond-> row (cond-> row
(db/pgpoint? position) (assoc :position (db/decode-pgpoint position)) (db/pgpoint? position) (assoc :position (db/decode-pgpoint position))
(db/pgobject? participants) (assoc :participants (db/decode-transit-pgobject participants)))) (db/pgobject? participants) (assoc :participants (db/decode-transit-pgobject participants))))
(def sql:get-file (def xf-decode-row
(map decode-row))
(def ^:privateqpage-name
sql:get-file
"select f.id, f.modified_at, f.revn, f.features, "select f.id, f.modified_at, f.revn, f.features,
f.project_id, p.team_id, f.data f.project_id, p.team_id, f.data
from file as f from file as f
@ -45,17 +48,19 @@
(defn- get-file (defn- get-file
"A specialized version of get-file for comments module." "A specialized version of get-file for comments module."
[{:keys [::db/conn] :as cfg} file-id page-id] [cfg file-id page-id]
(if-let [{:keys [data] :as file} (some-> (db/exec-one! conn [sql:get-file file-id]) (let [file (db/exec-one! cfg [sql:get-file file-id])]
(files/decode-row))] (when-not file
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)] (ex/raise :type :not-found
(-> file :code :object-not-found
(assoc :page-name (dm/get-in data [:pages-index page-id :name])) :hint "file not found"))
(assoc :page-id page-id)))
(ex/raise :type :not-found (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
:code :object-not-found (let [{:keys [data] :as file} (files/decode-row file)]
:hint "file not found"))) (-> file
(assoc :page-name (dm/get-in data [:pages-index page-id :name]))
(assoc :page-id page-id)
(dissoc :data))))))
(defn- get-comment-thread (defn- get-comment-thread
[conn thread-id & {:as opts}] [conn thread-id & {:as opts}]
@ -93,23 +98,25 @@
(declare ^:private get-comment-threads) (declare ^:private get-comment-threads)
(s/def ::team-id ::us/uuid) (def ^:private
(s/def ::file-id ::us/uuid) schema:get-comment-threads
(s/def ::share-id (s/nilable ::us/uuid)) [:and
[:map {:title "get-comment-threads"}
(s/def ::get-comment-threads [:file-id {:optional true} ::sm/uuid]
(s/and (s/keys :req [::rpc/profile-id] [:team-id {:optional true} ::sm/uuid]
:opt-un [::file-id ::share-id ::team-id]) [:share-id {:optional true} [:maybe ::sm/uuid]]]
#(or (:file-id %) (:team-id %)))) [::sm/contains-any #{:file-id :team-id}]])
(sv/defmethod ::get-comment-threads (sv/defmethod ::get-comment-threads
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id share-id] :as params}] ::sm/params schema:get-comment-threads}
(dm/with-open [conn (db/open pool)] [cfg {:keys [::rpc/profile-id file-id share-id] :as params}]
(files/check-comment-permissions! conn profile-id file-id share-id)
(get-comment-threads conn profile-id file-id)))
(def sql:comment-threads (db/run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id)
(get-comment-threads conn profile-id file-id))))
(def ^:private sql:comment-threads
"select distinct on (ct.id) "select distinct on (ct.id)
ct.*, ct.*,
f.name as file_name, f.name as file_name,
@ -134,23 +141,24 @@
(defn- get-comment-threads (defn- get-comment-threads
[conn profile-id file-id] [conn profile-id file-id]
(->> (db/exec! conn [sql:comment-threads profile-id file-id]) (->> (db/exec! conn [sql:comment-threads profile-id file-id])
(into [] (map decode-row)))) (into [] xf-decode-row)))
;; --- COMMAND: Get Unread Comment Threads ;; --- COMMAND: Get Unread Comment Threads
(declare ^:private get-unread-comment-threads) (declare ^:private get-unread-comment-threads)
(s/def ::team-id ::us/uuid) (def ^:private
(s/def ::get-unread-comment-threads schema:get-unread-comment-threads
(s/keys :req [::rpc/profile-id] [:map {:title "get-unread-comment-threads"}
:req-un [::team-id])) [:team-id ::sm/uuid]])
(sv/defmethod ::get-unread-comment-threads (sv/defmethod ::get-unread-comment-threads
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id team-id] :as params}] ::sm/params schema:get-unread-comment-threads}
(dm/with-open [conn (db/open pool)] [cfg {:keys [::rpc/profile-id team-id] :as params}]
(teams/check-read-permissions! conn profile-id team-id) (db/run! cfg (fn [{:keys [::db/conn]}]
(get-unread-comment-threads conn profile-id team-id))) (teams/check-read-permissions! conn profile-id team-id)
(get-unread-comment-threads conn profile-id team-id))))
(def sql:comment-threads-by-team (def sql:comment-threads-by-team
"select distinct on (ct.id) "select distinct on (ct.id)
@ -182,62 +190,60 @@
(defn- get-unread-comment-threads (defn- get-unread-comment-threads
[conn profile-id team-id] [conn profile-id team-id]
(->> (db/exec! conn [sql:unread-comment-threads-by-team profile-id team-id]) (->> (db/exec! conn [sql:unread-comment-threads-by-team profile-id team-id])
(into [] (map decode-row)))) (into [] xf-decode-row)))
;; --- COMMAND: Get Single Comment Thread ;; --- COMMAND: Get Single Comment Thread
(s/def ::get-comment-thread (def ^:private
(s/keys :req [::rpc/profile-id] schema:get-comment-thread
:req-un [::file-id ::us/id] [:map {:title "get-comment-thread"}
:opt-un [::share-id])) [:file-id ::sm/uuid]
[:id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::get-comment-thread (sv/defmethod ::get-comment-thread
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id id share-id] :as params}] ::sm/params schema:get-comment-thread}
(dm/with-open [conn (db/open pool)] [cfg {:keys [::rpc/profile-id file-id id share-id] :as params}]
(files/check-comment-permissions! conn profile-id file-id share-id) (db/run! cfg (fn [{:keys [::db/conn]}]
(let [sql (str "with threads as (" sql:comment-threads ")" (files/check-comment-permissions! conn profile-id file-id share-id)
"select * from threads where id = ?")] (let [sql (str "with threads as (" sql:comment-threads ")"
(-> (db/exec-one! conn [sql profile-id file-id id]) "select * from threads where id = ?")]
(decode-row))))) (-> (db/exec-one! conn [sql profile-id file-id id])
(decode-row))))))
;; --- COMMAND: Retrieve Comments ;; --- COMMAND: Retrieve Comments
(declare ^:private get-comments) (declare ^:private get-comments)
(s/def ::thread-id ::us/uuid) (def ^:private
(s/def ::get-comments schema:get-comments
(s/keys :req [::rpc/profile-id] [:map {:title "get-comments"}
:req-un [::thread-id] [:thread-id ::sm/uuid]
:opt-un [::share-id])) [:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::get-comments (sv/defmethod ::get-comments
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id thread-id share-id] :as params}] ::sm/params schema:get-comments}
(dm/with-open [conn (db/open pool)] [cfg {:keys [::rpc/profile-id thread-id share-id]}]
(let [{:keys [file-id] :as thread} (get-comment-thread conn thread-id)] (db/run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [file-id] :as thread} (get-comment-thread conn thread-id)]
(get-comments conn thread-id)))) (files/check-comment-permissions! conn profile-id file-id share-id)
(get-comments conn thread-id)))))
(def sql:comments
"select c.* from comment as c
where c.thread_id = ?
order by c.created_at asc")
(defn- get-comments (defn- get-comments
[conn thread-id] [conn thread-id]
(->> (db/query conn :comment (->> (db/query conn :comment
{:thread-id thread-id} {:thread-id thread-id}
{:order-by [[:created-at :asc]]}) {:order-by [[:created-at :asc]]})
(into [] (map decode-row)))) (into [] xf-decode-row)))
;; --- COMMAND: Get file comments users ;; --- COMMAND: Get file comments users
;; All the profiles that had comment the file, plus the current ;; All the profiles that had comment the file, plus the current
;; profile. ;; profile.
(def sql:file-comment-users (def ^:private sql:file-comment-users
"WITH available_profiles AS ( "WITH available_profiles AS (
SELECT DISTINCT owner_id AS id SELECT DISTINCT owner_id AS id
FROM comment FROM comment
@ -256,20 +262,22 @@
[conn file-id profile-id] [conn file-id profile-id]
(db/exec! conn [sql:file-comment-users file-id profile-id])) (db/exec! conn [sql:file-comment-users file-id profile-id]))
(s/def ::get-profiles-for-file-comments (def ^:private
(s/keys :req [::rpc/profile-id] schema:get-profiles-for-file-comments
:req-un [::file-id] [:map {:title "get-profiles-for-file-comments"}
:opt-un [::share-id])) [:file-id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::get-profiles-for-file-comments (sv/defmethod ::get-profiles-for-file-comments
"Retrieves a list of profiles with limited set of properties of all "Retrieves a list of profiles with limited set of properties of all
participants on comment threads of the file." participants on comment threads of the file."
{::doc/added "1.15" {::doc/added "1.15"
::doc/changes ["1.15" "Imported from queries and renamed."]} ::doc/changes ["1.15" "Imported from queries and renamed."]
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id share-id]}] ::sm/params schema:get-profiles-for-file-comments}
(dm/with-open [conn (db/open pool)] [cfg {:keys [::rpc/profile-id file-id share-id]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (db/run! cfg (fn [{:keys [::db/conn]}]
(get-file-comments-users conn file-id profile-id))) (files/check-comment-permissions! conn profile-id file-id share-id)
(get-file-comments-users conn file-id profile-id))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MUTATION COMMANDS ;; MUTATION COMMANDS
@ -279,52 +287,52 @@
;; --- COMMAND: Create Comment Thread ;; --- COMMAND: Create Comment Thread
(s/def ::page-id ::us/uuid) (def ^:private
(s/def ::position ::gpt/point) schema:create-comment-thread
(s/def ::content ::us/string) [:map {:title "create-comment-thread"}
(s/def ::frame-id ::us/uuid) [:file-id ::sm/uuid]
[:position ::gpt/point]
(s/def ::create-comment-thread [:content :string]
(s/keys :req [::rpc/profile-id] [:page-id ::sm/uuid]
:req-un [::file-id ::position ::content ::page-id ::frame-id] [:frame-id ::sm/uuid]
:opt-un [::share-id])) [:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::create-comment-thread (sv/defmethod ::create-comment-thread
{::doc/added "1.15" {::doc/added "1.15"
::webhooks/event? true} ::webhooks/event? true
::rtry/enabled true
::rtry/when rtry/conflict-exception?
::sm/params schema:create-comment-thread}
[cfg {:keys [::rpc/profile-id ::rpc/request-at file-id page-id share-id position content frame-id]}] [cfg {:keys [::rpc/profile-id ::rpc/request-at file-id page-id share-id position content frame-id]}]
(db/tx-run! cfg
(fn [{:keys [::db/conn] :as cfg}]
(files/check-comment-permissions! conn profile-id file-id share-id)
(let [{:keys [team-id project-id page-name] :as file} (get-file cfg file-id page-id)]
(run! (partial quotes/check-quote! conn) (db/tx-run! cfg (fn [{:keys [::db/conn] :as cfg}]
(list {::quotes/id ::quotes/comment-threads-per-file (files/check-comment-permissions! cfg profile-id file-id share-id)
::quotes/profile-id profile-id (let [{:keys [team-id project-id page-name]} (get-file conn file-id page-id)]
::quotes/team-id team-id
::quotes/project-id project-id
::quotes/file-id file-id}
{::quotes/id ::quotes/comments-per-file
::quotes/profile-id profile-id
::quotes/team-id team-id
::quotes/project-id project-id
::quotes/file-id file-id}))
(run! (partial quotes/check-quote! cfg)
(list {::quotes/id ::quotes/comment-threads-per-file
::quotes/profile-id profile-id
::quotes/team-id team-id
::quotes/project-id project-id
::quotes/file-id file-id}
{::quotes/id ::quotes/comments-per-file
::quotes/profile-id profile-id
::quotes/team-id team-id
::quotes/project-id project-id
::quotes/file-id file-id}))
(-> cfg (create-comment-thread conn {:created-at request-at
(assoc ::rtry/when rtry/conflict-exception?) :profile-id profile-id
(assoc ::rtry/label "create-comment-thread") :file-id file-id
(rtry/invoke create-comment-thread {:created-at request-at :page-id page-id
:profile-id profile-id :page-name page-name
:file-id file-id :position position
:page-id page-id :content content
:page-name page-name :frame-id frame-id})))))
:position position
:content content
:frame-id frame-id}))))))
(defn- create-comment-thread (defn- create-comment-thread
[{:keys [::db/conn]} {:keys [profile-id file-id page-id page-name created-at position content frame-id]}] [conn {:keys [profile-id file-id page-id page-name created-at position content frame-id]}]
(let [;; NOTE: we take the next seq number from a separate query because the whole (let [;; NOTE: we take the next seq number from a separate query because the whole
;; operation can be retried on conflict, and in this case the new seq shold be ;; operation can be retried on conflict, and in this case the new seq shold be
;; retrieved from the database. ;; retrieved from the database.
@ -364,68 +372,72 @@
;; --- COMMAND: Update Comment Thread Status ;; --- COMMAND: Update Comment Thread Status
(s/def ::id ::us/uuid) (def ^:private
(s/def ::share-id (s/nilable ::us/uuid)) schema:update-comment-thread-status
[:map {:title "update-comment-thread-status"}
(s/def ::update-comment-thread-status [:id ::sm/uuid]
(s/keys :req [::rpc/profile-id] [:share-id {:optional true} [:maybe ::sm/uuid]]])
:req-un [::id]
:opt-un [::share-id]))
(sv/defmethod ::update-comment-thread-status (sv/defmethod ::update-comment-thread-status
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id id share-id] :as params}] ::sm/params schema:update-comment-thread-status}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id id share-id]}]
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
(upsert-comment-thread-status! conn profile-id id)))) (files/check-comment-permissions! conn profile-id file-id share-id)
(upsert-comment-thread-status! conn profile-id id)))))
;; --- COMMAND: Update Comment Thread ;; --- COMMAND: Update Comment Thread
(s/def ::is-resolved ::us/boolean) (def ^:private
(s/def ::update-comment-thread schema:update-comment-thread
(s/keys :req [::rpc/profile-id] [:map {:title "update-comment-thread"}
:req-un [::id ::is-resolved] [:id ::sm/uuid]
:opt-un [::share-id])) [:is-resolved :boolean]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::update-comment-thread (sv/defmethod ::update-comment-thread
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id id is-resolved share-id] :as params}] ::sm/params schema:update-comment-thread}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id id is-resolved share-id]}]
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
(db/update! conn :comment-thread (files/check-comment-permissions! conn profile-id file-id share-id)
{:is-resolved is-resolved} (db/update! conn :comment-thread
{:id id}) {:is-resolved is-resolved}
nil))) {:id id})
nil))))
;; --- COMMAND: Add Comment ;; --- COMMAND: Add Comment
(declare ^:private get-comment-thread) (declare ^:private get-comment-thread)
(s/def ::create-comment (def ^:private
(s/keys :req [::rpc/profile-id] schema:create-comment
:req-un [::thread-id ::content] [:map {:title "create-comment"}
:opt-un [::share-id])) [:thread-id ::sm/uuid]
[:content :string]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::create-comment (sv/defmethod ::create-comment
{::doc/added "1.15" {::doc/added "1.15"
::webhooks/event? true} ::webhooks/event? true
::sm/params schema:create-comment}
[cfg {:keys [::rpc/profile-id ::rpc/request-at thread-id share-id content]}] [cfg {:keys [::rpc/profile-id ::rpc/request-at thread-id share-id content]}]
(db/tx-run! cfg (db/tx-run! cfg
(fn [{:keys [::db/conn] :as cfg}] (fn [{:keys [::db/conn] :as cfg}]
(let [{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::sql/for-update true) (let [{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::sql/for-update true)
{:keys [team-id project-id page-name] :as file} (get-file cfg file-id page-id)] {:keys [team-id project-id page-name] :as file} (get-file cfg file-id page-id)]
(files/check-comment-permissions! conn profile-id (:id file) share-id) (files/check-comment-permissions! conn profile-id file-id share-id)
(quotes/check-quote! conn (quotes/check-quote! conn
{::quotes/id ::quotes/comments-per-file {::quotes/id ::quotes/comments-per-file
::quotes/profile-id profile-id ::quotes/profile-id profile-id
::quotes/team-id team-id ::quotes/team-id team-id
::quotes/project-id project-id ::quotes/project-id project-id
::quotes/file-id (:id file)}) ::quotes/file-id file-id})
;; Update the page-name cached attribute on comment thread table. ;; Update the page-name cached attribute on comment thread table.
(when (not= page-name (:page-name thread)) (when (not= page-name (:page-name thread))
@ -461,15 +473,17 @@
;; --- COMMAND: Update Comment ;; --- COMMAND: Update Comment
(s/def ::update-comment (def ^:private
(s/keys :req [::rpc/profile-id] schema:update-comment
:req-un [::id ::content] [:map {:title "update-comment"}
:opt-un [::share-id])) [:id ::sm/uuid]
[:content :string]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::update-comment (sv/defmethod ::update-comment
{::doc/added "1.15"} {::doc/added "1.15"
::sm/params schema:update-comment}
[cfg {:keys [::rpc/profile-id ::rpc/request-at id share-id content]}] [cfg {:keys [::rpc/profile-id ::rpc/request-at id share-id content]}]
(db/tx-run! cfg (db/tx-run! cfg
(fn [{:keys [::db/conn] :as cfg}] (fn [{:keys [::db/conn] :as cfg}]
(let [{:keys [thread-id owner-id] :as comment} (get-comment conn id ::sql/for-update true) (let [{:keys [thread-id owner-id] :as comment} (get-comment conn id ::sql/for-update true)
@ -482,7 +496,7 @@
(ex/raise :type :validation (ex/raise :type :validation
:code :not-allowed)) :code :not-allowed))
(let [{:keys [page-name] :as file} (get-file cfg file-id page-id)] (let [{:keys [page-name]} (get-file cfg file-id page-id)]
(db/update! conn :comment (db/update! conn :comment
{:content content {:content content
:modified-at request-at} :modified-at request-at}
@ -496,79 +510,90 @@
;; --- COMMAND: Delete Comment Thread ;; --- COMMAND: Delete Comment Thread
(s/def ::delete-comment-thread (def ^:private
(s/keys :req [::rpc/profile-id] schema:delete-comment-thread
:req-un [::id] [:map {:title "delete-comment-thread"}
:opt-un [::share-id])) [:id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::delete-comment-thread (sv/defmethod ::delete-comment-thread
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id id share-id]}] ::sm/params schema:delete-comment-thread}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id id share-id]}]
(let [{:keys [owner-id file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [owner-id file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
(when-not (= owner-id profile-id) (files/check-comment-permissions! conn profile-id file-id share-id)
(ex/raise :type :validation (when-not (= owner-id profile-id)
:code :not-allowed)) (ex/raise :type :validation
:code :not-allowed))
(db/delete! conn :comment-thread {:id id}) (db/delete! conn :comment-thread {:id id})
nil))) nil))))
;; --- COMMAND: Delete comment ;; --- COMMAND: Delete comment
(s/def ::delete-comment (def ^:private
(s/keys :req [::rpc/profile-id] schema:delete-comment
:req-un [::id] [:map {:title "delete-comment"}
:opt-un [::share-id])) [:id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::delete-comment (sv/defmethod ::delete-comment
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id id share-id] :as params}] ::sm/params schema:delete-comment}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id id share-id]}]
(let [{:keys [owner-id thread-id] :as comment} (get-comment conn id ::sql/for-update true) (db/tx-run! cfg (fn [{:keys [::db/conn]}]
{:keys [file-id] :as thread} (get-comment-thread conn thread-id)] (let [{:keys [owner-id thread-id] :as comment} (get-comment conn id ::sql/for-update true)
(files/check-comment-permissions! conn profile-id file-id share-id) {:keys [file-id] :as thread} (get-comment-thread conn thread-id)]
(when-not (= owner-id profile-id) (files/check-comment-permissions! conn profile-id file-id share-id)
(ex/raise :type :validation (when-not (= owner-id profile-id)
:code :not-allowed)) (ex/raise :type :validation
(db/delete! conn :comment {:id id}) :code :not-allowed))
nil))) (db/delete! conn :comment {:id id})
nil))))
;; --- COMMAND: Update comment thread position ;; --- COMMAND: Update comment thread position
(s/def ::update-comment-thread-position (def ^:private
(s/keys :req [::rpc/profile-id] schema:update-comment-thread-position
:req-un [::id ::position ::frame-id] [:map {:title "update-comment-thread-position"}
:opt-un [::share-id])) [:id ::sm/uuid]
[:position ::gpt/point]
[:frame-id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::update-comment-thread-position (sv/defmethod ::update-comment-thread-position
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id position frame-id share-id]}] ::sm/params schema:update-comment-thread-position}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id ::rpc/request-at id position frame-id share-id]}]
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
(db/update! conn :comment-thread (files/check-comment-permissions! conn profile-id file-id share-id)
{:modified-at request-at (db/update! conn :comment-thread
:position (db/pgpoint position) {:modified-at request-at
:frame-id frame-id} :position (db/pgpoint position)
{:id (:id thread)}) :frame-id frame-id}
nil))) {:id (:id thread)})
nil))))
;; --- COMMAND: Update comment frame ;; --- COMMAND: Update comment frame
(s/def ::update-comment-thread-frame (def ^:private
(s/keys :req [::rpc/profile-id] schema:update-comment-thread-frame
:req-un [::id ::frame-id] [:map {:title "update-comment-thread-frame"}
:opt-un [::share-id])) [:id ::sm/uuid]
[:frame-id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]])
(sv/defmethod ::update-comment-thread-frame (sv/defmethod ::update-comment-thread-frame
{::doc/added "1.15"} {::doc/added "1.15"
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id frame-id share-id]}] ::sm/params schema:update-comment-thread-frame}
(db/with-atomic [conn pool] [cfg {:keys [::rpc/profile-id ::rpc/request-at id frame-id share-id]}]
(let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (let [{:keys [file-id] :as thread} (get-comment-thread conn id ::sql/for-update true)]
(db/update! conn :comment-thread (files/check-comment-permissions! conn profile-id file-id share-id)
{:modified-at request-at (db/update! conn :comment-thread
:frame-id frame-id} {:modified-at request-at
{:id id}) :frame-id frame-id}
nil))) {:id id})
nil))))