        ; nicknames are unique, so take the first
        first))
 
-(defn valid-user-id? [user-id]
-  (some? (get-in @app-state [:users user-id])))
-
-(defn id->thread [thread-id]
-  (get-in @app-state [:threads thread-id]))
-
-(defn open-thread? [thread-id]
-  (contains? (set (get-in @app-state [:user :open-thread-ids])) thread-id))
-
-(defn pagination-remaining []
-  (get @app-state :pagination-remaining 0))
-
-(defn all-tags []
-  (vals (get-in @app-state [:tags])))
-
-(defn tags-in-group [group-id]
-  (filter #(= group-id (% :group-id)) (vals (@app-state :tags))))
-
-(defn tags-in-open-group []
-  (tags-in-group (@app-state :open-group-id)))
-
-(defn tag-in-open-group? [tag-id]
-  (= (get-in @app-state [:tags tag-id :group-id]) (@app-state :open-group-id)))
+; used in handlers/extract-tag-ids
 
 (defn name->open-tag-id
   "Lookup tag by name in the open group"


; GETTERS

(defn all-users []
  (vals (get-in @app-state [:users])))

(defn users-in-group [group-id]
  (filter (fn [u] (contains? (set (u :group-ids)) group-id)) (vals (@app-state :users))))

(defn users-in-open-group []
  (users-in-group (@app-state :open-group-id)))

(defn user-in-open-group? [user-id]
  (contains? (set (get-in @app-state [:users user-id :group-ids])) (@app-state :open-group-id)))

(defn nickname->user [nickname]
  (->> (get-in @app-state [:users])


(def check-app-state! (s/validator AppState))

(defn transact! [v]
  (let [old-state @app-state]
    (reset! app-state v)
