Improve quote data structure validation

This commit is contained in:
Andrey Antukh 2024-01-26 14:48:58 +01:00
parent e7a27759e6
commit 5accbd511f

View file

@ -7,8 +7,10 @@
(ns app.rpc.quotes (ns app.rpc.quotes
"Penpot resource usage quotes." "Penpot resource usage quotes."
(:require (:require
[app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.logging :as l] [app.common.logging :as l]
[app.common.schema :as sm]
[app.common.spec :as us] [app.common.spec :as us]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
@ -23,21 +25,15 @@
;; PUBLIC API ;; PUBLIC API
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(s/def ::conn ::db/pool-or-conn) (def ^:private schema:quote
(s/def ::file-id ::us/uuid) (sm/define
(s/def ::team-id ::us/uuid) [:map {:title "Quote"}
(s/def ::project-id ::us/uuid) [::team-id {:optional true} ::sm/uuid]
(s/def ::profile-id ::us/uuid) [::project-id {:optional true} ::sm/uuid]
(s/def ::incr (s/and int? pos?)) [::file-id {:optional true} ::sm/uuid]
(s/def ::target ::us/string) [::incr {:optional true} [:int {:min 0}]]
[::id :keyword]
(s/def ::quote [::profile-id ::sm/uuid]]))
(s/keys :req [::id ::profile-id]
:opt [::conn
::team-id
::project-id
::file-id
::incr]))
(def ^:private enabled (volatile! true)) (def ^:private enabled (volatile! true))
@ -52,15 +48,22 @@
(vswap! enabled (constantly false))) (vswap! enabled (constantly false)))
(defn check-quote! (defn check-quote!
[conn quote] [ds quote]
(us/assert! ::db/pool-or-conn conn) (dm/assert!
(us/assert! ::quote quote) "expected valid quote map"
(sm/validate schema:quote quote))
(when (contains? cf/flags :quotes) (when (contains? cf/flags :quotes)
(when @enabled (when @enabled
(check-quote (assoc quote ::conn conn ::target (name (::id quote))))))) ;; This approach add flexibility on how and where the
;; check-quote! can be called (in or out of transaction)
(db/run! ds (fn [cfg]
(-> (merge cfg quote)
(assoc ::target (name (::id quote)))
(check-quote)))))))
(defn- send-notification! (defn- send-notification!
[{:keys [::conn] :as params}] [{:keys [::db/conn] :as params}]
(l/warn :hint "max quote reached" (l/warn :hint "max quote reached"
:target (::target params) :target (::target params)
:profile-id (some-> params ::profile-id str) :profile-id (some-> params ::profile-id str)
@ -93,7 +96,7 @@
:content content}]})))) :content content}]}))))
(defn- generic-check! (defn- generic-check!
[{:keys [::conn ::incr ::quote-sql ::count-sql ::default ::target] :or {incr 1} :as params}] [{:keys [::db/conn ::incr ::quote-sql ::count-sql ::default ::target] :or {incr 1} :as params}]
(let [quote (->> (db/exec! conn quote-sql) (let [quote (->> (db/exec! conn quote-sql)
(map :quote) (map :quote)
(reduce max (- Integer/MAX_VALUE))) (reduce max (- Integer/MAX_VALUE)))
@ -347,7 +350,6 @@
(assoc ::count-sql [sql:get-comments-per-file file-id]) (assoc ::count-sql [sql:get-comments-per-file file-id])
(generic-check!))) (generic-check!)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; QUOTE: DEFAULT ;; QUOTE: DEFAULT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;