 
 (defn index-post! [store ctx]
   (db/with-session [session (:hecuba-session store)]
-    (let [request    (-> ctx :request)
-          profile    (-> ctx :body)
-          entity_id  (-> profile :entity_id)
-          timestamp  (-> profile :timestamp)
+    (let [{:keys [request profile]} ctx
+          {:keys [entity_id timestamp]} profile
           username   (sec/session-username (-> ctx :request :session))
           ;; FIXME: Why user_id?
           user_id    (-> (db/execute session (hayt/select :users (hayt/where [[= :username username]]))) first :id)
           profile_id (sha1/gen-key :profile profile)]
       (when (and entity_id timestamp)
         (when-not (empty? (-> (db/execute session (hayt/select :entities (hayt/where [[= :id entity_id]]))) first))
-          (db/execute session (hayt/insert :profiles (-> profile
-                                                         (assoc :user_id user_id)
-                                                         (update-stringified-lists
-                                                          [:airflow_measurements :chps
-                                                           :conservatories :door_sets
-                                                           :extensions :floors :heat_pumps
-                                                           :heating_systems :hot_water_systems
-                                                           :low_energy_lights :photovoltaics
-                                                           :roof_rooms :roofs :small_hydros
-                                                           :solar_thermals :storeys :thermal_images
-                                                           :ventilation_systems :walls
-                                                           :wind_turbines :window_sets])
-                                                         (update-in [:profile_data] json/encode)
-                                                         )))
-          {:profile_id profile_id})))))
+          (let [query-profile (-> profile
+                                 (assoc :user_id user_id)
+                                 (update-stringified-lists
+                                  [:airflow_measurements :chps
+                                   :conservatories :door_sets
+                                   :extensions :floors :heat_pumps
+                                   :heating_systems :hot_water_systems
+                                   :low_energy_lights :photovoltaics
+                                   :roof_rooms :roofs :small_hydros
+                                   :solar_thermals :storeys :thermal_images
+                                   :ventilation_systems :walls
+                                   :wind_turbines :window_sets])
+                                 (update-in [:profile_data] json/encode))]
+          (db/execute session (hayt/insert :profiles (hayt/values query-profile)))
+          {:profile_id profile_id}))))))
 
 
 (defresource index [store]


(defn resource-put! [store ctx]
  (db/with-session [session (:hecuba-session store)]
    (let [{request :request} ctx]
      (if-let [item (::item ctx)]
        (let [body       (decode-body request)
              entity_id  (-> item :entity_id)
              username   (sec/session-username (-> ctx :request :session))
              user_id    (:id (users/get-by-username session username))
              profile_id (-> item :profile-id)]
          (db/execute session (hayt/insert :profiles (hayt/values (-> body
                                                                      (assoc :id profile_id)
                                                                      (assoc :user_id user_id)
                                                                      ;; TODO: add storeys, walls, etc.
                                                                      stringify-values)))))
        (ring-response {:status 404 :body "Please provide valid entity_id and timestamp"})))))

(defn resource-handle-ok [store ctx]

                                           (explode-associated-items attr (item (:name attr)))))))))]
    exploded-item))

(defn extract-attribute [attr-key input]
  (let [attr-name (name attr-key)
        attr-value (input attr-name)]
  {attr-key attr-value}))

(defn extract-nested-item [attr input]
  (let [association-name   (:name   attr)
        association-schema (:schema attr)
        nested-item (->> association-schema
                         (reduce
                           (fn [nested-item nested-attr]
                             (let [nested-attr-name (name nested-attr)
                                   exploded-attr-name (str (name association-name) "_" nested-attr-name)]
                               (conj nested-item { nested-attr (input exploded-attr-name)})))
                           {}))]
    {association-name nested-item}))

(defn extract-associated-item [association-name association-schema input index]
  (->> association-schema
    (reduce
      (fn [associated-item associated-item-attr]
        (let [associated-item-attr-name (name associated-item-attr)
              exploded-attr-name (str (name association-name) "_" index "_" associated-item-attr-name)]
          (conj associated-item { associated-item-attr (input exploded-attr-name)})))
      {})))

(defn extract-associated-items [attr input]
  (let [association-name   (:name attr)
        association-schema (:schema attr)
        attribute-names    (doall (keys input))
        items-id-pattern   (re-pattern (str (name association-name) "_(\\d+)_"))
        items-ids (reduce conj #{} (->> attribute-names
                                        (map #(when-some [x (re-find items-id-pattern %)] (last x)))
                                        (filter #(not (nil? %)))))
        associated-items (map #(extract-associated-item association-name association-schema input %) items-ids) ]
    {association-name associated-items}))

(defn parse-by-schema [input schema]
  (->> schema
       (reduce
         (fn [item attr]
           (let [t (attribute-type attr)
                 imploded-attribute (case t
                   :attribute               (extract-attribute attr input)
                   :nested-item             (extract-nested-item attr input)
                   :associated-items        (extract-associated-items attr input))]
             (conj item imploded-attribute)))
         {})))

(defn index-malformed? [ctx]
