Skip to content

Instantly share code, notes, and snippets.

@atroche
Last active September 15, 2017 19:59
Show Gist options
  • Save atroche/774e0d23e78d1c78713a89b4d09e6146 to your computer and use it in GitHub Desktop.
Save atroche/774e0d23e78d1c78713a89b4d09e6146 to your computer and use it in GitHub Desktop.
(defn response-or-error [conn data command-definition data auth-details]
(let [db (d/db conn)
{::commands/keys [data-spec
db-validator
handler
allowed?
pre-tx-side-effector
prepare-datoms
session-transformer
post-tx-side-effector]} command-definition]
(better/cond
:let [command-problems (or (s/explain-data ::commands/command command)
;; TODO: actually use spec for validating definitions
(and (not command-definition) ::commands/no-such-command))]
command-problems (command-error ::commands/bad-command command-problems)
:let [data-problems (when data-spec
(s/explain-data data-spec data))]
data-problems (command-error ::commands/bad-data-shape data-problems)
:let [not-allowed #?(:clj (and (not= ::auth/admin (::auth/user-type auth-details))
(when (fn? allowed?)
(not (allowed? db data auth-details))))
:cljs false)]
not-allowed (command-error ::commands/bad-auth)
:let [db-validation-problems (when db-validator
(db-validator db data))]
db-validation-problems (command-error ::commands/bad-db-validation db-validation-problems)
:let [side-effect-results-or-error (when pre-tx-side-effector
(pre-tx-side-effector db data))
side-effects-problems (::commands/error-details side-effect-results-or-error)]
side-effects-problems (command-error ::commands/bad-side-effects side-effects-problems)
:let [{::commands/keys [tempid-map datoms]} (when (fn? prepare-datoms)
;; TODO: instead of passing in whole DB, have another
;; fn in command definition which is “grab-data-needed-for-tx-from-db”
(prepare-datoms db
data
side-effect-results-or-error
auth-details))
tx-report-or-error #?(:cljs @(d/transact conn datoms)
:clj (try
@(d/transact conn datoms)
(catch ExecutionException e
{::commands/error-id ::commands/illegal-state-error
::commands/error-details (ex-data (.getCause e))})))]
(::commands/error-id tx-report-or-error) tx-report-or-error
:let [handler-response (if handler
(handler tx-report-or-error
tempid-map
data)
{:success true})]
(fn? post-tx-side-effector) (do
(post-tx-side-effector conn handler-response tx-report-or-error tempid-map data)
handler-response)
;; TODO: fill out with requisite args as needed
handler-response)))
(def command-definitions
;; TODO: is this cancel one actually used?! is it sending emails?!
{::commands/add-booking {::commands/data-spec ::booking/new-booking
::commands/prepare-datoms prepare-booking-datoms
::commands/allowed? (fn [& args]
(and (apply booking-only-references-account-entities? args)
(apply (partial auth-utils/is-specific-owner? ::booking/account-eid) args)))
::commands/post-tx-side-effector upsert-booking-post-tx-side-effector
::commands/handler booking-return-value})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment