better health check.

This commit is contained in:
Bryce Covert
2020-09-17 07:05:23 -07:00
parent 80efc14d3a
commit 2e18e2da26
11 changed files with 88 additions and 190 deletions

View File

@@ -37,6 +37,12 @@
:where ['[?e :transaction/bank-account ?bank-account-id]]}
:args [(:bank-account-id args)]})
(:account-id args)
(merge-query {:query {:in ['?account-id]
:where ['[?e :transaction/accounts ?accounts]
'[?accounts :transaction-account/account ?account-id]]}
:args [(:account-id args)]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :transaction/client ?client-id]]}

View File

@@ -590,6 +590,7 @@
:transaction_filters {:fields {:client_id {:type :id}
:vendor_id {:type :id}
:bank_account_id {:type :id}
:account_id {:type :id}
:date_range {:type :date_range}
:amount_lte {:type :money}
:amount_gte {:type :money}

View File

@@ -85,8 +85,7 @@
(when (not (get (into #{"Shared"} (:client/locations client))
(:location a)))
(let [err (str "Account " name " uses location " (:location a) ", but doesn't belong to the client " location)]
(throw (ex-info err {:validation-error err}) )))
)
(throw (ex-info err {:validation-error err}) ))))
rule-id (if id
id
"transaction-rule")

View File

@@ -1,48 +1,56 @@
(ns auto-ap.handler
(:require [amazonica.core :refer [defcredential]]
[auto-ap.routes.auth :as auth]
[auto-ap.routes.clients :as clients]
[auto-ap.routes.invoices :as invoices]
[auto-ap.routes.reminders :as reminders]
[auto-ap.routes.graphql :as graphql]
[auto-ap.routes.yodlee :as yodlee]
[auto-ap.routes.events :as events]
[auto-ap.routes.checks :as checks]
[auto-ap.routes.exports :as exports]
[auto-ap.routes.graphql :as graphql]
[auto-ap.routes.invoices :as invoices]
[auto-ap.routes.yodlee :as yodlee]
[buddy.auth.backends.token :refer [jws-backend]]
[buddy.auth.middleware :refer [wrap-authentication
wrap-authorization]]
[clojure.java.jdbc :as jdbc]
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
[clojure.tools.logging :as log]
[compojure.core :refer :all]
[compojure.route :as route]
[config.core :refer [env]]
[clojure.tools.logging :as log]
[unilog.context :as lc]
[mount.core :as mount]
[ring.middleware.edn :refer [wrap-edn-params]]
[ring.middleware.gzip :refer [wrap-gzip]]
[ring.middleware.multipart-params :as mp]
[ring.middleware.params :refer [wrap-params]]
[ring.middleware.reload :refer [wrap-reload]]
[ring.middleware.gzip :refer [wrap-gzip]]
[ring.util.response :as response]))
[ring.util.response :as response]
[unilog.context :as lc]))
(when (:aws-access-key-id env)
(defcredential (:aws-access-key-id env) (:aws-secret-access-key env) (:aws-region env)))
(def running? (atom false))
(mount/defstate manage-running?
:start (reset! running? true)
:stop (reset! running? false))
(defroutes static-routes
(GET "/" [] (response/resource-response "index.html" {:root "public"}))
(route/resources "/")
(routes (ANY "*" [] (response/resource-response "index.html" {:root "public"}))))
(defroutes health-check
(GET "/health-check" []
(if @running?
{:status 200
:body "Ok"}
{:status 503
:body "Application shut down"})))
(defroutes api-routes
(context "/api" []
exports/routes
yodlee/routes
invoices/routes
clients/routes
reminders/routes
checks/routes
graphql/routes
auth/routes))
auth/routes
health-check))
(def auth-backend (jws-backend {:secret (:jwt-secret env) :options {:alg :hs512}}))

View File

@@ -1,9 +0,0 @@
(ns auto-ap.routes.checks
(:require
[hiccup.core :refer [html]]
[auto-ap.routes.utils :refer [wrap-secure]]
[compojure.core :refer [GET POST context defroutes wrap-routes]]))
(defroutes routes
(wrap-routes
(context "/checks" [])
wrap-secure))

View File

@@ -1,29 +0,0 @@
(ns auto-ap.routes.clients
(:require [auto-ap.datomic.clients :as clients]
[auto-ap.graphql.utils :refer [can-see-client? assert-can-see-client]]
[auto-ap.routes.utils :refer [wrap-secure wrap-spec]]
[auto-ap.entities.clients :as entity]
[compojure.core :refer [GET PUT context defroutes
wrap-routes]]))
(defroutes routes
(wrap-routes
(context "/clients" []
#_(wrap-spec
(PUT "/:id" {{:keys [address email locations new-bank-accounts]} :edn-params :keys [edn-params] {:keys [id ]} :route-params :as r}
(assert-can-see-client (:identity r) id)
(let [id (Integer/parseInt id)
company (d-clients/get-by-id id)
updated-company (merge company {:address address
:email email
:locations locations})]
#_(companies/upsert id updated-company)
#_(doseq [bank-account new-bank-accounts]
(companies/add-bank-account id bank-account))
{:status 200
:body (pr-str (clients/get-by-id id))
:headers {"Content-Type" "application/edn"}}))
::entity/company))
wrap-secure))

