 (defn- update-projections [state event]
   (-> state
       (congregation/congregations-view event)
-      (gis-user/gis-users-view event)))
+      (gis-user/gis-users-view event)
+      (db-admin/projection event)))
 
-(defn- apply-new-events [conn cached]
-  (let [new-events (event-store/read-all-events conn {:since (:event/global-revision (:last-event cached))})
-        last-event (last new-events)]
-    (if last-event
-      {:last-event last-event
-       :state (reduce update-projections (:state cached) new-events)}
-      cached)))
+(defn- apply-events [cache events]
+  (update cache :state #(reduce update-projections % events)))
+
+(defn- apply-new-events [cache conn]
+  (let [new-events (event-store/read-all-events conn {:since (:event/global-revision (:last-event cache))})]
+    (if (empty? new-events)
+      cache
+      (-> cache
+          (apply-events new-events)
+          (assoc :last-event (last new-events))))))
 
 (defn refresh-now! [conn]
   (let [cached @*cache
-        updated (apply-new-events conn cached)]
+        updated (apply-new-events cached conn)]
     (when-not (identical? cached updated)
       ;; with concurrent requests, only one of them will update the cache
       (when (compare-and-set! *cache cached updated)
         (log/info "Updated from revision" (:event/global-revision (:last-event cached))
-                  "to" (:event/global-revision (:last-event updated)))))))
+                  "to" (:event/global-revision (:last-event updated)))))
+
+    (let [transient-events (read-transient-events!)]
+      (when-not (empty? transient-events)
+        (swap! *cache apply-events transient-events)
+        (log/info "Updated with" (count transient-events) "transient events")))))
 
 (defn cached-state []
   (:state @*cache))

  "Calculates the current state from all events, including uncommitted ones,
   but does not update the cache (it could cause dirty reads to others)."
  [conn]
  (:state (apply-new-events conn @*cache)))


(mount/defstate refresher
  :start (poller/create (fn []
                          (db/with-db [conn {}]
                            (refresh-now! conn))))
  :stop (poller/shutdown! refresher))

(defn refresh-async! []

            [mount.core :as mount]
            [territory-bro.congregation :as congregation]
            [territory-bro.db :as db]
            [territory-bro.db-admin :as db-admin]
            [territory-bro.event-store :as event-store]
            [territory-bro.gis-user :as gis-user]
            [territory-bro.poller :as poller])
  (:import (com.google.common.util.concurrent ThreadFactoryBuilder)
           (java.util.concurrent Executors ScheduledExecutorService TimeUnit)))

(mount/defstate *transient-events
  :start (atom []))

(defn read-transient-events! []
  (let [[new-events _] (reset-vals! *transient-events [])]
    new-events))

(defn dispatch-transient-event! [event]
  (assert (:event/transient? event) {:event event})
  (swap! *transient-events conj event))

(mount/defstate *cache
  :start (atom {:last-event nil
