 (defresource page-rotation [id]
   :allowed-methods #{:post}
   :available-media-types +default-media-types+
+  :malformed? (fn [ctx]
+                (try
+                  (let [id (Integer/parseInt id)
+                        rotation (get-in ctx [:request :body :rotation])]
+                    (if (and (integer? rotation)
+                             (zero? (mod rotation 90)))
+                      [false {::rotation (mod rotation 360)
+                              ::id id}]
+                      [true "Invalid rotation"]))
+                  (catch NumberFormatException e
+                    [true "Malformed ID"])))
   :exists? (fn [ctx]
              (let [db (get-in ctx [:request ::db])
-                   [{:keys [id]}] (db/query db ["SELECT id FROM pages WHERE id = ?" (Integer/parseInt id)])]
+                   [{:keys [id]}] (db/query db ["SELECT id FROM pages WHERE id = ?" (::id ctx)])]
                (when id {::page-id id})))
   :can-post-to-missing? false
-  :malformed? (fn [ctx]
-                (let [rotation (get-in ctx [:request :body :rotation])]
-                  (if (and (integer? rotation)
-                           (zero? (mod rotation 90)))
-                    [false {::rotation (mod rotation 360)}]
-                    [true "Invalid rotation"])))
+
   :post! (fn [ctx]
            (let [db (get-in ctx [:request ::db])
                  id (::page-id ctx)

(defresource page [id]
  :allowed-methods #{:get}
  :available-media-types ["application/transit+json"]
  :exists? (fn [ctx]
             (when-let [page (first (m/get-pages (get-in ctx [:request ::db])
                                                 [(Integer/parseInt id)]))]
               {::page (select-keys page
                                    [:id :render-status :rotation])}))
  :handle-ok ::page)

(defresource page-image [id size]
  :allowed-methods #{:get}
  :available-media-types ["image/png"]
  :exists? (fn [ctx]
             (try
               (let [db (get-in ctx [:request ::db])
                     config (get-in ctx [:request ::config])
                     [{:keys [image hash]}] (if (= size ::max)
                                              (db/query db ["SELECT image, hash FROM page_images WHERE page = ? ORDER BY dpi DESC LIMIT 1"
                                                            (Integer/parseInt id)])
                                              (db/query db ["SELECT image, hash FROM page_images WHERE page = ? AND dpi = ?"
                                                            (Integer/parseInt id) (Integer/parseInt size)]))]
                 (when image
                   {::page (ByteArrayInputStream. image)
                    ::hash hash}))

                     tagging (get-in request [::config :tagging])]
                 ;; NOTE: auto-tag*! so we don't trigger updates on the notification bus
                 (m/auto-tag*! conn id tagging
                               {:origin origin})
                 {::document (m/get-document conn id)}))))
  :handle-created ::document
  :handle-ok (fn [ctx]