View File

@@ -1,100 +0,0 @@
(ns auto-ap.routes.reminders
(:require
[auto-ap.routes.utils :refer [wrap-secure]]
[auto-ap.graphql.utils :refer [assert-admin]]
[config.core :refer [env]]
[clj-http.client :as http]
[clj-time.coerce :as c]
[clj-time.core :as time]
[clj-time.periodic :as p]
[clj-time.predicates :as pred]
[clojure.data.json :as json]
[compojure.core :refer [GET PUT POST context defroutes
wrap-routes]])
(:import (org.joda.time DateTime)))
#_(POST "/:id/remind" {:keys [edn-params] {:keys [id :<< as-int]} :route-params :as r}
(assert-admin (:identity r))
(let [id (if (int? id)
id
(Integer/parseInt id))
vendor (vendors/get-by-id id)]
(reminders/insert (assoc
(reminders/template)
:email (:primary-email vendor)
:vendor-id id
:scheduled (time/now)))
(-> (reminders/get-ready)
(reminders/send-emails))
{:status 200
:body "{}"
:headers {"Content-Type" "application/edn"}}))
#_(defn next-sunday []
(let [sunday (->> (p/periodic-seq (time/plus (time/today) (time/days 1)) (time/days 1))
(filter pred/sunday?)
first)]
(time/from-time-zone (time/date-time (time/year sunday) (time/month sunday) (time/day sunday))
(time/time-zone-for-id "America/Los_Angeles"))))
#_(defn schedule-reminders []
(let [vendors (vendors/find-with-reminders)
future-reminders (reminders/find-future (map :id vendors))
has-reminder-scheduled? (set (map :vendor-id future-reminders))
vendors-without-scheduled (filter #(not (has-reminder-scheduled? (:id %))) vendors)]
(println "Reminders already scheduled:" future-reminders)
(println "Reminders will happen at" (next-sunday))
(println "Reminders to schedule" vendors-without-scheduled)
(doseq [{:keys [id primary-email invoice-reminder-schedule]} vendors-without-scheduled]
(reminders/insert (assoc (reminders/template)
:vendor-id id
:email primary-email
:scheduled (next-sunday))))))
#_(defn find-ready-reminders []
(let [vendors (vendors/get-all)
ready-reminders (reminders/get-ready)]
ready-reminders))
#_(defn replace-joda [x]
(into {} (map (fn [[k v]]
[k (if (instance? DateTime v)
(c/to-date v)
v)])
x)))
(defroutes routes
(context "/reminders" []
#_(POST "/send" {:keys [query-params headers body] :as x}
(let [notification-type (get headers "x-amz-sns-message-type")]
(println "Received notification " notification-type)
(if (= "SubscriptionConfirmation" notification-type)
(do
(println "Responding to confirmation" )
(let [json (json/read-str (slurp body))]
(println json)
(http/get (get json "SubscribeURL"))))
(do
(println "Scheduling")
(schedule-reminders)
(-> (reminders/get-ready)
(reminders/send-emails)))))
{:status 200
:body "{}"
:headers {"Content-Type" "application/edn"}})
#_(wrap-routes
(PUT "/:id" {:keys [ edn-params] {:keys [id] } :route-params identity :identity}
(assert-admin identity)
(let [id (if (int? id)
id
(Integer/parseInt id))]
(assert (not (:sent (reminders/get-by-id id))))
(reminders/update! id edn-params)
{:status 200
:body "{}"
:headers {"Content-Type" "application/edn"}}))
wrap-secure)))

View File

