   (let [{:keys [queue complete]} app
         complete (conj complete {:status result, :item (peek queue)})
         queue (pop queue)]
-    (util/store :records {:queue queue, :complete complete})
+    (store-in-records complete)
     (assoc app :direction :forward, :queue queue, :complete complete)))
 
 (defn- approve [app]

(defn- last-action [app]
  (:status (peek (:complete app))))

;; Given a result keyword :approved or :rejected and an app state cursor,
;; removes the current item from the queue and adds it to the complete stack as
;; a vector in the form {:status result, :item <item>}.

(defn- undo [app]
  (om/transact! app
    (fn [app]
      (let [{:keys [queue complete]} app
            queue (conj queue (:item (peek complete)))
            complete (pop complete)]
        (store-in-records complete)
        (assoc app :direction :backward, :queue queue, :complete complete)))))

(defn- load-initial-data [app]
  (go (let [data (sort-by :id (<! (util/get-json data-url)))]
        (if-let [[queue complete] (restore-from-records data)]
          ; restore records from localStorage without loading JSON
          (om/transact! app
            (fn [app]
              (.log js/console "...restored state from localStorage!")
              (assoc app
                     :ready? true
                     :queue queue
                     :complete complete)))
          ; load data from JSON, then set it in the app
          (om/transact! app
            (fn [app]
              (.log js/console "...loaded data from JSON!")
              (assoc app
                     :ready? true
                     :queue (into cljs.core.PersistentQueue.EMPTY data))))))))

;; Given an input channel of KEYDOWN events, returns an output channel of
;; :approve, :reject, and :undo action keywords. Keystrokes not corresponding
