(ns metabase.events.schema (:require [malli.util :as mut] [metabase.models.view-log-impl :as view-log-impl] [metabase.util.malli :as mu] [metabase.util.malli.registry :as mr] [metabase.util.malli.schema :as ms] [toucan2.core :as t2])) | |
Get the Malli schema we should use for events of | (mu/defn event-schema [topic :- keyword?] (or (mr/registered-schema topic) :map)) |
Given a malli entry schema of a map, return a new entry schema with an additional option to hydrate information when sending system event notifications. (events.notification/hydrate! [:map (-> [:user_id :int] (with-hydrate :user [:model/User :email]))] {:user_id 1}) ;; => {:user_id 1 :user {:email "ngoc@metabase.com"}} | #_{:clj-kondo/ignore [:unused-private-var]} (defn- with-hydrate [entry-schema k model] (assert (#{2 3} (count entry-schema)) "entry-schema must have 2 or 3 elements") (let [[entry-key option schema] (if (= 2 (count entry-schema)) [(first entry-schema) {} (second entry-schema)] entry-schema)] [entry-key (assoc option :hydrate {:key k :model model}) schema])) |
(def ^:private user-hydrate [:model/User :first_name :last_name :email]) | |
collection events | |
(mr/def :event/collection-read [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/Collection %)]]]) | |
dashboard events | |
(mr/def ::dashboard [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/Dashboard %)]]]) | |
(mr/def :event/dashboard-create ::dashboard) (mr/def :event/dashboard-update ::dashboard) (mr/def :event/dashboard-delete ::dashboard) | |
(mr/def ::dashboard-with-dashcards (-> (event-schema ::dashboard) (mut/assoc :dashcards [:sequential [:map [:id pos-int?]]]))) | |
(mr/def :event/dashboard-remove-cards ::dashboard-with-dashcards) (mr/def :event/dashboard-add-cards ::dashboard-with-dashcards) | |
(mr/def :event/dashboard-read [:map {:closed true} [:user-id [:maybe pos-int?]] [:object-id [:maybe pos-int?]]]) | |
card events | |
(mr/def ::card [:map {:closed true} [:user-id [:maybe pos-int?]] [:object [:fn #(t2/instance-of? :model/Card %)]]]) | |
(mr/def :event/card-create ::card) (mr/def :event/card-update ::card) (mr/def :event/card-delete ::card) | |
(mr/def :event/card-read [:map {:closed true} ;; context is deliberately coupled to view-log's context [:context view-log-impl/context] [:user-id [:maybe pos-int?]] [:object-id [:maybe pos-int?]]]) | |
(mr/def :event/card-query [:map {:closed true} [:card-id pos-int?] [:user-id [:maybe pos-int?]] [:context {:optional true} :any]]) | |
user events | |
(mr/def ::user [:map {:closed true} [:user-id pos-int?]]) | |
(mr/def :event/user-login ::user) (mr/def :event/user-joined ::user) | |
(mr/def :event/user-invited [:map {:closed true} [:object [:map [:email ms/Email] [:is_from_setup {:optional true} :boolean] [:first_name {:optional true} [:maybe :string]] [:invite_method {:optional true} :string] [:sso_source {:optional true} [:maybe [:or :keyword :string]]]]] [:details {:optional true} [:map {:closed true} [:invitor [:map {:closed true} [:email ms/Email] [:first_name {:optional true} [:maybe :string]]]]]]]) | |
metric events | |
TODO -- are these for LEGACY METRICS? ARE THESE EVENT USED ANYMORE? | |
(mr/def ::metric [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/LegacyMetric %)]]]) | |
(mr/def :event/metric-create ::metric) | |
(mr/def ::metric-with-message [:merge ::metric [:map {:closed true} [:revision-message {:optional true} :string]]]) | |
(mr/def :event/metric-update ::metric-with-message) (mr/def :event/metric-delete ::metric-with-message) | |
segment events | |
(mr/def ::segment [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/Segment %)]]]) | |
(mr/def :event/segment-create ::segment) | |
(mr/def ::segment-with-message [:merge ::segment [:map {:closed true} [:revision-message {:optional true} :string]]]) | |
(mr/def :event/segment-update ::segment-with-message) (mr/def :event/segment-delete ::segment-with-message) | |
database events | |
(mr/def ::database [:map {:closed true} [:object [:fn #(t2/instance-of? :model/Database %)]] [:previous-object {:optional true} [:fn #(t2/instance-of? :model/Database %)]] [:user-id pos-int?]]) | |
(mr/def :event/database-create ::database) (mr/def :event/database-update ::database) (mr/def :event/database-delete ::database) | |
alert schemas | |
(mr/def :event/alert-create [:map {:closed true} (-> [:user-id pos-int?] (with-hydrate :user user-hydrate)) [:object [:and [:fn #(t2/instance-of? :model/Pulse %)] [:map [:card [:fn #(t2/instance-of? :model/Card %)]]]]]]) | |
pulse schemas | |
(mr/def :event/pulse-create [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/Pulse %)]]]) | |
table events | |
(mr/def :event/table-read [:map {:closed true} [:user-id pos-int?] [:object [:fn #(t2/instance-of? :model/Table %)]]]) | |
(mr/def ::permission-failure [:map {:closed true} [:user-id [:maybe pos-int?]] [:object [:maybe [:fn #(boolean (t2/model %))]]] [:has-access {:optional true} [:maybe :boolean]]]) | |
(mr/def :event/read-permission-failure ::permission-failure) (mr/def :event/write-permission-failure ::permission-failure) (mr/def :event/update-permission-failure ::permission-failure) | |
(mr/def :event/create-permission-failure [:map {:closed true} [:user-id [:maybe pos-int?]] [:model [:or :keyword :string]]]) | |