Repository: CSCfi/rems
Pull request #1198 (2019-05-03 07:59:49)

move round-based application code to rems.db.applications.legacy
part 1 out of several


Patch:
diff --git a/src/clj/rems/db/applications.clj b/src/clj/rems/db/applications.clj
index 2c3dd06c5..07be41991 100644
--- a/src/clj/rems/db/applications.clj
+++ b/src/clj/rems/db/applications.clj
@@ -6,7 +6,6 @@
             [clojure.test :refer [deftest is]]
             [conman.core :as conman]
             [cprop.tools :refer [merge-maps]]
-            [rems.application-util :refer [form-fields-editable?]]
             [rems.application.events :as events]
             [rems.application.model :as model]
             [rems.auth.util :refer [throw-forbidden]]
@@ -35,11 +34,6 @@
   [application-id]
   (nil? application-id))
 
-(declare get-application-state)
-
-(defn- not-empty? [args]
-  ((complement empty?) args))
-
 ;;; Query functions
 
 (declare is-dynamic-application?)
@@ -47,94 +41,8 @@
 (declare fix-workflow-from-db)
 (declare is-dynamic-handler?)
 
-(defn- is-actor? [user-id actors]
-  (assert user-id)
-  (assert actors)
-  (contains? (set actors) user-id))
-
-(defn can-act-as?
-  [user-id application role]
-  (assert user-id)
-  (assert application)
-  (assert role)
-  (or (and (= "applied" (:state application))
-           (is-actor? user-id (actors/get-by-role (:id application) (:curround application) role)))
-      (and (= "approver" role)
-           (contains? (dynamic/possible-commands user-id (get-application-state (:id application)))
-                      :application.command/approve))))
-
-(declare get-application-state)
-
-(defn- has-actor-role? [user-id application-id role]
-  (assert user-id)
-  (assert application-id)
-  (assert role)
-  (or (is-actor? user-id (actors/get-by-role application-id role))
-      (is-dynamic-handler? user-id (get-application-state application-id))))
-
-(defn can-approve? [user-id application]
-  (assert user-id)
-  (assert application)
-  (can-act-as? user-id application "approver"))
-
-(defn- is-approver? [user-id application-id]
-  (assert user-id)
-  (assert application-id)
-  (has-actor-role? user-id application-id "approver"))
-
-(defn- can-review? [user-id application]
-  (assert user-id)
-  (assert application)
-  (can-act-as? user-id application "reviewer"))
-
-(defn- is-reviewer? [user-id application-id]
-  (has-actor-role? user-id application-id "reviewer"))
-
-(defn- is-third-party-reviewer?
-  "Checks if a given user has been requested to review the given application.
-   Additionally a specific round can be provided to narrow the check to apply only to the given round."
-  ([user application]
-   (->> (:events application)
-        (filter #(and (= "review-request" (:event %)) (= user (:userid %))))
-        (not-empty?)))
-  ([user round application]
-   (is-third-party-reviewer? user (update application :events (fn [events] (filter #(= round (:round %)) events))))))
-
-(defn can-third-party-review?
-  "Checks if the current user can perform a 3rd party review action on the current round for the given application."
-  [user-id application]
-  (and (= "applied" (:state application))
-       (is-third-party-reviewer? user-id (:curround application) application)))
-
-(defn is-applicant? [user-id application]
-  (assert user-id)
-  (assert application)
-  (= user-id (:applicantuserid application)))
-
-(defn may-see-application? [user-id application]
-  (assert user-id)
-  (assert application)
-  (let [application-id (:id application)]
-    (or (is-applicant? user-id application)
-        (is-approver? user-id application-id)
-        (is-reviewer? user-id application-id)
-        (is-third-party-reviewer? user-id application)
-        (model/see-application? application user-id))))
-
-(defn can-close? [user-id application]
-  (assert user-id)
-  (assert application)
-  (let [application-id (:id application)]
-    (or (and (is-approver? user-id application-id)
-             (= "approved" (:state application)))
-        (and (is-applicant? user-id application)
-             (not= "closed" (:state application))))))
-
-(defn can-withdraw? [user-id application]
-  (assert user-id)
-  (assert application)
-  (and (is-applicant? user-id application)
-       (= (:state application) "applied")))
+;;; Form & field stuff
+;; TODO these should be in rems.db.form or so
 
 (defn- get-field-value [field form-id application-id]
   (let [query-params {:item (:id field)
@@ -189,150 +97,6 @@
            "")
    :maxlength (:maxlength field)})
 
-(defn- assoc-field-previous-values [application fields]
-  (let [previous-values (:items (if (form-fields-editable? application)
-                                  (:submitted-form-contents application)
-                                  (:previous-submitted-form-contents application)))]
-    (for [field fields]
-      (assoc field :previous-value (get previous-values (:id field))))))
-
-(defn- process-license
-  [application license]
-  (let [app-id (:id application)
-        app-user (:applicantuserid application)
-        license-id (:id license)]
-    (-> license
-        (assoc :type "license"
-               :approved (= "approved"
-                            (:state
-                             (when application
-                               (db/get-application-license-approval {:catappid app-id
-                                                                     :licid license-id
-                                                                     :actoruserid app-user}))))))))
-
-(defn get-application-licenses [application catalogue-item-ids]
-  (mapv #(process-license application %)
-        (licenses/get-active-licenses
-         (or (:start application) (time/now))
-         {:wfid (:wfid application) :items catalogue-item-ids})))
-
-;;; Application phases
-
-(defn get-application-phases [state]
-  (cond (contains? #{"rejected" :application.state/rejected} state)
-        [{:phase :apply :completed? true :text :t.phases/apply}
-         {:phase :approve :completed? true :rejected? true :text :t.phases/approve}
-         {:phase :result :completed? true :rejected? true :text :t.phases/rejected}]
-
-        (contains? #{"approved" :application.state/approved} state)
-        [{:phase :apply :completed? true :text :t.phases/apply}
-         {:phase :approve :completed? true :approved? true :text :t.phases/approve}
-         {:phase :result :completed? true :approved? true :text :t.phases/approved}]
-
-        (contains? #{"closed" :application.state/closed} state)
-        [{:phase :apply :closed? true :text :t.phases/apply}
-         {:phase :approve :closed? true :text :t.phases/approve}
-         {:phase :result :closed? true :text :t.phases/approved}]
-
-        (contains? #{"draft" "returned" "withdrawn" :application.state/draft} state)
-        [{:phase :apply :active? true :text :t.phases/apply}
-         {:phase :approve :text :t.phases/approve}
-         {:phase :result :text :t.phases/approved}]
-
-        (contains? #{"applied" :application.state/submitted} state)
-        [{:phase :apply :completed? true :text :t.phases/apply}
-         {:phase :approve :active? true :text :t.phases/approve}
-         {:phase :result :text :t.phases/approved}]
-
-        :else
-        [{:phase :apply :active? true :text :t.phases/apply}
-         {:phase :approve :text :t.phases/approve}
-         {:phase :result :text :t.phases/approved}]))
-
-(defn get-form-for
-  "Returns a form structure like this:
-
-    {:id 7
-     :title \"Title\"
-     :application {:id 3
-                   :state \"draft\"
-                   :review-type :normal
-                   :can-approve? false
-                   :can-close? true
-                   :can-withdraw? false
-                   :can-third-party-review? false
-                   :is-applicant? true
-                   :workflow {...}
-                   :possible-actions #{...}}
-     :applicant-attributes {\"eppn\" \"developer\"
-                            \"email\" \"developer@e.mail\"
-                            \"displayName\" \"deve\"
-                            \"surname\" \"loper\"
-                            ...}
-     :catalogue-items [{:application 3 :item 123}]
-     :items [{:id 123
-              :type \"texta\"
-              :title \"Item title\"
-              :inputprompt \"hello\"
-              :optional true
-              :value \"filled value or nil\"}
-             ...]
-     :licenses [{:id 2
-                 :type \"license\"
-                 :licensetype \"link\"
-                 :title \"LGPL\"
-                 :textcontent \"http://foo\"
-                 :localizations {\"fi\" {:title \"...\" :textcontent \"...\"}}
-                 :approved false}]
-     :phases [{:phase :apply :active? true :text :t.phases/apply}
-              {:phase :approve :text :t.phases/approve}
-              {:phase :result :text :t.phases/approved}]}"
-  ([user-id application-id]
-   (let [form (db/get-form-for-application {:application application-id})
-         _ (assert form)
-         application (get-application-state application-id)
-         application (if (is-dynamic-application? application)
-                       (dynamic/assoc-possible-commands user-id application) ; TODO move even higher?
-                       application)
-         _ (assert application)
-         form-id (:formid form)
-         _ (assert form-id)
-         catalogue-item-ids (mapv :item (db/get-application-items {:application application-id}))
-         catalogue-items (catalogue/get-localized-catalogue-items {:ids catalogue-item-ids})
-         items (->> (db/get-form-items {:id form-id})
-                    (mapv #(process-field application-id form-id %))
-                    (assoc-field-previous-values application))
-         description (-> (filter #(= "description" (:type %)) items)
-                         first
-                         :value)
-         licenses (get-application-licenses application catalogue-item-ids)
-         review-type (cond
-                       (can-review? user-id application) :normal
-                       (can-third-party-review? user-id application) :third-party
-                       :else nil)]
-     (when application-id
-       (when-not (may-see-application? user-id application)
-         (throw-forbidden)))
-     {:id form-id
-      :title (:formtitle form)
-      :catalogue-items catalogue-items
-      :application (-> application
-                       (assoc :formid form-id
-                              :catalogue-items catalogue-items ;; TODO decide if catalogue-items are part of "form" or "application"
-                              :can-approve? (can-approve? user-id application)
-                              :can-close? (can-close? user-id application)
-                              :can-withdraw? (can-withdraw? user-id application)
-                              :can-third-party-review? (can-third-party-review? user-id application)
-                              :is-applicant? (is-applicant? user-id application)
-                              :review-type review-type
-                              :description description)
-                       (permissions/cleanup))
-      :applicant-attributes (users/get-user-attributes (:applicantuserid application))
-      :items items
-      :licenses licenses
-      :accepted-licenses (get-in application [:form-contents :accepted-licenses])
-      :phases (get-application-phases (:state application))})))
-
 (defn create-new-draft [user-id wfid]
   (assert user-id)
   (assert wfid)
@@ -341,249 +105,6 @@
 (defn create-new-draft-at-time [user-id wfid time]
   (:id (db/create-application! {:user user-id :wfid wfid :start time})))
 
-;;; Applying events
-
-(defmulti ^:private apply-event
-  "Applies an event to an application state."
-  ;; dispatch by event type
-  (fn [_application event] (:event event)))
-
-(defn get-event-types
-  "Fetch sequence of supported event names."
-  []
-  (keys (methods apply-event)))
-
-(defmethod apply-event "save"
-  [application _event]
-  application)
-
-(defmethod apply-event "apply"
-  [application event]
-  (assert (#{"draft" "returned" "withdrawn"} (:state application))
-          (str "Can't submit application " (pr-str application)))
-  (assert (= (:round event) 0)
-          (str "Apply event should have round 0" (pr-str event)))
-  (assoc application :state "applied" :curround 0))
-
-(defn- apply-approve [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't approve application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and approval rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (if (= (:curround application) (:fnlround application))
-    (assoc application :state "approved")
-    (assoc application :state "applied" :curround (inc (:curround application)))))
-
-(defmethod apply-event "approve"
-  [application event]
-  (apply-approve application event))
-
-(defmethod apply-event "autoapprove"
-  [application event]
-  (apply-approve application event))
-
-(defmethod apply-event "reject"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't reject application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and rejection rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (assoc application :state "rejected"))
-
-(defmethod apply-event "return"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't return application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and rejection rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (assoc application :state "returned" :curround 0))
-
-(defmethod apply-event "review"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't review application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and review rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (if (= (:curround application) (:fnlround application))
-    (assoc application :state "approved")
-    (assoc application :state "applied" :curround (inc (:curround application)))))
-
-(defmethod apply-event "third-party-review"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't review application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and review rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (assoc application :state "applied"))
-
-(defmethod apply-event "review-request"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't send a review request " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and review request rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (assoc application :state "applied"))
-
-(defmethod apply-event "withdraw"
-  [application event]
-  (assert (= (:state application) "applied")
-          (str "Can't withdraw application " (pr-str application)))
-  (assert (= (:curround application) (:round event))
-          (str "Application and withdrawal rounds don't match: "
-               (pr-str application) " vs. " (pr-str event)))
-  (assoc application :state "withdrawn" :curround 0))
-
-(defmethod apply-event "close"
-  [application event]
-  (assoc application :state "closed"))
-
-(defn- apply-events [application events]
-  (reduce apply-event application events))
-
-;;; Public event api
-
-(defn get-application-state ; TODO: legacy code; remove me
-  ([application-id]
-   (get-application-state (first (db/get-applications {:id application-id}))
-                          (map #(dissoc % :id :appid) ; remove keys not in v1 API
-                               (db/get-application-events {:application application-id}))))
-  ([application events]
-   (if (not (nil? (:workflow application)))
-     (get-dynamic-application-state (:id application))
-     (let [application (-> application
-                           (dissoc :workflow)
-                           (assoc :state "draft" :curround 0) ;; reset state
-                           (assoc :events events)
-                           (assoc :last-modified (or (:time (last events))
-                                                     (:start application))))]
-       (apply-events application events)))))
-
-(declare handle-state-change)
-
-(defn try-autoapprove-application
-  "If application can be autoapproved (round has no approvers), add an
-   autoapprove event. Otherwise do nothing."
-  [user-id application]
-  (let [application-id (:id application)
-        round (:curround application)
-        fnlround (:fnlround application)
-        state (:state application)]
-    (when (= "applied" state)
-      (let [approvers (actors/get-by-role application-id round "approver")
-            reviewers (actors/get-by-role application-id round "reviewer")]
-        (when (and (empty? approvers)
-                   (empty? reviewers)
-                   (<= round fnlround))
-          (db/add-application-event! {:application application-id :user user-id
-                                      :round round :event "autoapprove" :comment nil})
-          true)))))
-
-(defn handle-state-change [user-id application-id]
-  (let [application (get-application-state application-id)]
-    (entitlements/update-entitlements-for application)
-    (when (try-autoapprove-application user-id application)
-      (recur user-id application-id))))
-
-(defn submit-application [applicant-id application-id]
-  (assert applicant-id)
-  (assert application-id)
-  (let [application (get-application-state application-id)]
-    (when-not (= applicant-id (:applicantuserid application))
-      (throw-forbidden))
-    (when-not (#{"draft" "returned" "withdrawn"} (:state application))
-      (throw-forbidden))
-    (db/add-application-event! {:application application-id :user applicant-id
-                                :round 0 :event "apply" :comment nil})
-    (handle-state-change applicant-id application-id)))
-
-(defn- judge-application [approver-id application-id event round msg]
-  (assert approver-id)
-  (assert application-id)
-  (assert event)
-  (assert round)
-  (assert msg)
-  (let [state (get-application-state application-id)]
-    (when-not (= round (:curround state))
-      (throw-forbidden))
-    (db/add-application-event! {:application application-id :user approver-id
-                                :round round :event event :comment msg})
-    (handle-state-change approver-id application-id)))
-
-(defn approve-application [approver-id application-id round msg]
-  (when-not (can-approve? approver-id (get-application-state application-id))
-    (throw-forbidden))
-  (judge-application approver-id application-id "approve" round msg))
-
-(defn reject-application [user-id application-id round msg]
-  (when-not (can-approve? user-id (get-application-state application-id))
-    (throw-forbidden))
-  (judge-application user-id application-id "reject" round msg))
-
-(defn return-application [user-id application-id round msg]
-  (when-not (can-approve? user-id (get-application-state application-id))
-    (throw-forbidden))
-  (judge-application user-id application-id "return" round msg))
-
-(defn review-application [user-id application-id round msg]
-  (when-not (can-review? user-id (get-application-state application-id))
-    (throw-forbidden))
-  (judge-application user-id application-id "review" round msg))
-
-(defn perform-third-party-review [user-id application-id round msg]
-  (let [application (get-application-state application-id)]
-    (when-not (can-third-party-review? user-id application)
-      (throw-forbidden))
-    (when-not (= round (:curround application))
-      (throw-forbidden))
-    (db/add-application-event! {:application application-id :user user-id
-                                :round round :event "third-party-review" :comment msg})))
-
-(defn send-review-request [user-id application-id round msg recipients]
-  (let [application (get-application-state application-id)]
-    (when-not (can-approve? user-id application)
-      (throw-forbidden))
-    (when-not (= round (:curround application))
-      (throw-forbidden))
-    (assert (not-empty? recipients)
-            (str "Can't send a review request without recipients."))
-    (let [send-to (if (vector? recipients)
-                    recipients
-                    (vector recipients))]
-      (doseq [recipient send-to]
-        (when-not (is-third-party-reviewer? recipient (:curround application) application)
-          (db/add-application-event! {:application application-id :user recipient
-                                      :round round :event "review-request" :comment msg}))))))
-
-;; TODO better name
-;; TODO consider refactoring together with judge
-(defn- unjudge-application
-  "Action handling for both approver and applicant."
-  [user-id application event round msg]
-  (let [application-id (:id application)]
-    (when-not (= round (:curround application))
-      (throw-forbidden))
-    (db/add-application-event! {:application application-id :user user-id
-                                :round round :event event :comment msg})
-    (handle-state-change user-id application-id)))
-
-(defn withdraw-application [applicant-id application-id round msg]
-  (let [application (get-application-state application-id)]
-    (when-not (can-withdraw? applicant-id application)
-      (throw-forbidden))
-    (unjudge-application applicant-id application "withdraw" round msg)))
-
-(defn close-application [user-id application-id round msg]
-  (let [application (get-application-state application-id)]
-    (when-not (can-close? user-id application)
-      (throw-forbidden))
-    (unjudge-application user-id application "close" round msg)))
-
 ;;; Dynamic workflows
 ;; TODO these should be in their own namespace probably
 
diff --git a/src/clj/rems/db/applications/legacy.clj b/src/clj/rems/db/applications/legacy.clj
new file mode 100644
index 000000000..a057d45c5
--- /dev/null
+++ b/src/clj/rems/db/applications/legacy.clj
@@ -0,0 +1,503 @@
+(ns rems.db.applications.legacy
+  "Functions for dealing with old round-based applications."
+  (:require [clojure.test :refer :all]
+            [clj-time.core :as time]
+            [rems.application.model :as model]
+            [rems.application-util :refer [form-fields-editable?]]
+            [rems.auth.util :refer [throw-forbidden]]
+            [rems.db.workflow-actors :as actors]
+            [rems.db.applications :as applications]
+            [rems.db.core :as db]
+            [rems.db.catalogue :as catalogue]
+            [rems.db.entitlements :as entitlements]
+            [rems.db.licenses :as licenses]
+            [rems.db.users :as users]
+            [rems.permissions :as permissions]
+            [rems.workflow.dynamic :as dynamic]))
+
+(declare get-application-state)
+
+;;; Query functions
+
+
+(defn- is-actor? [user-id actors]
+  (assert user-id)
+  (assert actors)
+  (contains? (set actors) user-id))
+
+(defn can-act-as?
+  [user-id application role]
+  (assert user-id)
+  (assert application)
+  (assert role)
+  (or (and (= "applied" (:state application))
+           (is-actor? user-id (actors/get-by-role (:id application) (:curround application) role)))
+      (and (= "approver" role)
+           (contains? (dynamic/possible-commands user-id (get-application-state (:id application)))
+                      :application.command/approve))))
+
+(defn- has-actor-role? [user-id application-id role]
+  (assert user-id)
+  (assert application-id)
+  (assert role)
+  (or (is-actor? user-id (actors/get-by-role application-id role))
+      (applications/is-dynamic-handler? user-id (get-application-state application-id))))
+
+(defn can-approve? [user-id application]
+  (assert user-id)
+  (assert application)
+  (can-act-as? user-id application "approver"))
+
+(defn- is-approver? [user-id application-id]
+  (assert user-id)
+  (assert application-id)
+  (has-actor-role? user-id application-id "approver"))
+
+(defn can-review? [user-id application]
+  (assert user-id)
+  (assert application)
+  (can-act-as? user-id application "reviewer"))
+
+(defn- is-reviewer? [user-id application-id]
+  (has-actor-role? user-id application-id "reviewer"))
+
+(defn- not-empty? [args]
+  ((complement empty?) args))
+
+(defn- is-third-party-reviewer?
+  "Checks if a given user has been requested to review the given application.
+   Additionally a specific round can be provided to narrow the check to apply only to the given round."
+  ([user application]
+   (->> (:events application)
+        (filter #(and (= "review-request" (:event %)) (= user (:userid %))))
+        (not-empty?)))
+  ([user round application]
+   (is-third-party-reviewer? user (update application :events (fn [events] (filter #(= round (:round %)) events))))))
+
+(defn can-third-party-review?
+  "Checks if the current user can perform a 3rd party review action on the current round for the given application."
+  [user-id application]
+  (and (= "applied" (:state application))
+       (is-third-party-reviewer? user-id (:curround application) application)))
+
+(defn is-applicant? [user-id application]
+  (assert user-id)
+  (assert application)
+  (= user-id (:applicantuserid application)))
+
+(defn may-see-application? [user-id application]
+  (assert user-id)
+  (assert application)
+  (let [application-id (:id application)]
+    (or (is-applicant? user-id application)
+        (is-approver? user-id application-id)
+        (is-reviewer? user-id application-id)
+        (is-third-party-reviewer? user-id application)
+        (model/see-application? application user-id))))
+
+(defn can-close? [user-id application]
+  (assert user-id)
+  (assert application)
+  (let [application-id (:id application)]
+    (or (and (is-approver? user-id application-id)
+             (= "approved" (:state application)))
+        (and (is-applicant? user-id application)
+             (not= "closed" (:state application))))))
+
+(defn can-withdraw? [user-id application]
+  (assert user-id)
+  (assert application)
+  (and (is-applicant? user-id application)
+       (= (:state application) "applied")))
+
+;;; Legacy form stuff
+
+(defn- assoc-field-previous-values [application fields]
+  (let [previous-values (:items (if (form-fields-editable? application)
+                                  (:submitted-form-contents application)
+                                  (:previous-submitted-form-contents application)))]
+    (for [field fields]
+      (assoc field :previous-value (get previous-values (:id field))))))
+
+(defn- process-license
+  [application license]
+  (let [app-id (:id application)
+        app-user (:applicantuserid application)
+        license-id (:id license)]
+    (-> license
+        (assoc :type "license"
+               :approved (= "approved"
+                            (:state
+                             (when application
+                               (db/get-application-license-approval {:catappid app-id
+                                                                     :licid license-id
+                                                                     :actoruserid app-user}))))))))
+
+(defn- get-application-licenses [application catalogue-item-ids]
+  (mapv #(process-license application %)
+        (licenses/get-active-licenses
+         (or (:start application) (time/now))
+         {:wfid (:wfid application) :items catalogue-item-ids})))
+
+;;; Phases
+
+(defn get-application-phases [state]
+  (cond (contains? #{"rejected" :application.state/rejected} state)
+        [{:phase :apply :completed? true :text :t.phases/apply}
+         {:phase :approve :completed? true :rejected? true :text :t.phases/approve}
+         {:phase :result :completed? true :rejected? true :text :t.phases/rejected}]
+
+        (contains? #{"approved" :application.state/approved} state)
+        [{:phase :apply :completed? true :text :t.phases/apply}
+         {:phase :approve :completed? true :approved? true :text :t.phases/approve}
+         {:phase :result :completed? true :approved? true :text :t.phases/approved}]
+
+        (contains? #{"closed" :application.state/closed} state)
+        [{:phase :apply :closed? true :text :t.phases/apply}
+         {:phase :approve :closed? true :text :t.phases/approve}
+         {:phase :result :closed? true :text :t.phases/approved}]
+
+        (contains? #{"draft" "returned" "withdrawn" :application.state/draft} state)
+        [{:phase :apply :active? true :text :t.phases/apply}
+         {:phase :approve :text :t.phases/approve}
+         {:phase :result :text :t.phases/approved}]
+
+        (contains? #{"applied" :application.state/submitted} state)
+        [{:phase :apply :completed? true :text :t.phases/apply}
+         {:phase :approve :active? true :text :t.phases/approve}
+         {:phase :result :text :t.phases/approved}]
+
+        :else
+        [{:phase :apply :active? true :text :t.phases/apply}
+         {:phase :approve :text :t.phases/approve}
+         {:phase :result :text :t.phases/approved}]))
+
+;;; The main entry point, get-form-for
+
+(defn get-form-for
+  "Returns a form structure like this:
+
+    {:id 7
+     :title \"Title\"
+     :application {:id 3
+                   :state \"draft\"
+                   :review-type :normal
+                   :can-approve? false
+                   :can-close? true
+                   :can-withdraw? false
+                   :can-third-party-review? false
+                   :is-applicant? true
+                   :workflow {...}
+                   :possible-actions #{...}}
+     :applicant-attributes {\"eppn\" \"developer\"
+                            \"email\" \"developer@e.mail\"
+                            \"displayName\" \"deve\"
+                            \"surname\" \"loper\"
+                            ...}
+     :catalogue-items [{:application 3 :item 123}]
+     :items [{:id 123
+              :type \"texta\"
+              :title \"Item title\"
+              :inputprompt \"hello\"
+              :optional true
+              :value \"filled value or nil\"}
+             ...]
+     :licenses [{:id 2
+                 :type \"license\"
+                 :licensetype \"link\"
+                 :title \"LGPL\"
+                 :textcontent \"http://foo\"
+                 :localizations {\"fi\" {:title \"...\" :textcontent \"...\"}}
+                 :approved false}]
+     :phases [{:phase :apply :active? true :text :t.phases/apply}
+              {:phase :approve :text :t.phases/approve}
+              {:phase :result :text :t.phases/approved}]}"
+  ([user-id application-id]
+   (let [form (db/get-form-for-application {:application application-id})
+         _ (assert form)
+         application (get-application-state application-id)
+         application (if (applications/is-dynamic-application? application)
+                       (dynamic/assoc-possible-commands user-id application) ; TODO move even higher?
+                       application)
+         _ (assert application)
+         form-id (:formid form)
+         _ (assert form-id)
+         catalogue-item-ids (mapv :item (db/get-application-items {:application application-id}))
+         catalogue-items (catalogue/get-localized-catalogue-items {:ids catalogue-item-ids})
+         items (->> (db/get-form-items {:id form-id})
+                    (mapv #(applications/process-field application-id form-id %))
+                    (assoc-field-previous-values application))
+         description (-> (filter #(= "description" (:type %)) items)
+                         first
+                         :value)
+         licenses (get-application-licenses application catalogue-item-ids)
+         review-type (cond
+                       (can-review? user-id application) :normal
+                       (can-third-party-review? user-id application) :third-party
+                       :else nil)]
+     (when application-id
+       (when-not (may-see-application? user-id application)
+         (throw-forbidden)))
+     {:id form-id
+      :title (:formtitle form)
+      :catalogue-items catalogue-items
+      :application (-> application
+                       (assoc :formid form-id
+                              :catalogue-items catalogue-items ;; TODO decide if catalogue-items are part of "form" or "application"
+                              :can-approve? (can-approve? user-id application)
+                              :can-close? (can-close? user-id application)
+                              :can-withdraw? (can-withdraw? user-id application)
+                              :can-third-party-review? (can-third-party-review? user-id application)
+                              :is-applicant? (is-applicant? user-id application)
+                              :review-type review-type
+                              :description description)
+                       (permissions/cleanup))
+      :applicant-attributes (users/get-user-attributes (:applicantuserid application))
+      :items items
+      :licenses licenses
+      :accepted-licenses (get-in application [:form-contents :accepted-licenses])
+      :phases (get-application-phases (:state application))})))
+
+
+;;; Round-based events
+
+(defmulti ^:private apply-event
+  "Applies an event to an application state."
+  ;; dispatch by event type
+  (fn [_application event] (:event event)))
+
+(defn get-event-types
+  "Fetch sequence of supported event names."
+  []
+  (keys (methods apply-event)))
+
+(defmethod apply-event "save"
+  [application _event]
+  application)
+
+(defmethod apply-event "apply"
+  [application event]
+  (assert (#{"draft" "returned" "withdrawn"} (:state application))
+          (str "Can't submit application " (pr-str application)))
+  (assert (= (:round event) 0)
+          (str "Apply event should have round 0" (pr-str event)))
+  (assoc application :state "applied" :curround 0))
+
+(defn- apply-approve [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't approve application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and approval rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (if (= (:curround application) (:fnlround application))
+    (assoc application :state "approved")
+    (assoc application :state "applied" :curround (inc (:curround application)))))
+
+(defmethod apply-event "approve"
+  [application event]
+  (apply-approve application event))
+
+(defmethod apply-event "autoapprove"
+  [application event]
+  (apply-approve application event))
+
+(defmethod apply-event "reject"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't reject application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and rejection rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (assoc application :state "rejected"))
+
+(defmethod apply-event "return"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't return application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and rejection rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (assoc application :state "returned" :curround 0))
+
+(defmethod apply-event "review"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't review application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and review rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (if (= (:curround application) (:fnlround application))
+    (assoc application :state "approved")
+    (assoc application :state "applied" :curround (inc (:curround application)))))
+
+(defmethod apply-event "third-party-review"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't review application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and review rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (assoc application :state "applied"))
+
+(defmethod apply-event "review-request"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't send a review request " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and review request rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (assoc application :state "applied"))
+
+(defmethod apply-event "withdraw"
+  [application event]
+  (assert (= (:state application) "applied")
+          (str "Can't withdraw application " (pr-str application)))
+  (assert (= (:curround application) (:round event))
+          (str "Application and withdrawal rounds don't match: "
+               (pr-str application) " vs. " (pr-str event)))
+  (assoc application :state "withdrawn" :curround 0))
+
+(defmethod apply-event "close"
+  [application event]
+  (assoc application :state "closed"))
+
+(defn- apply-events [application events]
+  (reduce apply-event application events))
+
+;;; Round-based public api
+
+(defn get-application-state
+  ([application-id]
+   (get-application-state (first (db/get-applications {:id application-id}))
+                          (map #(dissoc % :id :appid) ; remove keys not in v1 API
+                               (db/get-application-events {:application application-id}))))
+  ([application events]
+   (if (not (nil? (:workflow application)))
+     (applications/get-dynamic-application-state (:id application))
+     (let [application (-> application
+                           (dissoc :workflow)
+                           (assoc :state "draft" :curround 0) ;; reset state
+                           (assoc :events events)
+                           (assoc :last-modified (or (:time (last events))
+                                                     (:start application))))]
+       (apply-events application events)))))
+
+(declare handle-state-change)
+
+(defn try-autoapprove-application
+  "If application can be autoapproved (round has no approvers), add an
+   autoapprove event. Otherwise do nothing."
+  [user-id application]
+  (let [application-id (:id application)
+        round (:curround application)
+        fnlround (:fnlround application)
+        state (:state application)]
+    (when (= "applied" state)
+      (let [approvers (actors/get-by-role application-id round "approver")
+            reviewers (actors/get-by-role application-id round "reviewer")]
+        (when (and (empty? approvers)
+                   (empty? reviewers)
+                   (<= round fnlround))
+          (db/add-application-event! {:application application-id :user user-id
+                                      :round round :event "autoapprove" :comment nil})
+          true)))))
+
+(defn handle-state-change [user-id application-id]
+  (let [application (get-application-state application-id)]
+    (entitlements/update-entitlements-for application)
+    (when (try-autoapprove-application user-id application)
+      (recur user-id application-id))))
+
+(defn submit-application [applicant-id application-id]
+  (assert applicant-id)
+  (assert application-id)
+  (let [application (get-application-state application-id)]
+    (when-not (= applicant-id (:applicantuserid application))
+      (throw-forbidden))
+    (when-not (#{"draft" "returned" "withdrawn"} (:state application))
+      (throw-forbidden))
+    (db/add-application-event! {:application application-id :user applicant-id
+                                :round 0 :event "apply" :comment nil})
+    (handle-state-change applicant-id application-id)))
+
+(defn- judge-application [approver-id application-id event round msg]
+  (assert approver-id)
+  (assert application-id)
+  (assert event)
+  (assert round)
+  (assert msg)
+  (let [state (get-application-state application-id)]
+    (when-not (= round (:curround state))
+      (throw-forbidden))
+    (db/add-application-event! {:application application-id :user approver-id
+                                :round round :event event :comment msg})
+    (handle-state-change approver-id application-id)))
+
+(defn approve-application [approver-id application-id round msg]
+  (when-not (can-approve? approver-id (get-application-state application-id))
+    (throw-forbidden))
+  (judge-application approver-id application-id "approve" round msg))
+
+(defn reject-application [user-id application-id round msg]
+  (when-not (can-approve? user-id (get-application-state application-id))
+    (throw-forbidden))
+  (judge-application user-id application-id "reject" round msg))
+
+(defn return-application [user-id application-id round msg]
+  (when-not (can-approve? user-id (get-application-state application-id))
+    (throw-forbidden))
+  (judge-application user-id application-id "return" round msg))
+
+(defn review-application [user-id application-id round msg]
+  (when-not (can-review? user-id (get-application-state application-id))
+    (throw-forbidden))
+  (judge-application user-id application-id "review" round msg))
+
+(defn perform-third-party-review [user-id application-id round msg]
+  (let [application (get-application-state application-id)]
+    (when-not (can-third-party-review? user-id application)
+      (throw-forbidden))
+    (when-not (= round (:curround application))
+      (throw-forbidden))
+    (db/add-application-event! {:application application-id :user user-id
+                                :round round :event "third-party-review" :comment msg})))
+
+(defn send-review-request [user-id application-id round msg recipients]
+  (let [application (get-application-state application-id)]
+    (when-not (can-approve? user-id application)
+      (throw-forbidden))
+    (when-not (= round (:curround application))
+      (throw-forbidden))
+    (assert (not-empty? recipients)
+            (str "Can't send a review request without recipients."))
+    (let [send-to (if (vector? recipients)
+                    recipients
+                    (vector recipients))]
+      (doseq [recipient send-to]
+        (when-not (is-third-party-reviewer? recipient (:curround application) application)
+          (db/add-application-event! {:application application-id :user recipient
+                                      :round round :event "review-request" :comment msg}))))))
+
+;; TODO better name
+;; TODO consider refactoring together with judge
+(defn- unjudge-application
+  "Action handling for both approver and applicant."
+  [user-id application event round msg]
+  (let [application-id (:id application)]
+    (when-not (= round (:curround application))
+      (throw-forbidden))
+    (db/add-application-event! {:application application-id :user user-id
+                                :round round :event event :comment msg})
+    (handle-state-change user-id application-id)))
+
+(defn withdraw-application [applicant-id application-id round msg]
+  (let [application (get-application-state application-id)]
+    (when-not (can-withdraw? applicant-id application)
+      (throw-forbidden))
+    (unjudge-application applicant-id application "withdraw" round msg)))
+
+(defn close-application [user-id application-id round msg]
+  (let [application (get-application-state application-id)]
+    (when-not (can-close? user-id application)
+      (throw-forbidden))
+    (unjudge-application user-id application "close" round msg)))
diff --git a/src/clj/rems/form_validation.clj b/src/clj/rems/form_validation.clj
index da4139fd7..a81bca1c7 100644
--- a/src/clj/rems/form_validation.clj
+++ b/src/clj/rems/form_validation.clj
@@ -30,7 +30,7 @@
        (seq)))
 
 (defn validate
-  "Validates a filled in form from (get-form-for application).
+  "Validates a filled in form from (see rems.db.form/get-form).
 
    Returns either :valid or a sequence of validation errors."
   [form]
diff --git a/src/clj/rems/migrations/convert_to_dynamic_applications.clj b/src/clj/rems/migrations/convert_to_dynamic_applications.clj
index 8040969a9..46f111c8c 100644
--- a/src/clj/rems/migrations/convert_to_dynamic_applications.clj
+++ b/src/clj/rems/migrations/convert_to_dynamic_applications.clj
@@ -2,6 +2,7 @@
   (:require [clojure.java.jdbc :as jdbc]
             [conman.core :as conman]
             [rems.db.applications :as applications]
+            [rems.db.applications.legacy :as legacy]
             [rems.db.core :refer [*db*] :as db]
             [rems.db.workflow :as workflow]
             [rems.db.workflow-actors :as actors]
@@ -15,8 +16,8 @@
   (let [read-user (or (first (actors/get-by-role application-id "approver"))
                       ;; auto-approved workflows do not have an approver,
                       ;; so the applicant is the only one who can see the application
-                      (:applicantuserid (applications/get-application-state application-id)))
-        form (applications/get-form-for read-user application-id)
+                      (:applicantuserid (legacy/get-application-state application-id)))
+        form (legacy/get-form-for read-user application-id)
         application (:application form)
         workflow (workflow/get-workflow workflow-id)
         comment-requests-by-commenter (atom {})]
diff --git a/src/cljs/rems/collapsible.cljs b/src/cljs/rems/collapsible.cljs
index 2a98a887c..d118b358c 100644
--- a/src/cljs/rems/collapsible.cljs
+++ b/src/cljs/rems/collapsible.cljs
@@ -10,25 +10,19 @@
 (defn- show-more-button
   [id expanded callback]
   [:div.mb-3.collapse.collapse-toggle {:class (str (str id "more ") (when-not expanded "show"))}
-   [:a {:href "#"
-        :on-click (fn [event]
-                    (.preventDefault event)
-                    (.collapse (js/$ (str "#" id "collapse")) "show")
-                    (.collapse (js/$ (str "." id "more")) "hide")
-                    (when callback
-                      (callback))
-                    (.collapse (js/$ (str "." id "less")) "show"))}
+   [:a {:on-click #(do (.collapse (js/$ (str "#" id "collapse")) "show")
+                       (.collapse (js/$ (str "." id "more")) "hide")
+                       (when callback
+                         (callback))
+                       (.collapse (js/$ (str "." id "less")) "show"))}
     (text :t.collapse/show-more)]])
 
 (defn- show-less-button
   [id expanded]
   [:div.mb-3.collapse.collapse-toggle {:class (str (str id "less ") (when expanded "show"))}
-   [:a {:href "#"
-        :on-click (fn [event]
-                    (.preventDefault event)
-                    (.collapse (js/$ (str "#" id "collapse")) "hide")
-                    (.collapse (js/$ (str "." id "more")) "show")
-                    (.collapse (js/$ (str "." id "less")) "hide"))}
+   [:a {:on-click #(do (.collapse (js/$ (str "#" id "collapse")) "hide")
+                       (.collapse (js/$ (str "." id "more")) "show")
+                       (.collapse (js/$ (str "." id "less")) "hide"))}
     (text :t.collapse/show-less)]])
 
 (defn- block [id expanded callback content-always content-hideable content-footer top-less-button? bottom-less-button?]


Test patch:
diff --git a/src/clj/rems/db/test_data.clj b/src/clj/rems/db/test_data.clj
index 83af70d0c..53552740e 100644
--- a/src/clj/rems/db/test_data.clj
+++ b/src/clj/rems/db/test_data.clj
@@ -3,6 +3,7 @@
   (:require [clj-time.core :as time]
             [rems.context :as context]
             [rems.db.applications :as applications]
+            [rems.db.applications.legacy :as legacy]
             [rems.db.catalogue :as catalogue]
             [rems.db.core :as db]
             [rems.db.form :as form]
@@ -473,8 +474,9 @@
         catids (if (vector? catids) catids [catids])
         _ (doseq [catid catids]
             (db/add-application-item! {:application app-id :item catid}))
+        ;; TODO don't use legacy get-form-for
         form (binding [context/*lang* :en]
-               (applications/get-form-for user-id app-id))
+               (legacy/get-form-for user-id app-id))
         dynamic-workflow? (= :workflow/dynamic (get-in form [:application :workflow :type]))
         save-draft-command (atom {:type :application.command/save-draft
                                   :actor user-id
@@ -516,16 +518,16 @@
   (binding [context/*tempura* (locales/tempura-config)]
     (create-draft! applicant catid wfid "draft application")
     (let [application (create-draft! applicant catid wfid "applied application")]
-      (applications/submit-application applicant application))
+      (legacy/submit-application applicant application))
     (let [application (create-draft! applicant catid wfid "rejected application")]
-      (applications/submit-application applicant application)
-      (applications/reject-application approver application 0 "comment for rejection"))
+      (legacy/submit-application applicant application)
+      (legacy/reject-application approver application 0 "comment for rejection"))
     (let [application (create-draft! applicant catid wfid "accepted application")]
-      (applications/submit-application applicant application)
-      (applications/approve-application approver application 0 "comment for approval"))
+      (legacy/submit-application applicant application)
+      (legacy/approve-application approver application 0 "comment for approval"))
     (let [application (create-draft! applicant catid wfid "returned application")]
-      (applications/submit-application applicant application)
-      (applications/return-application approver application 0 "comment for return"))))
+      (legacy/submit-application applicant application)
+      (legacy/return-application approver application 0 "comment for return"))))
 
 (defn- run-and-check-dynamic-command! [& args]
   (let [result (apply applications/command! args)]
@@ -554,9 +556,9 @@
 (defn- create-bundled-application! [catid catid2 wfid applicant approver]
   (binding [context/*tempura* (locales/tempura-config)]
     (let [app-id (create-draft! applicant [catid catid2] wfid "bundled application")]
-      (applications/submit-application applicant app-id)
-      (applications/return-application approver app-id 0 "comment for return")
-      (applications/submit-application applicant app-id))))
+      (legacy/submit-application applicant app-id)
+      (legacy/return-application approver app-id 0 "comment for return")
+      (legacy/submit-application applicant app-id))))
 
 (defn- create-member-applications! [catid wfid applicant approver members]
   (let [appid1 (create-draft! applicant catid wfid "draft with invited members")]
@@ -607,11 +609,11 @@
         reviewer (users :reviewer)]
     (binding [context/*tempura* (locales/tempura-config)]
       (let [app-id (create-draft! applicant catid wfid "application with review")]
-        (applications/submit-application applicant app-id)
-        (applications/review-application reviewer app-id 0 "comment for review")
-        (applications/approve-application approver app-id 1 "comment for approval")) ; already reviewed and approved
+        (legacy/submit-application applicant app-id)
+        (legacy/review-application reviewer app-id 0 "comment for review")
+        (legacy/approve-application approver app-id 1 "comment for approval")) ; already reviewed and approved
       (let [app-id (create-draft! applicant catid wfid "application in review")]
-        (applications/submit-application applicant app-id))))) ; still in review
+        (legacy/submit-application applicant app-id))))) ; still in review
 
 (defn- create-application-with-expired-resource-license! [wfid form users]
   (let [applicant (users :applicant1)
@@ -625,7 +627,7 @@
                                                                                  "fi" "Resurssi jolla on vanhentunut resurssilisenssi"})]
     (binding [context/*tempura* (locales/tempura-config)]
       (let [application (create-draft! applicant item-with-expired-license wfid "applied when license was valid that has since expired" (time/minus (time/now) (time/days 2)))]
-        (applications/submit-application applicant application)))))
+        (legacy/submit-application applicant application)))))
 
 (defn- create-application-before-new-resource-license! [wfid form users]
   (let [applicant (users :applicant1)
@@ -637,7 +639,7 @@
                                                                                 "fi" "Resurssi jolla on uusi resurssilisenssi"})]
     (binding [context/*tempura* (locales/tempura-config)]
       (let [application (create-draft! applicant item-without-new-license wfid "applied before license was valid" (time/minus (time/now) (time/days 2)))]
-        (applications/submit-application applicant application)))))
+        (legacy/submit-application applicant application)))))
 
 (defn create-performance-test-data! []
   (let [resource-count 1000
diff --git a/test/clj/rems/db/test_applications.clj b/test/clj/rems/db/test_applications.clj
index ac7ceebc0..7a8664cf9 100644
--- a/test/clj/rems/db/test_applications.clj
+++ b/test/clj/rems/db/test_applications.clj
@@ -7,6 +7,7 @@
             [rems.application.events :as events]
             [rems.config :refer [env]]
             [rems.db.applications :refer :all]
+            [rems.db.applications.legacy :as legacy]
             [rems.db.catalogue :as catalogue]
             [rems.db.core :as db]
             [rems.db.form :as form]
@@ -27,9 +28,9 @@
   test-data-fixture)
 
 (deftest can-act-as?-test
-  (is (can-act-as? "developer" (get-application-state 10) "approver"))
-  (is (not (can-act-as? "developer" (get-application-state 10) "reviewer")))
-  (is (not (can-act-as? "alice" (get-application-state 10) "approver"))))
+  (is (legacy/can-act-as? "developer" (legacy/get-application-state 10) "approver"))
+  (is (not (legacy/can-act-as? "developer" (legacy/get-application-state 10) "reviewer")))
+  (is (not (legacy/can-act-as? "alice" (legacy/get-application-state 10) "approver"))))
 
 (deftest test-event-serialization
   (testing "round trip serialization"
diff --git a/test/clj/rems/db/test_entitlements.clj b/test/clj/rems/db/test_entitlements.clj
index 669e1e04b..47713d879 100644
--- a/test/clj/rems/db/test_entitlements.clj
+++ b/test/clj/rems/db/test_entitlements.clj
@@ -140,7 +140,7 @@
 
           (is (= {uid #{lic-id1 lic-id2}
                   memberid #{lic-id1}}
-                 (:application/accepted-licenses (applications/get-application-state app-id))))
+                 (:application/accepted-licenses (applications/get-dynamic-application-state app-id))))
 
           (testing "approved application, licenses accepted by one user generates entitlements for that user"
             (entitlements-poller/run)
diff --git a/test/clj/rems/migrations/test_convert_to_dynamic_applications.clj b/test/clj/rems/migrations/test_convert_to_dynamic_applications.clj
index ce88d7fc0..46c12c3c3 100644
--- a/test/clj/rems/migrations/test_convert_to_dynamic_applications.clj
+++ b/test/clj/rems/migrations/test_convert_to_dynamic_applications.clj
@@ -4,6 +4,7 @@
             [clojure.test :refer :all]
             [conman.core :as conman]
             [rems.db.applications :as applications]
+            [rems.db.applications.legacy :as legacy]
             [rems.db.core :refer [*db*]]
             [rems.db.test-data :as test-data]
             [rems.db.workflow :as workflow]
@@ -117,7 +118,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
       (is (nil? (validate/validate))))
 
     (let [app-id 1
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "draft application"
               :applicantuserid "developer"
@@ -158,7 +159,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 2
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "applied application"
               :applicantuserid "developer"
@@ -204,7 +205,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 3
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "rejected application"
               :applicantuserid "developer"
@@ -256,7 +257,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 4
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "accepted application"
               :applicantuserid "developer"
@@ -308,7 +309,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 5
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "returned application"
               :applicantuserid "developer"
@@ -360,7 +361,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 6
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "bundled application"
               :applicantuserid "alice"
@@ -420,7 +421,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 7
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "application with review"
               :applicantuserid "alice"
@@ -479,7 +480,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 8
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "application in review"
               :applicantuserid "alice"
@@ -525,7 +526,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 20
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "direct approval"
               :applicantuserid "alice"
@@ -577,7 +578,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 21
-          application (applications/get-application-state app-id)
+          application (legacy/get-application-state app-id)
           request-id (-> application :dynamic-events (nth 4) :application/request-id)]
       (is request-id)
       (is (= {:id app-id
@@ -640,7 +641,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 22
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "withdraw"
               :applicantuserid "alice"
@@ -692,7 +693,7 @@ INSERT INTO entitlement (resid, catappid, userid, start, endt) VALUES (1, 23, 'a
              (select-keys application [:id :description :applicantuserid :dynamic-events :workflow]))))
 
     (let [app-id 23
-          application (applications/get-application-state app-id)]
+          application (legacy/get-application-state app-id)]
       (is (= {:id app-id
               :description "close"
               :applicantuserid "alice"
diff --git a/test/clj/rems/test_db.clj b/test/clj/rems/test_db.clj
index 3977290b8..9be70bdb8 100644
--- a/test/clj/rems/test_db.clj
+++ b/test/clj/rems/test_db.clj
@@ -9,6 +9,7 @@
             [rems.config]
             [rems.context :as context]
             [rems.db.applications :as applications]
+            [rems.db.applications.legacy :as legacy]
             [rems.db.catalogue :as catalogue]
             [rems.db.core :as db]
             [rems.db.entitlements :as entitlements]
@@ -43,6 +44,7 @@
                                       :workflow-name))
             "should find same catalogue item by id")))))
 
+;; TODO port this test to look at get-form or build-application-view instead of legacy/get-form-for
 (deftest test-form
   (binding [context/*lang* :en]
     (let [uid "test-user"
@@ -82,7 +84,7 @@
       (testing "get form for catalogue item"
         (with-redefs [catalogue/cached
                       {:localizations (catalogue/load-catalogue-item-localizations!)}]
-          (let [form (applications/get-form-for "test-user" app-id)]
+          (let [form (legacy/get-form-for "test-user" app-id)]
             (is (= "internal-title" (:title form)) "title")
             (is (= ["A-en" "B-en" "C-en"] (map #(get-in % [:localizations :en :title]) (:items form))) "items should be in order")
             (is (= ["A-fi" "B-fi" "C-fi"] (map #(get-in % [:localizations :fi :title]) (:items form))) "items should be in order")
@@ -106,7 +108,7 @@
                                     :actoruserid uid
                                     :round 0
                                     :state "approved"})
-        (let [f (applications/get-form-for uid app-id)]
+        (let [f (legacy/get-form-for uid app-id)]
           (is (= app-id (:id (:application f))))
           (is (= "draft" (:state (:application f))))
           (is (= ["" "B" ""] (map :value (:items f))))
@@ -129,7 +131,7 @@
                                                             :licid license-id
                                                             :actoruserid uid}))
               "after deletion there should not be saved approvals")
-          (let [f (applications/get-form-for uid app-id)]
+          (let [f (legacy/get-form-for uid app-id)]
             (is (= [false] (map :approved (:licenses f))))))
         (testing "reset field value"
           (db/clear-field-value! {:application app-id
@@ -140,7 +142,7 @@
                                  :item (:id item-b)
                                  :user uid
                                  :value "X"})
-          (let [f (applications/get-form-for uid app-id)]
+          (let [f (legacy/get-form-for uid app-id)]
             (is (= ["" "X" ""] (map :value (:items f)))))))
 
       (testing "get submitted form as approver"
@@ -150,16 +152,16 @@
                                     :actoruserid uid
                                     :round 0
                                     :state "approved"})
-        (applications/submit-application uid app-id)
-        (let [form (applications/get-form-for "approver" app-id)]
+        (legacy/submit-application uid app-id)
+        (let [form (legacy/get-form-for "approver" app-id)]
           (is (= "applied" (get-in form [:application :state])))
           (is (= ["" "X" ""] (map :value (:items form))))
           (is (get-in form [:licenses 0 :approved]))))
 
       (testing "get approved form as applicant"
         (db/add-user! {:user "approver" :userattrs nil})
-        (applications/approve-application "approver" app-id 0 "comment")
-        (let [form (applications/get-form-for "approver" app-id)]
+        (legacy/approve-application "approver" app-id 0 "comment")
+        (let [form (legacy/get-form-for "approver" app-id)]
           (is (= "approved" (get-in form [:application :state])))
           (is (= ["" "X" ""] (map :value (:items form))))
           (is (= [nil "comment"]
@@ -212,7 +214,7 @@
     (let [wf (:id (db/create-workflow! {:organization "abc" :owneruserid "owner" :modifieruserid "owner" :title "" :fnlround 1}))
           item (:id (db/create-catalogue-item! {:title "item" :form nil :resid nil :wfid wf}))
           app (applications/create-new-draft "applicant" wf)
-          get-phases (fn [] (applications/get-application-phases (:state (applications/get-application-state app))))]
+          get-phases (fn [] (legacy/get-application-phases (:state (legacy/get-application-state app))))]
       (db/add-application-item! {:application app :item item})
       (actors/add-approver! wf "approver1" 0)
       (actors/add-approver! wf "approver2" 1)
@@ -223,7 +225,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/submit-application "applicant" app)
+      (legacy/submit-application "applicant" app)
 
       (testing "after submission the application is in first approval round"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -231,7 +233,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/approve-application "approver1" app 0 "it's good")
+      (legacy/approve-application "approver1" app 0 "it's good")
 
       (testing "after first approval the application is in the second approval round"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -239,7 +241,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/approve-application "approver2" app 1 "it's good")
+      (legacy/approve-application "approver2" app 1 "it's good")
 
       (testing "after both approvals the application is in approved phase"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -251,7 +253,7 @@
     (let [wf (:id (db/create-workflow! {:organization "abc" :owneruserid "owner" :modifieruserid "owner" :title "" :fnlround 1}))
           item (:id (db/create-catalogue-item! {:title "item" :form nil :resid nil :wfid wf}))
           app (applications/create-new-draft "applicant" wf)
-          get-phases (fn [] (applications/get-application-phases (:state (applications/get-application-state app))))]
+          get-phases (fn [] (legacy/get-application-phases (:state (legacy/get-application-state app))))]
       (db/add-application-item! {:application app :item item})
       (actors/add-approver! wf "approver1" 0)
       (actors/add-approver! wf "approver2" 1)
@@ -262,7 +264,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/submit-application "applicant" app)
+      (legacy/submit-application "applicant" app)
 
       (testing "after submission the application is in first approval round"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -270,7 +272,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/return-application "approver1" app 0 "it must be changed")
+      (legacy/return-application "approver1" app 0 "it must be changed")
 
       (testing "after return the application is in the draft phase again"
         (is (= [{:phase :apply :active? true :text :t.phases/apply}
@@ -282,7 +284,7 @@
     (let [wf (:id (db/create-workflow! {:organization "abc" :owneruserid "owner" :modifieruserid "owner" :title "" :fnlround 1}))
           item (:id (db/create-catalogue-item! {:title "item" :form nil :resid nil :wfid wf}))
           app (applications/create-new-draft "applicant" wf)
-          get-phases (fn [] (applications/get-application-phases (:state (applications/get-application-state app))))]
+          get-phases (fn [] (legacy/get-application-phases (:state (legacy/get-application-state app))))]
       (db/add-application-item! {:application app :item item})
       (actors/add-approver! wf "approver1" 0)
       (actors/add-approver! wf "approver2" 1)
@@ -293,7 +295,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/submit-application "applicant" app)
+      (legacy/submit-application "applicant" app)
 
       (testing "after submission the application is in first approval round"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -301,7 +303,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/approve-application "approver1" app 0 "it's good")
+      (legacy/approve-application "approver1" app 0 "it's good")
 
       (testing "after first approval the application is in the second approval round"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -309,7 +311,7 @@
                 {:phase :result :text :t.phases/approved}]
                (get-phases))))
 
-      (applications/reject-application "approver2" app 1 "is no good")
+      (legacy/reject-application "approver2" app 1 "is no good")
 
       (testing "after second round rejection the application is in rejected phase"
         (is (= [{:phase :apply :completed? true :text :t.phases/apply}
@@ -343,7 +345,7 @@
   (let [uid "event-test"
         wf (:id (db/create-workflow! {:organization "abc" :modifieruserid uid :owneruserid uid :title "Test workflow" :fnlround 1}))
         item (:id (db/create-catalogue-item! {:title "A" :form nil :resid nil :wfid wf}))
-        fetch (fn [app] (select-keys (applications/get-application-state app)
+        fetch (fn [app] (select-keys (legacy/get-application-state app)
                                      [:state :curround]))]
     (actors/add-approver! wf uid 0)
     (actors/add-reviewer! wf "event-test-reviewer" 0)
@@ -355,52 +357,52 @@
 
         (is (= {:curround 0 :state "draft"} (fetch app)))
 
-        (is (thrown? ForbiddenException (applications/approve-application uid app 0 ""))
+        (is (thrown? ForbiddenException (legacy/approve-application uid app 0 ""))
             "Should not be able to approve draft")
 
-        (is (thrown? ForbiddenException (applications/withdraw-application uid app 0 ""))
+        (is (thrown? ForbiddenException (legacy/withdraw-application uid app 0 ""))
             "Should not be able to withdraw draft")
 
-        (is (thrown? ForbiddenException (applications/submit-application "event-test-approver" app))
+        (is (thrown? ForbiddenException (legacy/submit-application "event-test-approver" app))
             "Should not be able to submit when not applicant")
 
-        (applications/submit-application uid app)
+        (legacy/submit-application uid app)
         (is (= {:curround 0 :state "applied"} (fetch app)))
 
-        (applications/try-autoapprove-application uid app)
+        (legacy/try-autoapprove-application uid app)
         (is (= {:curround 0 :state "applied"} (fetch app))
             "Autoapprove should do nothing")
 
-        (is (thrown? ForbiddenException (applications/submit-application uid app)) ; TODO Wrong exception?
+        (is (thrown? ForbiddenException (legacy/submit-application uid app)) ; TODO Wrong exception?
             "Should not be able to submit twice")
 
-        (is (thrown? ForbiddenException (applications/approve-application uid app 1 "")) ; TODO Wrong exception?
+        (is (thrown? ForbiddenException (legacy/approve-application uid app 1 "")) ; TODO Wrong exception?
             "Should not be able to approve wrong round")
 
         (testing "withdrawing and resubmitting"
-          (applications/withdraw-application uid app 0 "test withdraw")
+          (legacy/withdraw-application uid app 0 "test withdraw")
           (is (= {:curround 0 :state "withdrawn"} (fetch app)))
 
-          (applications/submit-application uid app)
+          (legacy/submit-application uid app)
           (is (= {:curround 0 :state "applied"} (fetch app))))
 
-        (is (thrown? ForbiddenException (applications/review-application uid app 0 ""))
+        (is (thrown? ForbiddenException (legacy/review-application uid app 0 ""))
             "Should not be able to review as an approver")
-        (applications/approve-application uid app 0 "c1")
+        (legacy/approve-application uid app 0 "c1")
         (is (= {:curround 1 :state "applied"} (fetch app)))
 
-        (is (thrown? ForbiddenException (applications/approve-application uid app 1 ""))
+        (is (thrown? ForbiddenException (legacy/approve-application uid app 1 ""))
             "Should not be able to approve if not approver")
 
-        (is (thrown? ForbiddenException (applications/withdraw-application "event-test-approver" app 1 ""))
+        (is (thrown? ForbiddenException (legacy/withdraw-application "event-test-approver" app 1 ""))
             "Should not be able to withdraw as approver")
 
         (is (empty? (db/get-entitlements)))
 
-        (applications/approve-application "event-test-approver" app 1 "c2")
+        (legacy/approve-application "event-test-approver" app 1 "c2")
         (is (= {:curround 1 :state "approved"} (fetch app)))
 
-        (is (= (->> (applications/get-application-state app)
+        (is (= (->> (legacy/get-application-state app)
                     :events
                     (map #(select-keys % [:round :event :comment])))
                [{:round 0 :event "apply" :comment nil}
@@ -408,7 +410,7 @@
                 {:round 0 :event "apply" :comment nil}
                 {:round 0 :event "approve" :comment "c1"}
                 {:round 1 :event "approve" :comment "c2"}]
-               (->> (applications/get-application-state app)
+               (->> (legacy/get-application-state app)
                     :events
                     (map #(select-keys % [:round :event :comment])))))))
 
@@ -417,33 +419,33 @@
         (db/add-application-item! {:application app :item item})
 
         (is (= {:curround 0 :state "draft"} (fetch app)))
-        (applications/submit-application uid app)
+        (legacy/submit-application uid app)
         (is (= {:curround 0 :state "applied"} (fetch app)))
-        (applications/reject-application uid app 0 "comment")
+        (legacy/reject-application uid app 0 "comment")
         (is (= {:curround 0 :state "rejected"} (fetch app)))))
 
     (testing "returning, resubmitting"
       (let [app (applications/create-new-draft uid wf)]
         (db/add-application-item! {:application app :item item})
 
-        (is (thrown? ForbiddenException (applications/return-application uid app 0 "comment"))
+        (is (thrown? ForbiddenException (legacy/return-application uid app 0 "comment"))
             "Should not be able to return before submitting")
 
-        (applications/submit-application uid app)
+        (legacy/submit-application uid app)
 
-        (is (thrown? ForbiddenException (applications/return-application "event-test-approver" app 0 "comment"))
+        (is (thrown? ForbiddenException (legacy/return-application "event-test-approver" app 0 "comment"))
             "Should not be able to return when not approver")
 
-        (applications/return-application uid app 0 "comment")
+        (legacy/return-application uid app 0 "comment")
         (is (= {:curround 0 :state "returned"} (fetch app)))
 
-        (is (thrown? ForbiddenException (applications/return-application uid app 0 "comment"))
+        (is (thrown? ForbiddenException (legacy/return-application uid app 0 "comment"))
             "Should not be able to return twice")
 
-        (is (thrown? ForbiddenException (applications/submit-application "event-test-approver" app)) ; TODO wrong exception?
+        (is (thrown? ForbiddenException (legacy/submit-application "event-test-approver" app)) ; TODO wrong exception?
             "Should not be able to resubmit when not approver")
 
-        (applications/submit-application uid app)
+        (legacy/submit-application uid app)
         (is (= {:curround 0 :state "applied"} (fetch app)))))
 
     (testing "review"
@@ -454,57 +456,57 @@
         (actors/add-reviewer! rev-wf "event-test-reviewer" 0)
         (actors/add-approver! rev-wf uid 1)
         (is (= {:curround 0 :state "draft"} (fetch rev-app)))
-        (is (thrown? ForbiddenException (applications/review-application "event-test-reviewer" rev-app 0 ""))
+        (is (thrown? ForbiddenException (legacy/review-application "event-test-reviewer" rev-app 0 ""))
             "Should not be able to review a draft")
-        (is (thrown? ForbiddenException (applications/review-application uid rev-app 0 ""))
+        (is (thrown? ForbiddenException (legacy/review-application uid rev-app 0 ""))
             "Should not be able to review if not reviewer")
-        (applications/submit-application uid rev-app)
+        (legacy/submit-application uid rev-app)
         (is (= {:curround 0 :state "applied"} (fetch rev-app)))
-        (is (thrown? ForbiddenException (applications/review-application "event-test-reviewer" rev-app 1 ""))
+        (is (thrown? ForbiddenException (legacy/review-application "event-test-reviewer" rev-app 1 ""))
             "Should not be able to review wrong round")
-        (is (thrown? ForbiddenException (applications/approve-application "event-test-reviewer" rev-app 0 ""))
+        (is (thrown? ForbiddenException (legacy/approve-application "event-test-reviewer" rev-app 0 ""))
             "Should not be able to approve as reviewer")
-        (applications/review-application "event-test-reviewer" rev-app 0 "looks good to me")
+        (legacy/review-application "event-test-reviewer" rev-app 0 "looks good to me")
         (is (= {:curround 1 :state "applied"} (fetch rev-app)))
-        (applications/return-application uid rev-app 1 "comment")
+        (legacy/return-application uid rev-app 1 "comment")
         (is (= {:curround 0 :state "returned"} (fetch rev-app)))
-        (is (thrown? ForbiddenException (applications/review-application "event-test-reviewer" rev-app 0 ""))
+        (is (thrown? ForbiddenException (legacy/review-application "event-test-reviewer" rev-app 0 ""))
             "Should not be able to review when returned")
-        (applications/submit-application uid rev-app)
-        (applications/withdraw-application uid rev-app 0 "test withdraw")
+        (legacy/submit-application uid rev-app)
+        (legacy/withdraw-application uid rev-app 0 "test withdraw")
         (is (= {:curround 0 :state "withdrawn"} (fetch rev-app)))
-        (is (thrown? ForbiddenException (applications/review-application "event-test-reviewer" rev-app 0 ""))
+        (is (thrown? ForbiddenException (legacy/review-application "event-test-reviewer" rev-app 0 ""))
             "Should not be able to review when withdrawn")))
 
     (testing "closing"
       (testing "a draft as the applicant"
         (let [app (applications/create-new-draft uid wf)]
           (db/add-application-item! {:application app :item item})
-          (applications/close-application uid app 0 "closing draft")
+          (legacy/close-application uid app 0 "closing draft")
           (is (= {:curround 0 :state "closed"} (fetch app)))))
       (testing "an applied application as the applicant"
         (let [app (applications/create-new-draft uid wf)]
           (db/add-application-item! {:application app :item item})
-          (applications/submit-application uid app)
+          (legacy/submit-application uid app)
           (testing "as approver fails"
-            (is (thrown? ForbiddenException (applications/close-application "event-test-approver" app 0 "closing applied"))))
-          (applications/close-application uid app 0 "closing applied")
+            (is (thrown? ForbiddenException (legacy/close-application "event-test-approver" app 0 "closing applied"))))
+          (legacy/close-application uid app 0 "closing applied")
           (is (= {:curround 0 :state "closed"} (fetch app)))))
       (testing "an approved application as the applicant"
         (let [app (applications/create-new-draft uid wf)]
           (db/add-application-item! {:application app :item item})
-          (applications/submit-application uid app)
-          (applications/approve-application uid app 0 "c1")
-          (applications/approve-application "event-test-approver" app 1 "c2")
-          (applications/close-application uid app 1 "closing approved")
+          (legacy/submit-application uid app)
+          (legacy/approve-application uid app 0 "c1")
+          (legacy/approve-application "event-test-approver" app 1 "c2")
+          (legacy/close-application uid app 1 "closing approved")
           (is (= {:curround 1 :state "closed"} (fetch app)))))
       (testing "an approved application as the approver"
         (let [app (applications/create-new-draft uid wf)]
           (db/add-application-item! {:application app :item item})
-          (applications/submit-application uid app)
-          (applications/approve-application uid app 0 "c1")
-          (applications/approve-application "event-test-approver" app 1 "c2")
-          (applications/close-application "event-test-approver" app 1 "closing approved")
+          (legacy/submit-application uid app)
+          (legacy/approve-application uid app 0 "c1")
+          (legacy/approve-application "event-test-approver" app 1 "c2")
+          (legacy/close-application "event-test-approver" app 1 "closing approved")
           (is (= {:curround 1 :state "closed"} (fetch app))))))
 
     (testing "autoapprove"
@@ -514,9 +516,9 @@
             auto-app (applications/create-new-draft uid auto-wf)]
         (db/add-application-item! {:application auto-app :item auto-item})
         (is (= (fetch auto-app) {:curround 0 :state "draft"}))
-        (applications/submit-application uid auto-app)
+        (legacy/submit-application uid auto-app)
         (is (= (fetch auto-app) {:curround 1 :state "approved"}))
-        (is (= (->> (applications/get-application-state auto-app)
+        (is (= (->> (legacy/get-application-state auto-app)
                     :events
                     (map #(select-keys % [:round :event])))
                [{:round 0 :event "apply"}
@@ -530,27 +532,27 @@
       (testing "3rd party review"
         (let [new-app (applications/create-new-draft uid new-wf)]
           (db/add-application-item! {:application new-app :item new-item})
-          (applications/submit-application uid new-app)
+          (legacy/submit-application uid new-app)
           (is (= #{:logged-in} (roles/get-roles "third-party-reviewer"))) ;; default role
           (is (= #{:logged-in} (roles/get-roles "another-reviewer"))) ;; default role
-          (applications/send-review-request uid new-app 0 "review?" "third-party-reviewer")
+          (legacy/send-review-request uid new-app 0 "review?" "third-party-reviewer")
           (is (= #{:logged-in} (roles/get-roles "third-party-reviewer")))
           ;; should not send twice to third-party-reviewer, but another-reviewer should still be added
-          (applications/send-review-request uid new-app 0 "can you please review this?" ["third-party-reviewer" "another-reviewer"])
+          (legacy/send-review-request uid new-app 0 "can you please review this?" ["third-party-reviewer" "another-reviewer"])
           (is (= #{:logged-in} (roles/get-roles "third-party-reviewer")))
           (is (= #{:logged-in} (roles/get-roles "another-reviewer")))
           (is (= (fetch new-app) {:curround 0 :state "applied"}))
-          (applications/perform-third-party-review "third-party-reviewer" new-app 0 "comment")
-          (is (thrown? ForbiddenException (applications/review-application "third-party-reviewer" new-app 0 "another comment")
+          (legacy/perform-third-party-review "third-party-reviewer" new-app 0 "comment")
+          (is (thrown? ForbiddenException (legacy/review-application "third-party-reviewer" new-app 0 "another comment")
                        "Should not be able to do normal review"))
           (is (= (fetch new-app) {:curround 0 :state "applied"}))
-          (applications/approve-application uid new-app 0 "")
+          (legacy/approve-application uid new-app 0 "")
           (is (= (fetch new-app) {:curround 0 :state "approved"}))
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "third-party-reviewer" new-app 0 "another comment")
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "third-party-reviewer" new-app 0 "another comment")
                        "Should not be able to review when approved"))
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "other-reviewer" new-app 0 "too late comment"))
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "other-reviewer" new-app 0 "too late comment"))
               "Should not be able to review when approved")
-          (is (= (->> (applications/get-application-state new-app)
+          (is (= (->> (legacy/get-application-state new-app)
                       :events
                       (map #(select-keys % [:round :event :comment])))
                  [{:round 0 :event "apply" :comment nil}
@@ -567,49 +569,49 @@
           (db/add-application-item! {:application app-to-approve :item new-item})
           (db/add-application-item! {:application app-to-reject :item new-item})
           (db/add-application-item! {:application app-to-return :item new-item})
-          (applications/submit-application uid app-to-close)
-          (applications/submit-application uid app-to-approve)
-          (applications/submit-application uid app-to-reject)
-          (applications/submit-application uid app-to-return)
-          (applications/send-review-request uid app-to-close 0 "can you please review this?" "third-party-reviewer")
-          (applications/send-review-request uid app-to-approve 0 "can you please review this?" "third-party-reviewer")
-          (applications/send-review-request uid app-to-reject 0 "can you please review this?" "third-party-reviewer")
-          (applications/send-review-request uid app-to-return 0 "can you please review this?" "third-party-reviewer")
-          (applications/close-application uid app-to-close 0 "closing")
+          (legacy/submit-application uid app-to-close)
+          (legacy/submit-application uid app-to-approve)
+          (legacy/submit-application uid app-to-reject)
+          (legacy/submit-application uid app-to-return)
+          (legacy/send-review-request uid app-to-close 0 "can you please review this?" "third-party-reviewer")
+          (legacy/send-review-request uid app-to-approve 0 "can you please review this?" "third-party-reviewer")
+          (legacy/send-review-request uid app-to-reject 0 "can you please review this?" "third-party-reviewer")
+          (legacy/send-review-request uid app-to-return 0 "can you please review this?" "third-party-reviewer")
+          (legacy/close-application uid app-to-close 0 "closing")
           (is (= (fetch app-to-close) {:curround 0 :state "closed"}) "should be able to close application even without review")
-          (applications/approve-application uid app-to-approve 0 "approving")
+          (legacy/approve-application uid app-to-approve 0 "approving")
           (is (= (fetch app-to-approve) {:curround 0 :state "approved"}) "should be able to approve application even without review")
-          (applications/reject-application uid app-to-reject 0 "rejecting")
+          (legacy/reject-application uid app-to-reject 0 "rejecting")
           (is (= (fetch app-to-reject) {:curround 0 :state "rejected"}) "should be able to reject application even without review")
-          (applications/return-application uid app-to-return 0 "returning")
+          (legacy/return-application uid app-to-return 0 "returning")
           (is (= (fetch app-to-return) {:curround 0 :state "returned"}) "should be able to return application even without review")
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "third-party-reviewer" app-to-close 0 "comment"))
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "third-party-reviewer" app-to-close 0 "comment"))
               "Should not be able to review when closed")
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "third-party-reviewer" app-to-approve 0 "comment"))
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "third-party-reviewer" app-to-approve 0 "comment"))
               "Should not be able to review when approved")
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "third-party-reviewer" app-to-reject 0 "comment"))
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "third-party-reviewer" app-to-reject 0 "comment"))
               "Should not be able to review when rejected")
-          (is (thrown? ForbiddenException (applications/perform-third-party-review "third-party-reviewer" app-to-return 0 "another comment"))
+          (is (thrown? ForbiddenException (legacy/perform-third-party-review "third-party-reviewer" app-to-return 0 "another comment"))
               "Should not be able to review when returned")
-          (is (= (->> (applications/get-application-state app-to-close)
+          (is (= (->> (legacy/get-application-state app-to-close)
                       :events
                       (map #(select-keys % [:round :event :comment])))
                  [{:round 0 :event "apply" :comment nil}
                   {:round 0 :event "review-request" :comment "can you please review this?"}
                   {:round 0 :event "close" :comment "closing"}]))
-          (is (= (->> (applications/get-application-state app-to-approve)
+          (is (= (->> (legacy/get-application-state app-to-approve)
                       :events
                       (map #(select-keys % [:round :event :comment])))
                  [{:round 0 :event "apply" :comment nil}
                   {:round 0 :event "review-request" :comment "can you please review this?"}
                   {:round 0 :event "approve" :comment "approving"}]))
-          (is (= (->> (applications/get-application-state app-to-reject)
+          (is (= (->> (legacy/get-application-state app-to-reject)
                       :events
                       (map #(select-keys % [:round :event :comment])))
                  [{:round 0 :event "apply" :comment nil}
                   {:round 0 :event "review-request" :comment "can you please review this?"}
                   {:round 0 :event "reject" :comment "rejecting"}]))
-          (is (= (->> (applications/get-application-state app-to-return)
+          (is (= (->> (legacy/get-application-state app-to-return)
                       :events
                       (map #(select-keys % [:round :event :comment])))
                  [{:round 0 :event "apply" :comment nil}