@@ -14,14 +14,19 @@
[mount.core :as mount])
(:gen-class))
(defn add-shutdown-hook! [^Runnable f]
(.addShutdownHook (Runtime/getRuntime)
(Thread. f)))
(mount/defstate port :start (Integer/parseInt (or (env :port) "3000")))
(mount/defstate jetty
:start (run-jetty app {:port port :join? false})
:stop (.stop jetty)
)
:stop (.stop jetty))
(defn shutdown-mount []
(mount/stop))
(defn -main [& args]
(add-shutdown-hook! shutdown-mount)
(start-server :port 9000 :bind "0.0.0.0" #_#_:handler (cider-nrepl-handler))
(mount/start))

View File

@@ -49,6 +49,17 @@
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :bank-account %])
:value @(re-frame/subscribe [::data-page/filter data-page :bank-account])}]]
[:p.menu-label "Financial Account"]
[:div
[typeahead-entity {:matches accounts
:match->text (fn [x ] (str (:numeric-code x) " - " (:name x)))
:include-keys [:name :id :numeric-code]
:type "typeahead-entity"
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :account %])
:value @(re-frame/subscribe [::data-page/filter data-page :account])}]]
[:p.menu-label "Vendor"]
[:div
[typeahead-entity {:matches @(re-frame/subscribe [::subs/searchable-vendors])
@@ -58,22 +69,15 @@
:type "typeahead-entity"
:value @(re-frame/subscribe [::data-page/filter data-page :vendor])}]]
[:p.menu-label "Account"]
[:div
[typeahead-entity {:matches accounts
:match->text (fn [x ] (str (:numeric-code x) " - " (:name x)))
:include-keys [:name :id :numeric-code]
:type "typeahead-entity"
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :account %])
:value @(re-frame/subscribe [::data-page/filter data-page :account])}]]
[:p.menu-label "Amount"]
[:div
[number-filter
{:on-change-event [::data-page/filter-changed data-page :amount-range]
:value @(re-frame/subscribe [::data-page/filter data-page :amount-range])}]]
[:p.menu-label "Date Range"]
[:div
[date-range-filter
{:on-change-event [::data-page/filter-changed data-page :date-range]
:value @(re-frame/subscribe [::data-page/filter data-page :date-range])}]]])]]))
:value @(re-frame/subscribe [::data-page/filter data-page :date-range])}]]
[:p.menu-label "Amount"]
[:div
[number-filter
{:on-change-event [::data-page/filter-changed data-page :amount-range]
:value @(re-frame/subscribe [::data-page/filter data-page :amount-range])}]]])]]))

View File

@@ -28,6 +28,7 @@
:client-id (:id @(re-frame/subscribe [::subs/client]))
:vendor-id (:id (:vendor params))
:date-range (:date-range params)
:account-id (:id (:account params))
:bank-account-id (:id (:bank-account params))
:amount-gte (:amount-gte (:amount-range params))
:amount-lte (:amount-lte (:amount-range params))

View File

@@ -10,11 +10,10 @@
[re-frame.core :as re-frame]
[auto-ap.views.pages.data-page :as data-page]))
(defn side-bar [{:keys [data-page]}]
(let [ap @(re-frame/subscribe [::subs/active-page])
user @(re-frame/subscribe [::subs/user])]
user @(re-frame/subscribe [::subs/user])
accounts @(re-frame/subscribe [::subs/accounts])]
[:div
[:div [:p.menu-label "Type"]
[:ul.menu-list
@@ -57,11 +56,25 @@
:value @(re-frame/subscribe [::data-page/filter data-page :bank-account])
:bank-accounts @(re-frame/subscribe [::subs/bank-accounts])}]]
[:p.menu-label "Date Range"]
[:div
[date-range-filter
{:on-change-event [::data-page/filter-changed data-page :date-range]
:value @(re-frame/subscribe [::data-page/filter data-page :date-range])}]]
[:p.menu-label "Financial Account"]
[:div
[typeahead-entity {:matches accounts
:match->text (fn [x ] (str (:numeric-code x) " - " (:name x)))
:include-keys [:name :id :numeric-code]
:type "typeahead-entity"
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :account %])
:value @(re-frame/subscribe [::data-page/filter data-page :account])}]]
[:p.menu-label "Vendor"]
[:div
[typeahead-entity {:matches @(re-frame/subscribe [::subs/searchable-vendors])
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :vendor %])
:include-keys [:name :id]
:match->text :name
:type "typeahead-entity"
:value @(re-frame/subscribe [::data-page/filter data-page :vendor])}]]
[:p.menu-label "Amount"]
[:div
@@ -69,14 +82,13 @@
{:on-change-event [::data-page/filter-changed data-page :amount-range]
:value @(re-frame/subscribe [::data-page/filter data-page :amount-range])}]]
[:p.menu-label "Vendor"]
[:div
[typeahead-entity {:matches @(re-frame/subscribe [::subs/searchable-vendors])
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :vendor %])
:include-keys [:name :id]
:match->text :name
:type "typeahead-entity"
:value @(re-frame/subscribe [::data-page/filter data-page :vendor])}]]
[:p.menu-label "Date Range"]
[:div
[date-range-filter
{:on-change-event [::data-page/filter-changed data-page :date-range]
:value @(re-frame/subscribe [::data-page/filter data-page :date-range])}]]
[:p.menu-label "Description"]
[:div