Repository: CSCfi/rems
Pull request #1089 (2019-04-08 12:26:12)

:expired instead of :active in APIs
for #806


Patch:
diff --git a/src/clj/rems/api.clj b/src/clj/rems/api.clj
index aba049d1f..4002aa530 100644
--- a/src/clj/rems/api.clj
+++ b/src/clj/rems/api.clj
@@ -4,7 +4,7 @@
             [compojure.api.exception :as ex]
             [compojure.api.sweet :refer :all]
             [conman.core :as conman]
-            [rems.api.applications :refer [applications-api]]
+            [rems.api.applications :refer [applications-api application-commands-api v2-applications-api]]
             [rems.api.catalogue :refer [catalogue-api]]
             [rems.api.catalogue-items :refer [catalogue-items-api]]
             [rems.api.entitlements :refer [entitlements-api]]
@@ -54,8 +54,8 @@
      (log/log log-level e (str (.getMessage e)
                                "\n"
                                (with-out-str
-                                 (clojure.pprint/pprint
-                                  (select-keys data [:schema :errors :response])))))
+                                (clojure.pprint/pprint
+                                 (select-keys data [:schema :errors :response])))))
      (handler e data req))))
 
 (def cors-middleware
@@ -81,39 +81,41 @@
 (def api-routes
   (api
     {;; TODO: should this be in rems.middleware?
-     :formats muuntaja
+     :formats    muuntaja
      :middleware [cors-middleware
                   transaction-middleware]
-     :exceptions {:handlers {NotAuthorizedException unauthorized-handler
-                             ForbiddenException forbidden-handler
-                             InvalidRequestException invalid-handler
+     :exceptions {:handlers {NotAuthorizedException   unauthorized-handler
+                             ForbiddenException       forbidden-handler
+                             InvalidRequestException  invalid-handler
                              ;; java.lang.Throwable (ex/with-logging debug-handler) ; optional Debug handler
                              ;; add logging to validation handlers
-                             ::ex/request-validation (with-logging ex/request-validation-handler)
-                             ::ex/request-parsing (with-logging ex/request-parsing-handler)
+                             ::ex/request-validation  (with-logging ex/request-validation-handler)
+                             ::ex/request-parsing     (with-logging ex/request-parsing-handler)
                              ::ex/response-validation (with-logging ex/response-validation-handler)}}
-     :swagger {:ui "/swagger-ui"
-               :spec "/swagger.json"
-               :data {:info {:version "1.0.0"
-                             :title "REMS API"
-                             :description "REMS API Services"}}}}
+     :swagger    {:ui   "/swagger-ui"
+                  :spec "/swagger.json"
+                  :data {:info {:version     "1.0.0"
+                                :title       "REMS API"
+                                :description "REMS API Services"}}}}
 
     (context "/api" []
-      ;; :middleware [slow-middleware]
-      :header-params [{x-rems-api-key :- (describe s/Str "REMS API-Key (optional for UI, required for API)") nil}
-                      {x-rems-user-id :- (describe s/Str "user id (optional for UI, required for API)") nil}]
+     ;; :middleware [slow-middleware]
+     :header-params [{x-rems-api-key :- (describe s/Str "REMS API-Key (optional for UI, required for API)") nil}
+                     {x-rems-user-id :- (describe s/Str "user id (optional for UI, required for API)") nil}]
 
-      public/translations-api
-      public/theme-api
-      public/config-api
+     public/translations-api
+     public/theme-api
+     public/config-api
 
-      reviews-api
-      applications-api
-      catalogue-api
-      catalogue-items-api
-      entitlements-api
-      forms-api
-      licenses-api
-      resources-api
-      users-api
-      workflows-api)))
+     reviews-api
+     applications-api
+     v2-applications-api
+     application-commands-api
+     catalogue-api
+     catalogue-items-api
+     entitlements-api
+     forms-api
+     licenses-api
+     resources-api
+     users-api
+     workflows-api)))
diff --git a/src/clj/rems/api/applications.clj b/src/clj/rems/api/applications.clj
index 4d5d20fc6..8f18229e0 100644
--- a/src/clj/rems/api/applications.clj
+++ b/src/clj/rems/api/applications.clj
@@ -15,6 +15,7 @@
             [ring.middleware.multipart-params :as multipart]
             [ring.swagger.upload :as upload]
             [ring.util.http-response :refer :all]
+            [schema-refined.core :as r]
             [schema.core :as s])
   (:import [java.io ByteArrayInputStream]))
 
@@ -86,48 +87,15 @@
 
 (def get-deciders get-users)
 
-(defn- coerce-command-from-api [cmd]
-  ;; TODO: schema could do these coercions for us
+(defn- fix-command-from-api
+  [cmd]
+  ;; schema could do these coercions for us...
   (update-present cmd :decision keyword))
 
-(defn api-command [command-type request]
-  (let [command (-> request
-                    (coerce-command-from-api)
-                    (assoc :type command-type
-                           :actor (getx-user-id)
-                           :time (time/now)))
-        errors (applications/command! command)]
-    (if errors
-      (ok {:success false
-           :errors (:errors errors)})
-      (ok {:success true}))))
-
-(defmacro command-endpoint [command schema]
-  (let [path (str "/" (name command))]
-    `(POST ~path []
-       :summary ~(str "Submit a `" (name command) "` command for an application.")
-       :roles #{:logged-in}
-       :body [request# ~schema]
-       :return SuccessResponse
-       (api-command ~command request#))))
-
 (def applications-api
   (context "/applications" []
     :tags ["applications"]
 
-    (GET "/" []
-      :summary "Get current user's all applications"
-      :roles #{:logged-in}
-      :return [ApplicationOverview]
-      (ok (applications-v2/get-own-applications (getx-user-id))))
-
-    (POST "/create" []
-      :summary "Create a new application"
-      :roles #{:logged-in}
-      :body [request CreateApplicationCommand]
-      :return CreateApplicationResponse
-      (ok (applications/create-application! (getx-user-id) (:catalogue-item-ids request))))
-
     (GET "/commenters" []
       :summary "Available third party commenters"
       :roles #{:handler}
@@ -156,6 +124,26 @@
             (content-type (:content-type attachment)))
         (not-found! "not found")))
 
+    (POST "/accept-invitation" []
+      :summary "Accept an invitation by token"
+      :roles #{:logged-in}
+      :query-params [invitation-token :- (describe s/Str "invitation token")]
+      :return AcceptInvitationResult
+      (ok (applications/accept-invitation (getx-user-id) invitation-token)))
+
+    (GET "/:application-id/pdf" []
+      :summary "Get a pdf version of an application"
+      :roles #{:logged-in}
+      :path-params [application-id :- (describe s/Num "application id")]
+      :produces ["application/pdf"]
+      (if-let [app (applications-v2/get-application (getx-user-id) application-id)]
+        (-> app
+            (pdf/application-to-pdf-bytes)
+            (ByteArrayInputStream.)
+            (ok)
+            (content-type "application/pdf"))
+        (not-found! "not found")))
+
     ;; TODO: think about size limit
     (POST "/add-attachment" []
       :summary "Add an attachment file related to an application field"
@@ -175,15 +163,33 @@
                      field-id :- (describe s/Int "application form field id the attachment is related to")]
       :return SuccessResponse
       (attachments/remove-attachment! (getx-user-id) application-id field-id)
-      (ok {:success true}))
+      (ok {:success true}))))
 
-    (POST "/accept-invitation" []
-      :summary "Accept an invitation by token"
-      :roles #{:logged-in}
-      :query-params [invitation-token :- (describe s/Str "invitation token")]
-      :return AcceptInvitationResult
-      (ok (applications/accept-invitation (getx-user-id) invitation-token)))
+(defn api-command [command-type request]
+  (let [command (-> request
+                    (assoc :type command-type)
+                    (assoc :actor (getx-user-id))
+                    (assoc :time (time/now))
+                    (fix-command-from-api))
+        errors (applications/command! command)]
+    (if errors
+      (ok {:success false
+           :errors (:errors errors)})
+      (ok {:success true}))))
+
+(defmacro command-endpoint [command schema]
+  (let [path (str "/" (name command))]
+    `(POST ~path []
+       :summary ~(str "Submit a `" (name command) "` command for an application.")
+       :roles #{:logged-in}
+       :body [request# ~schema]
+       :return SuccessResponse
+       (api-command ~command request#))))
 
+(def application-commands-api
+  (context "/applications" []
+    :tags ["applications"]
+    (command-endpoint :application.command/accept-invitation commands/AcceptInvitationCommand)
     (command-endpoint :application.command/add-member commands/AddMemberCommand)
     (command-endpoint :application.command/invite-member commands/InviteMemberCommand)
     (command-endpoint :application.command/approve commands/ApproveCommand)
@@ -197,9 +203,25 @@
     (command-endpoint :application.command/return commands/ReturnCommand)
     (command-endpoint :application.command/save-draft commands/SaveDraftCommand)
     (command-endpoint :application.command/submit commands/SubmitCommand)
-    (command-endpoint :application.command/uninvite-member commands/UninviteMemberCommand)
+    (command-endpoint :application.command/uninvite-member commands/UninviteMemberCommand)))
+
+(def v2-applications-api
+  (context "/v2/applications" []
+    :tags ["applications"]
+
+    (GET "/" []
+      :summary "Get current user's all applications"
+      :roles #{:logged-in}
+      :return [ApplicationOverview]
+      (ok (applications-v2/get-own-applications (getx-user-id))))
+
+    (POST "/create" []
+      :summary "Create a new application"
+      :roles #{:logged-in}
+      :body [request CreateApplicationCommand]
+      :return CreateApplicationResponse
+      (ok (applications/create-application! (getx-user-id) (:catalogue-item-ids request))))
 
-    ;; the path parameter matches also non-numeric paths, so this route must be after all overlapping routes
     (GET "/:application-id" []
       :summary "Get application by `application-id`"
       :roles #{:logged-in}
@@ -208,18 +230,4 @@
                   404 {:schema s/Str :description "Not found"}}
       (if-let [app (applications-v2/get-application (getx-user-id) application-id)]
         (ok app)
-        (not-found! "not found")))
-
-    (GET "/:application-id/pdf" []
-      :summary "Get a pdf version of an application"
-      :roles #{:logged-in}
-      :path-params [application-id :- (describe s/Num "application id")]
-      :produces ["application/pdf"]
-      (if-let [app (applications-v2/get-application (getx-user-id) application-id)]
-        (-> app
-            (pdf/application-to-pdf-bytes)
-            (ByteArrayInputStream.)
-            (ok)
-            (content-type "application/pdf"))
         (not-found! "not found")))))
-
diff --git a/src/clj/rems/api/catalogue.clj b/src/clj/rems/api/catalogue.clj
index 86998fe0b..d45f2f265 100644
--- a/src/clj/rems/api/catalogue.clj
+++ b/src/clj/rems/api/catalogue.clj
@@ -3,6 +3,7 @@
             [rems.api.schema :refer :all]
             [rems.api.util :refer [check-user]]
             [rems.db.catalogue :as catalogue]
+            [rems.db.core :as db]
             [ring.util.http-response :refer :all]
             [schema.core :as s]))
 
@@ -14,7 +15,9 @@
     :tags ["catalogue"]
 
     (GET "/" []
-      :summary "Get the catalogue of items for the UI (does not include disabled)"
+      :summary "Get the catalogue of items for the UI (does not include disabled, expired or archived items)"
       :roles #{:logged-in}
       :return GetCatalogueResponse
-      (ok (catalogue/get-localized-catalogue-items)))))
+      (ok (db/apply-filters
+           {:expired false :enabled true}
+           (catalogue/get-localized-catalogue-items {:archived false}))))))
diff --git a/src/clj/rems/api/catalogue_items.clj b/src/clj/rems/api/catalogue_items.clj
index 282cc7376..b5b1e1fff 100644
--- a/src/clj/rems/api/catalogue_items.clj
+++ b/src/clj/rems/api/catalogue_items.clj
@@ -45,7 +45,7 @@
                      {expired :- (describe s/Bool "whether to include expired items") false}]
       :return GetCatalogueItemsResponse
       (ok (db/apply-filters
-           (merge (when-not expired {:active true})
+           (merge (when-not expired {:expired false})
                   (when-not disabled {:enabled true})
                   (when-not archived {:archived false}))
            (catalogue/get-localized-catalogue-items {:resource resource
diff --git a/src/clj/rems/api/forms.clj b/src/clj/rems/api/forms.clj
index 2ccf3fb99..7458415ef 100644
--- a/src/clj/rems/api/forms.clj
+++ b/src/clj/rems/api/forms.clj
@@ -15,7 +15,7 @@
    :title s/Str
    :start DateTime
    :end (s/maybe DateTime)
-   :active s/Bool
+   :expired s/Bool
    :enabled s/Bool
    :archived s/Bool})
 
@@ -38,13 +38,13 @@
   [Form])
 
 (defn- format-form
-  [{:keys [id organization title start endt active enabled archived]}]
+  [{:keys [id organization title start endt expired enabled archived]}]
   {:id id
    :organization organization
    :title title
    :start start
    :end endt
-   :active active
+   :expired expired
    :enabled enabled
    :archived archived})
 
@@ -73,7 +73,7 @@
                      {expired :- (describe s/Bool "whether to include expired forms") false}
                      {archived :- (describe s/Bool "whether to include archived forms") false}]
       :return Forms
-      (ok (get-forms (merge (when-not expired {:active true})
+      (ok (get-forms (merge (when-not expired {:expired false})
                             (when-not disabled {:enabled true})
                             (when-not archived {:archived false})))))
 
diff --git a/src/clj/rems/api/licenses.clj b/src/clj/rems/api/licenses.clj
index 5b7477b64..748a37c9b 100644
--- a/src/clj/rems/api/licenses.clj
+++ b/src/clj/rems/api/licenses.clj
@@ -52,7 +52,7 @@
                      {archived :- (describe s/Bool "whether to include archived licenses") false}]
       :return Licenses
       (ok (licenses/get-all-licenses (merge (when-not disabled {:enabled true})
-                                            (when-not expired {:active true})
+                                            (when-not expired {:expired false})
                                             (when-not archived {:archived false})))))
 
     (GET "/:license-id" []
diff --git a/src/clj/rems/api/resources.clj b/src/clj/rems/api/resources.clj
index 9555ce7cd..ad2cb3116 100644
--- a/src/clj/rems/api/resources.clj
+++ b/src/clj/rems/api/resources.clj
@@ -18,7 +18,7 @@
    :resid s/Str
    :start DateTime
    :end (s/maybe DateTime)
-   :active s/Bool
+   :expired s/Bool
    :enabled s/Bool
    :archived s/Bool
    :licenses [ResourceLicense]})
@@ -37,7 +37,7 @@
    (s/optional-key :errors) [s/Any]})
 
 (defn- format-resource
-  [{:keys [id owneruserid modifieruserid organization resid start endt active enabled archived]}]
+  [{:keys [id owneruserid modifieruserid organization resid start endt expired enabled archived]}]
   {:id id
    :owneruserid owneruserid
    :modifieruserid modifieruserid
@@ -45,7 +45,7 @@
    :resid resid
    :start start
    :end endt
-   :active active
+   :expired expired
    :enabled enabled
    :archived archived})
 
@@ -72,7 +72,7 @@
                      {expired :- (describe s/Bool "whether to include expired resources") false}
                      {archived :- (describe s/Bool "whether to include archived resources") false}]
       :return Resources
-      (ok (get-resources (merge (when-not expired {:active true})
+      (ok (get-resources (merge (when-not expired {:expired false})
                                 (when-not disabled {:enabled true})
                                 (when-not archived {:archived false})))))
 
diff --git a/src/clj/rems/api/reviews.clj b/src/clj/rems/api/reviews.clj
index b59ba11eb..ce9375167 100644
--- a/src/clj/rems/api/reviews.clj
+++ b/src/clj/rems/api/reviews.clj
@@ -33,7 +33,7 @@
        (remove open-review?)))
 
 (def reviews-api
-  (context "/reviews" []
+  (context "/v2/reviews" []
     :tags ["reviews"]
 
     (GET "/open" []
diff --git a/src/clj/rems/api/schema.clj b/src/clj/rems/api/schema.clj
index e28102483..62f87b2db 100644
--- a/src/clj/rems/api/schema.clj
+++ b/src/clj/rems/api/schema.clj
@@ -19,7 +19,7 @@
    :end (s/maybe DateTime)
    :enabled s/Bool
    :archived s/Bool
-   :active s/Bool
+   :expired s/Bool
    :localizations (s/maybe {s/Any s/Any})})
 
 (s/defschema License
@@ -29,7 +29,7 @@
    :end (s/maybe DateTime)
    :enabled s/Bool
    :archived s/Bool
-   :active s/Bool
+   :expired s/Bool
    :title s/Str
    :textcontent s/Str
    (s/optional-key :attachment-id) (s/maybe s/Num)
@@ -90,7 +90,7 @@
    :catalogue-item/start DateTime
    :catalogue-item/end (s/maybe DateTime)
    :catalogue-item/enabled s/Bool
-   :catalogue-item/active s/Bool
+   :catalogue-item/expired s/Bool
    :catalogue-item/archived s/Bool})
 
 (s/defschema License
@@ -105,7 +105,7 @@
    :license/start DateTime
    :license/end (s/maybe DateTime)
    :license/enabled s/Bool
-   :license/active s/Bool
+   :license/expired s/Bool
    :license/archived s/Bool})
 
 (s/defschema Field
diff --git a/src/clj/rems/api/workflows.clj b/src/clj/rems/api/workflows.clj
index 61e4f7328..1fd7573ec 100644
--- a/src/clj/rems/api/workflows.clj
+++ b/src/clj/rems/api/workflows.clj
@@ -52,7 +52,7 @@
    :workflow s/Any
    :start DateTime
    :end (s/maybe DateTime)
-   :active s/Bool
+   :expired s/Bool
    :enabled s/Bool
    :archived s/Bool
    :actors [Actor]
@@ -62,7 +62,7 @@
   [Workflow])
 
 (defn- format-workflow
-  [{:keys [id organization owneruserid modifieruserid title fnlround workflow start endt active enabled archived licenses]}]
+  [{:keys [id organization owneruserid modifieruserid title fnlround workflow start endt expired enabled archived licenses]}]
   {:id id
    :organization organization
    :owneruserid owneruserid
@@ -72,7 +72,7 @@
    :workflow workflow
    :start start
    :end endt
-   :active active
+   :expired expired
    :enabled enabled
    :archived archived
    :licenses licenses})
@@ -117,7 +117,7 @@
                      {expired :- (describe s/Bool "whether to include expired workflows") false}
                      {archived :- (describe s/Bool "whether to include archived workflows") false}]
       :return Workflows
-      (ok (get-workflows (merge (when-not expired {:active true})
+      (ok (get-workflows (merge (when-not expired {:expired false})
                                 (when-not disabled {:enabled true})
                                 (when-not archived {:archived false})))))
 
diff --git a/src/clj/rems/application/model.clj b/src/clj/rems/application/model.clj
index 1fb111c99..d19cfd8dc 100644
--- a/src/clj/rems/application/model.clj
+++ b/src/clj/rems/application/model.clj
@@ -402,7 +402,7 @@
                :catalogue-item/start (:start item)
                :catalogue-item/end (:end item)
                :catalogue-item/enabled (:enabled item)
-               :catalogue-item/active (:active item)
+               :catalogue-item/expired (:expired item)
                :catalogue-item/archived (:archived item)}))
        (sort-by :catalogue-item/id)))
 
@@ -420,7 +420,7 @@
                                             :license/start (:start license)
                                             :license/end (:end license)
                                             :license/enabled (:enabled license)
-                                            :license/active (:active license)
+                                            :license/expired (:expired license)
                                             :license/archived (:archived license)}
                                            (case license-type
                                              :text {:license/text (assoc (localization-for :textcontent license)
diff --git a/src/clj/rems/db/applications.clj b/src/clj/rems/db/applications.clj
index 6e42224e7..a9e4953b7 100644
--- a/src/clj/rems/db/applications.clj
+++ b/src/clj/rems/db/applications.clj
@@ -25,7 +25,8 @@
             [schema-tools.core :as st]
             [schema.coerce :as coerce]
             [schema.utils])
-  (:import [org.joda.time DateTime]))
+  (:import [org.joda.time DateTime]
+           rems.InvalidRequestException))
 
 (declare get-dynamic-application-state)
 (declare get-dynamic-application-state-for-user)
@@ -604,7 +605,6 @@
   (or (datestring-coercion-matcher schema)
       (coerce/string-coercion-matcher schema)))
 
-;; TODO: remove "dynamic" from names
 (def ^:private coerce-dynamic-event-commons
   (coerce/coercer (st/open-schema events/EventBase) coercion-matcher))
 
@@ -634,7 +634,6 @@
   (assoc (-> event :eventdata json->event)
          :event/id (:id event)))
 
-;; TODO: remove "dynamic" from names
 (defn get-dynamic-application-events [application-id]
   (map fix-event-from-db (db/get-application-events {:application application-id})))
 
diff --git a/src/clj/rems/db/catalogue.clj b/src/clj/rems/db/catalogue.clj
index d0c995a06..95b348195 100644
--- a/src/clj/rems/db/catalogue.clj
+++ b/src/clj/rems/db/catalogue.clj
@@ -30,7 +30,7 @@
   ([query-params]
    (->> (db/get-catalogue-items query-params)
         (map localize-catalogue-item)
-        (map db/assoc-active))))
+        (map db/assoc-expired))))
 
 (defn get-localized-catalogue-item [id]
   (first (get-localized-catalogue-items {:ids [id] :archived true})))
diff --git a/src/clj/rems/db/core.clj b/src/clj/rems/db/core.clj
index 9cd65d0d3..e4d354dc5 100644
--- a/src/clj/rems/db/core.clj
+++ b/src/clj/rems/db/core.clj
@@ -37,13 +37,12 @@
         (or (nil? end)
             (time/before? now end)))))
 
-(defn assoc-active
-  "Calculates and assocs :active attribute based on current time and :start and :endt attributes.
+(defn assoc-expired
+  "Calculates and assocs :expired attribute based on current time and :start and :endt attributes.
 
    Current time can be passed in optionally."
   ([x]
-   (assoc-active (time/now) x))
+   (assoc-expired (time/now) x))
   ([now x]
    ;; TODO: rename endt to end in all places
-   (assoc x :active (now-active? now (:start x) (or (:endt x)
-                                                    (:end x))))))
+   (assoc x :expired (not (now-active? now (:start x) (or (:endt x) (:end x)))))))
diff --git a/src/clj/rems/db/form.clj b/src/clj/rems/db/form.clj
index bfecba2cc..00e49cb04 100644
--- a/src/clj/rems/db/form.clj
+++ b/src/clj/rems/db/form.clj
@@ -8,17 +8,17 @@
 
 (defn get-forms [filters]
   (->> (db/get-forms)
-       (map db/assoc-active)
+       (map db/assoc-expired)
        (db/apply-filters filters)))
 
 (defn get-form [id]
   (-> (db/get-form {:id id})
-      (db/assoc-active)
+      (db/assoc-expired)
       (update :fields json/parse-string)))
 
 (defn get-form-template [id]
   (-> (db/get-form-template {:id id})
-      (db/assoc-active)
+      (db/assoc-expired)
       (update :fields json/parse-string)))
 
 (defn- create-form-item! [user-id form-id item-index {:keys [title optional type input-prompt maxlength options]}]
diff --git a/src/clj/rems/db/form_item.clj b/src/clj/rems/db/form_item.clj
index 40c7a3561..9e42c0b83 100644
--- a/src/clj/rems/db/form_item.clj
+++ b/src/clj/rems/db/form_item.clj
@@ -3,5 +3,5 @@
 
 (defn get-form-items [filters]
   (->> (db/get-all-form-items)
-       (map db/assoc-active)
+       (map db/assoc-expired)
        (db/apply-filters filters)))
diff --git a/src/clj/rems/db/licenses.clj b/src/clj/rems/db/licenses.clj
index ccbb84541..0b9e43bf5 100644
--- a/src/clj/rems/db/licenses.clj
+++ b/src/clj/rems/db/licenses.clj
@@ -13,7 +13,7 @@
    :end (:endt license)
    :enabled (:enabled license)
    :archived (:archived license)
-   :active (:active license)
+   :expired (:expired license)
    ;; TODO why do licenses have a non-localized title & content while items don't?
    :title (:title license)
    :textcontent (:textcontent license)
@@ -42,7 +42,7 @@
   [id]
   (->> (db/get-resource-licenses {:id id})
        (format-licenses)
-       (mapv db/assoc-active)
+       (mapv db/assoc-expired)
        (localize-licenses)))
 
 (defn get-license
@@ -50,7 +50,7 @@
   [id]
   (->> (db/get-license {:id id})
        (format-license)
-       (db/assoc-active)
+       (db/assoc-expired)
        (localize-license (get-license-localizations))))
 
 ;; NB! There are three different "license activity" concepts:
@@ -68,7 +68,7 @@
    filters is a map of key-value pairs that must be present in the licenses"
   [filters]
   (->> (db/get-all-licenses)
-       (map db/assoc-active)
+       (map db/assoc-expired)
        (db/apply-filters filters)
        (format-licenses)
        (localize-licenses)))
@@ -81,8 +81,8 @@
   (->> (db/get-licenses params)
        (format-licenses)
        (localize-licenses)
-       (map (partial db/assoc-active now))
-       (filter :active)
+       (map (partial db/assoc-expired now))
+       (remove :expired)
        (distinct-by :id)))
 
 (defn create-license! [{:keys [title licensetype textcontent localizations attachment-id]} user-id]
diff --git a/src/clj/rems/db/resource.clj b/src/clj/rems/db/resource.clj
index 989702996..a5ba77c13 100644
--- a/src/clj/rems/db/resource.clj
+++ b/src/clj/rems/db/resource.clj
@@ -6,11 +6,11 @@
 (defn get-resource [id]
   (-> {:id id}
       db/get-resource
-      db/assoc-active))
+      db/assoc-expired))
 
 (defn get-resources [filters]
   (->> (db/get-resources)
-       (map db/assoc-active)
+       (map db/assoc-expired)
        (db/apply-filters filters)))
 
 (defn duplicate-resid? [^Exception e]
diff --git a/src/clj/rems/db/workflow.clj b/src/clj/rems/db/workflow.clj
index 51ca75ce3..21c112b36 100644
--- a/src/clj/rems/db/workflow.clj
+++ b/src/clj/rems/db/workflow.clj
@@ -14,12 +14,12 @@
       db/get-workflow
       (update :workflow parse-workflow-body)
       (update :licenses parse-licenses)
-      db/assoc-active))
+      db/assoc-expired))
 
 (defn get-workflows [filters]
   (->> (db/get-workflows)
        (map #(update % :workflow parse-workflow-body))
-       (map db/assoc-active)
+       (map db/assoc-expired)
        (db/apply-filters filters)))
 
 (defn- create-auto-approve-workflow! [{:keys [user-id organization title]}]
diff --git a/src/cljs/rems/actions.cljs b/src/cljs/rems/actions.cljs
index 046352a74..eadc202f0 100644
--- a/src/cljs/rems/actions.cljs
+++ b/src/cljs/rems/actions.cljs
@@ -21,7 +21,7 @@
 (rf/reg-event-fx
  ::fetch-actions
  (fn [{:keys [db]} _]
-   (fetch "/api/reviews/open"
+   (fetch "/api/v2/reviews/open"
           {:handler #(rf/dispatch [::fetch-actions-result %])})
    {:db (assoc db ::loading-actions? true)}))
 
@@ -47,7 +47,7 @@
 (rf/reg-event-fx
  ::fetch-handled-actions
  (fn [{:keys [db]} _]
-   (fetch "/api/reviews/handled"
+   (fetch "/api/v2/reviews/handled"
           {:handler #(rf/dispatch [::fetch-handled-actions-result %])})
    {:db (assoc db ::loading-handled-actions? true)}))
 
diff --git a/src/cljs/rems/administration/catalogue_item.cljs b/src/cljs/rems/administration/catalogue_item.cljs
index 5fefbc531..493d450ea 100644
--- a/src/cljs/rems/administration/catalogue_item.cljs
+++ b/src/cljs/rems/administration/catalogue_item.cljs
@@ -63,7 +63,7 @@
                                                                        (:form-name catalogue-item)]]
                      [inline-info-field (text :t.administration/start) (localize-time (:start catalogue-item))]
                      [inline-info-field (text :t.administration/end) (localize-time (:end catalogue-item))]
-                     [inline-info-field (text :t.administration/active) [readonly-checkbox (:active catalogue-item)]]]))}]
+                     [inline-info-field (text :t.administration/active) [readonly-checkbox (not (:expired catalogue-item))]]]))}]
    [:div.col.commands [back-button]]])
 
 (defn catalogue-item-page []
diff --git a/src/cljs/rems/administration/catalogue_items.cljs b/src/cljs/rems/administration/catalogue_items.cljs
index 8b03d2d55..29922292b 100644
--- a/src/cljs/rems/administration/catalogue_items.cljs
+++ b/src/cljs/rems/administration/catalogue_items.cljs
@@ -99,8 +99,9 @@
              :value (comp localize-time :start)}
    :end {:header #(text :t.administration/end)
          :value (comp localize-time :end)}
+   ;; TODO: active means not-expired currently. it should maybe mean (and not-expired enabled not-archived)
    :active {:header #(text :t.administration/active)
-            :value (comp readonly-checkbox :enabled)}
+            :value (comp readonly-checkbox not :expired)}
    :commands {:values (fn [item]
                         [[to-catalogue-item (:id item)]
                          [status-flags/enabled-toggle item #(rf/dispatch [::update-catalogue-item %])]
diff --git a/src/cljs/rems/administration/form.cljs b/src/cljs/rems/administration/form.cljs
index 8d8d8af7b..33d10f944 100644
--- a/src/cljs/rems/administration/form.cljs
+++ b/src/cljs/rems/administration/form.cljs
@@ -74,7 +74,7 @@
               [inline-info-field (text :t.administration/title) (:title form)]
               [inline-info-field (text :t.administration/start) (localize-time (:start form))]
               [inline-info-field (text :t.administration/end) (localize-time (:end form))]
-              [inline-info-field (text :t.administration/active) (str (:active form))]]}]
+              [inline-info-field (text :t.administration/active) [readonly-checkbox (not (:expired form))]]]}]
    [form-fields (:fields form) language]
    [:div.col.commands [back-button]]])
    ;; TODO Do we support form licenses?
diff --git a/src/cljs/rems/administration/forms.cljs b/src/cljs/rems/administration/forms.cljs
index c832e4268..7cad22f9a 100644
--- a/src/cljs/rems/administration/forms.cljs
+++ b/src/cljs/rems/administration/forms.cljs
@@ -83,7 +83,7 @@
    :end {:header #(text :t.administration/end)
          :value (comp localize-time :end)}
    :active {:header #(text :t.administration/active)
-            :value (comp readonly-checkbox :active)}
+            :value (comp readonly-checkbox not :expired)}
    :commands {:values (fn [item]
                         [[to-view-form item]
                          [status-flags/enabled-toggle item #(rf/dispatch [::update-form %])]
diff --git a/src/cljs/rems/administration/license.cljs b/src/cljs/rems/administration/license.cljs
index d1984261d..5f8982e81 100644
--- a/src/cljs/rems/administration/license.cljs
+++ b/src/cljs/rems/administration/license.cljs
@@ -81,7 +81,7 @@
                            {:no-box? true}])))
                     [[inline-info-field (text :t.administration/start) (localize-time (:start license))]
                      [inline-info-field (text :t.administration/end) (localize-time (:end license))]
-                     [inline-info-field (text :t.administration/active) [readonly-checkbox (:active license)]]]))}]
+                     [inline-info-field (text :t.administration/active) [readonly-checkbox (not (:expired license))]]]))}]
    [:div.col.commands [back-button]]])
 
 (defn license-page []
diff --git a/src/cljs/rems/administration/licenses.cljs b/src/cljs/rems/administration/licenses.cljs
index d5be4fe95..e48029b43 100644
--- a/src/cljs/rems/administration/licenses.cljs
+++ b/src/cljs/rems/administration/licenses.cljs
@@ -83,7 +83,7 @@
    :end {:header #(text :t.administration/end)
          :value (comp localize-time :end)}
    :active {:header #(text :t.administration/active)
-            :value (comp readonly-checkbox :active)}
+            :value (comp readonly-checkbox not :expired)}
    :commands {:values (fn [license]
                         [[to-view-license (:id license)]
                          [status-flags/enabled-toggle license #(rf/dispatch [::update-license %])]
diff --git a/src/cljs/rems/administration/resource.cljs b/src/cljs/rems/administration/resource.cljs
index a2c1942be..2449813aa 100644
--- a/src/cljs/rems/administration/resource.cljs
+++ b/src/cljs/rems/administration/resource.cljs
@@ -94,7 +94,7 @@
               [inline-info-field (text :t.administration/resource) (:resid resource)]
               [inline-info-field (text :t.administration/start) (localize-time (:start resource))]
               [inline-info-field (text :t.administration/end) (localize-time (:end resource))]
-              [inline-info-field (text :t.administration/active) [readonly-checkbox (:active resource)]]]}]
+              [inline-info-field (text :t.administration/active) [readonly-checkbox (not (:expired resource))]]]}]
    [licenses-view (:licenses resource) language]
    [:div.col.commands [back-button]]])
 
diff --git a/src/cljs/rems/administration/resources.cljs b/src/cljs/rems/administration/resources.cljs
index 82a7ca109..5b267e76f 100644
--- a/src/cljs/rems/administration/resources.cljs
+++ b/src/cljs/rems/administration/resources.cljs
@@ -79,7 +79,7 @@
    :end {:header #(text :t.administration/end)
          :value (comp localize-time :end)}
    :active {:header #(text :t.administration/active)
-            :value (comp readonly-checkbox :active)}
+            :value (comp readonly-checkbox not :expired)}
    :commands {:values (fn [resource]
                         [[to-view-resource (:id resource)]
                          [status-flags/enabled-toggle resource #(rf/dispatch [::update-resource %])]
diff --git a/src/cljs/rems/administration/workflow.cljs b/src/cljs/rems/administration/workflow.cljs
index 1a3f8af9e..c38b15317 100644
--- a/src/cljs/rems/administration/workflow.cljs
+++ b/src/cljs/rems/administration/workflow.cljs
@@ -129,7 +129,7 @@
                 [inline-info-field (text :t.create-workflow/handlers) (str/join ", " (get-in workflow [:workflow :handlers]))])
               [inline-info-field (text :t.administration/start) (localize-time (:start workflow))]
               [inline-info-field (text :t.administration/end) (localize-time (:end workflow))]
-              [inline-info-field (text :t.administration/active) [readonly-checkbox (:active workflow)]]]}]
+              [inline-info-field (text :t.administration/active) [readonly-checkbox (not (:expired workflow))]]]}]
    [rounds-view (:actors workflow) language]
    [licenses-view (:licenses workflow) language]
    [:div.col.commands [back-button]]])
diff --git a/src/cljs/rems/administration/workflows.cljs b/src/cljs/rems/administration/workflows.cljs
index 50a10a8cb..24d529c73 100644
--- a/src/cljs/rems/administration/workflows.cljs
+++ b/src/cljs/rems/administration/workflows.cljs
@@ -83,7 +83,7 @@
    :end {:header #(text :t.administration/end)
          :value (comp localize-time :end)}
    :active {:header #(text :t.administration/active)
-            :value (comp readonly-checkbox :active)}
+            :value (comp readonly-checkbox not :expired)}
    :commands {:values (fn [workflow]
                         [[to-view-workflow (:id workflow)]
                          [status-flags/enabled-toggle workflow #(rf/dispatch [::update-workflow %])]
diff --git a/src/cljs/rems/application.cljs b/src/cljs/rems/application.cljs
index d009531f0..4ff35360a 100644
--- a/src/cljs/rems/application.cljs
+++ b/src/cljs/rems/application.cljs
@@ -100,7 +100,7 @@
 (rf/reg-fx
  ::fetch-application
  (fn [id]
-   (fetch (str "/api/applications/" id)
+   (fetch (str "/api/v2/applications/" id)
           {:handler #(rf/dispatch [::fetch-application-result %])})))
 
 (rf/reg-event-db
diff --git a/src/cljs/rems/applications.cljs b/src/cljs/rems/applications.cljs
index 1f265ccf9..f24e32ef7 100644
--- a/src/cljs/rems/applications.cljs
+++ b/src/cljs/rems/applications.cljs
@@ -16,7 +16,7 @@
 (rf/reg-event-fx
  ::fetch-my-applications
  (fn [{:keys [db]} _]
-   (fetch "/api/applications"
+   (fetch "/api/v2/applications"
           {:handler #(rf/dispatch [::fetch-my-applications-result %])})
    {:db (assoc db ::loading-my-applications? true)}))
 
diff --git a/src/cljs/rems/catalogue.cljs b/src/cljs/rems/catalogue.cljs
index 74a564583..467ce73b6 100644
--- a/src/cljs/rems/catalogue.cljs
+++ b/src/cljs/rems/catalogue.cljs
@@ -56,7 +56,7 @@
 (rf/reg-event-fx
  ::fetch-drafts
  (fn [{:keys [db]} _]
-   (fetch "/api/applications"
+   (fetch "/api/v2/applications"
           {:handler #(rf/dispatch [::fetch-drafts-result %])})
    {:db (assoc db ::loading-drafts? true)}))
 
@@ -89,11 +89,6 @@
               :sortable? false
               :filterable? false}})
 
-(defn- catalogue-item-visible? [item]
-  ;; archived items are not returned from the API
-  (and (:enabled item)
-       (:active item)))
-
 (defn- catalogue-list
   "Renders the catalogue using table.
 
@@ -103,7 +98,7 @@
    (merge {:column-definitions (catalogue-columns language config)
            :visible-columns [:name :commands]
            :id-function :id
-           :items (filter catalogue-item-visible? items)
+           :items items
            :class "catalogue"}
           (when sorting {:sorting sorting})
           (when filtering {:filtering filtering}))])
diff --git a/src/cljs/rems/new_application.cljs b/src/cljs/rems/new_application.cljs
index 01a6400fb..1248e88db 100644
--- a/src/cljs/rems/new_application.cljs
+++ b/src/cljs/rems/new_application.cljs
@@ -12,7 +12,7 @@
 (rf/reg-event-fx
  ::enter-new-application-page
  (fn [{:keys [db]} [_ catalogue-item-ids]]
-   (post! "/api/applications/create"
+   (post! "/api/v2/applications/create"
           {:params {:catalogue-item-ids catalogue-item-ids}
            :handler (fn [response]
                       (remove-catalogue-items-from-cart! catalogue-item-ids)


Test patch:
diff --git a/test/clj/rems/api/test_applications.clj b/test/clj/rems/api/test_applications.clj
index e7856fef0..217316e70 100644
--- a/test/clj/rems/api/test_applications.clj
+++ b/test/clj/rems/api/test_applications.clj
@@ -51,47 +51,47 @@
         workflow-id (create-dynamic-workflow)]
     (create-catalogue-item form-id workflow-id)))
 
-(defn- send-command [actor cmd]
+(defn- send-dynamic-command [actor cmd]
   (-> (request :post (str "/api/applications/" (name (:type cmd))))
       (authenticate "42" actor)
       (json-body (dissoc cmd :type))
       handler
       read-body))
 
-(defn- create-application [catalogue-item-ids user-id]
-  (-> (request :post "/api/applications/create")
+(defn- create-v2-application [catalogue-item-ids user-id]
+  (-> (request :post "/api/v2/applications/create")
       (authenticate "42" user-id)
       (json-body {:catalogue-item-ids catalogue-item-ids})
       handler
       read-ok-body
       :application-id))
 
-(defn- create-dummy-application [user-id]
-  (create-application [(create-dymmy-catalogue-item)] user-id))
+(defn- create-dynamic-application [user-id]
+  (create-v2-application [(create-dymmy-catalogue-item)] user-id))
 
 (defn- get-ids [applications]
   (set (map :application/id applications)))
 
-(defn- get-applications [user-id]
-  (-> (request :get "/api/applications")
+(defn- get-v2-applications [user-id]
+  (-> (request :get "/api/v2/applications")
       (authenticate "42" user-id)
       handler
       read-ok-body))
 
-(defn- get-application [app-id user-id]
-  (-> (request :get (str "/api/applications/" app-id))
+(defn- get-v2-application [app-id user-id]
+  (-> (request :get (str "/api/v2/applications/" app-id))
       (authenticate "42" user-id)
       handler
       read-ok-body))
 
-(defn- get-open-reviews [user-id]
-  (-> (request :get "/api/reviews/open")
+(defn- get-v2-open-reviews [user-id]
+  (-> (request :get "/api/v2/reviews/open")
       (authenticate "42" user-id)
       handler
       read-ok-body))
 
-(defn- get-handled-reviews [user-id]
-  (-> (request :get "/api/reviews/handled")
+(defn- get-v2-handled-reviews [user-id]
+  (-> (request :get "/api/v2/reviews/handled")
       (authenticate "42" user-id)
       handler
       read-ok-body))
@@ -106,7 +106,7 @@
         [_ token] (re-find token-regex (:body response))]
     token))
 
-(deftest test-application-api-session
+(deftest application-api-session-test
   (let [username "alice"
         login-headers (-> (request :get "/Shibboleth.sso/Login" {:username username})
                           handler
@@ -122,7 +122,7 @@
     (is cookie)
     (is csrf)
     (testing "save with session"
-      (let [body (-> (request :post "/api/applications/create")
+      (let [body (-> (request :post "/api/v2/applications/create")
                      (header "Cookie" cookie)
                      (header "x-csrf-token" csrf)
                      (json-body {:catalogue-item-ids [cat-id]})
@@ -131,13 +131,13 @@
                      read-body)]
         (is (:success body))))
     (testing "save with session but without csrf"
-      (let [response (-> (request :post "/api/applications/create")
+      (let [response (-> (request :post "/api/v2/applications/create")
                          (header "Cookie" cookie)
                          (json-body {:catalogue-item-ids [cat-id]})
                          handler)]
         (is (response-is-unauthorized? response))))
     (testing "save with session and csrf and wrong api-key"
-      (let [response (-> (request :post "/api/applications/create")
+      (let [response (-> (request :post "/api/v2/applications/create")
                          (header "Cookie" cookie)
                          (header "x-csrf-token" csrf)
                          (header "x-rems-api-key" "WRONG")
@@ -166,7 +166,7 @@
       (is (= "application/pdf" (get-in response [:headers "Content-Type"])))
       (is (.startsWith (slurp (:body response)) "%PDF-1.")))))
 
-(deftest test-application-commands
+(deftest dynamic-applications-test
   (let [user-id "alice"
         handler-id "developer"
         commenter-id "carl"
@@ -174,7 +174,7 @@
         application-id 11] ;; submitted dynamic application from test data
 
     (testing "getting dynamic application as applicant"
-      (let [application (get-application application-id user-id)]
+      (let [application (get-v2-application application-id user-id)]
         (is (= "workflow/dynamic" (get-in application [:application/workflow :workflow/type])))
         (is (= ["application.event/created"
                 "application.event/draft-saved"
@@ -185,7 +185,7 @@
                (set (get application :application/permissions))))))
 
     (testing "getting dynamic application as handler"
-      (let [application (get-application application-id handler-id)]
+      (let [application (get-v2-application application-id handler-id)]
         (is (= "workflow/dynamic" (get-in application [:application/workflow :workflow/type])))
         (is (= #{"application.command/request-comment"
                  "application.command/request-decision"
@@ -202,63 +202,63 @@
     (testing "send command without user"
       (is (= {:success false
               :errors [{:type "forbidden"}]}
-             (send-command "" {:type :application.command/approve
-                               :comment "" :application-id application-id}))
+             (send-dynamic-command "" {:type :application.command/approve
+                                       :comment "" :application-id application-id}))
           "user should be forbidden to send command"))
 
     (testing "send command with a user that is not a handler"
       (is (= {:success false
               :errors [{:type "forbidden"}]}
-             (send-command user-id {:type :application.command/approve
-                                    :application-id application-id
-                                    :comment ""}))
+             (send-dynamic-command user-id {:type :application.command/approve
+                                            :application-id application-id
+                                            :comment ""}))
           "user should be forbidden to send command"))
 
     (testing "send commands with authorized user"
       (testing "even handler cannot comment without request"
         (is (= {:errors [{:type "forbidden"}], :success false}
-               (send-command handler-id
-                             {:type :application.command/comment
-                              :application-id application-id
-                              :comment "What am I commenting on?"}))))
+               (send-dynamic-command handler-id
+                                     {:type :application.command/comment
+                                      :application-id application-id
+                                      :comment "What am I commenting on?"}))))
       (testing "comment with request"
-        (let [eventcount (count (get (get-application application-id handler-id) :events))]
+        (let [eventcount (count (get (get-v2-application application-id handler-id) :events))]
           (testing "requesting comment"
-            (is (= {:success true} (send-command handler-id
-                                                 {:type :application.command/request-comment
-                                                  :application-id application-id
-                                                  :commenters [decider-id commenter-id]
-                                                  :comment "What say you?"}))))
+            (is (= {:success true} (send-dynamic-command handler-id
+                                                         {:type :application.command/request-comment
+                                                          :application-id application-id
+                                                          :commenters [decider-id commenter-id]
+                                                          :comment "What say you?"}))))
           (testing "commenter can now comment"
-            (is (= {:success true} (send-command commenter-id
-                                                 {:type :application.command/comment
-                                                  :application-id application-id
-                                                  :comment "Yeah, I dunno"}))))
+            (is (= {:success true} (send-dynamic-command commenter-id
+                                                         {:type :application.command/comment
+                                                          :application-id application-id
+                                                          :comment "Yeah, I dunno"}))))
           (testing "comment was linked to request"
-            (let [application (get-application application-id handler-id)
+            (let [application (get-v2-application application-id handler-id)
                   request-event (get-in application [:application/events eventcount])
                   comment-event (get-in application [:application/events (inc eventcount)])]
               (is (= (:application/request-id request-event)
                      (:application/request-id comment-event)))))))
       (testing "request-decision"
-        (is (= {:success true} (send-command handler-id
-                                             {:type :application.command/request-decision
-                                              :application-id application-id
-                                              :deciders [decider-id]
-                                              :comment ""}))))
+        (is (= {:success true} (send-dynamic-command handler-id
+                                                     {:type :application.command/request-decision
+                                                      :application-id application-id
+                                                      :deciders [decider-id]
+                                                      :comment ""}))))
       (testing "decide"
-        (is (= {:success true} (send-command decider-id
-                                             {:type :application.command/decide
-                                              :application-id application-id
-                                              :decision :approved
-                                              :comment ""}))))
+        (is (= {:success true} (send-dynamic-command decider-id
+                                                     {:type :application.command/decide
+                                                      :application-id application-id
+                                                      :decision :approved
+                                                      :comment ""}))))
       (testing "approve"
-        (is (= {:success true} (send-command handler-id {:type :application.command/approve
-                                                         :application-id application-id
-                                                         :comment ""})))
-        (let [handler-data (get-application application-id handler-id)
+        (is (= {:success true} (send-dynamic-command handler-id {:type :application.command/approve
+                                                                 :application-id application-id
+                                                                 :comment ""})))
+        (let [handler-data (get-v2-application application-id handler-id)
               handler-event-types (map :event/type (get handler-data :application/events))
-              applicant-data (get-application application-id user-id)
+              applicant-data (get-v2-application application-id user-id)
               applicant-event-types (map :event/type (get applicant-data :application/events))]
           (testing "handler can see all events"
             (is (= {:application/id application-id
@@ -280,35 +280,35 @@
                     "application.event/approved"]
                    applicant-event-types))))))))
 
-(deftest test-application-create
+(deftest dynamic-application-create-test
   (let [api-key "42"
         user-id "alice"
-        application-id (create-dummy-application user-id)]
+        application-id (create-dynamic-application user-id)]
 
     (testing "creating"
       (is (some? application-id))
-      (let [created (get-application application-id user-id)]
+      (let [created (get-v2-application application-id user-id)]
         (is (= "application.state/draft" (get created :application/state)))))
 
     (testing "getting application as other user is forbidden"
       (is (response-is-forbidden?
-           (-> (request :get (str "/api/applications/" application-id))
+           (-> (request :get (str "/api/v2/applications/" application-id))
                (authenticate api-key "bob")
                handler))))
 
     (testing "modifying application as other user is forbidden"
       (is (= {:success false
               :errors [{:type "forbidden"}]}
-             (send-command "bob" {:type :application.command/save-draft
-                                  :application-id application-id
-                                  :field-values {}
-                                  :accepted-licenses #{}}))))
+             (send-dynamic-command "bob" {:type :application.command/save-draft
+                                          :application-id application-id
+                                          :field-values {}
+                                          :accepted-licenses #{}}))))
 
     (testing "submitting"
       (is (= {:success true}
-             (send-command user-id {:type :application.command/submit
-                                    :application-id application-id})))
-      (let [submitted (get-application application-id user-id)]
+             (send-dynamic-command user-id {:type :application.command/submit
+                                            :application-id application-id})))
+      (let [submitted (get-v2-application application-id user-id)]
         (is (= "application.state/submitted" (get submitted :application/state)))
         (is (= ["application.event/created"
                 "application.event/submitted"]
@@ -328,7 +328,7 @@
                         :filename "malicious_test.html"
                         :size (.length malicious-file)})
 
-(deftest test-application-api-attachments
+(deftest application-api-attachments-test
   (let [api-key "42"
         user-id "alice"
         workflow-id (create-dynamic-workflow)
@@ -337,147 +337,123 @@
                                            :optional true}])
         field-id (-> (form/get-form form-id) :fields first :id)
         cat-id (create-catalogue-item form-id workflow-id)
-        app-id (create-application [cat-id] user-id)
-        upload-request (fn [file]
-                         (-> (request :post (str "/api/applications/add-attachment?application-id=" app-id "&field-id=" field-id))
-                             (assoc :params {"file" file})
-                             (assoc :multipart-params {"file" file})))
-        read-request (request :get "/api/applications/attachments" {:application-id app-id :field-id field-id})]
+        app-id (create-v2-application [cat-id] user-id)]
     (testing "uploading attachment for a draft"
-      (let [body (-> (upload-request filecontent)
+      (let [body (-> (request :post (str "/api/applications/add-attachment?application-id=" app-id "&field-id=" field-id))
+                     (assoc :params {"file" filecontent})
+                     (assoc :multipart-params {"file" filecontent})
                      (authenticate api-key user-id)
                      handler
                      read-ok-body)]
         (is (= {:success true} body))))
     (testing "uploading malicious file for a draft"
-      (let [response (-> (upload-request malicious-content)
+      (let [response (-> (request :post (str "/api/applications/add-attachment?application-id=" app-id "&field-id=" field-id))
+                         (assoc :params {"file" malicious-content})
+                         (assoc :multipart-params {"file" malicious-content})
                          (authenticate api-key user-id)
                          handler)]
         (is (response-is-bad-request? response))))
     (testing "retrieving attachment for a draft"
-      (let [response (-> read-request
+      (let [response (-> (request :get "/api/applications/attachments" {:application-id app-id :field-id field-id})
                          (authenticate api-key user-id)
                          handler
                          assert-response-is-ok)]
         (is (= (slurp testfile) (slurp (:body response))))))
-    (testing "uploading attachment without authentication"
-      (let [response (-> (upload-request filecontent)
-                         handler)]
-        (is (response-is-unauthorized? response))))
-    (testing "uploading attachment with wrong API key"
-      (let [response (-> (upload-request filecontent)
-                         (authenticate api-key user-id)
-                         (assoc-in [:headers "x-rems-api-key"] "invalid-api-key")
-                         handler)]
-        (is (response-is-unauthorized? response))))
     (testing "uploading attachment as non-applicant"
-      (let [response (-> (upload-request filecontent)
+      (let [response (-> (request :post (str "/api/applications/add-attachment?application-id=" app-id "&field-id=" field-id))
+                         (assoc :params {"file" filecontent})
+                         (assoc :multipart-params {"file" filecontent})
                          (authenticate api-key "carl")
                          handler)]
         (is (response-is-forbidden? response))))
     (testing "retrieving attachment as non-applicant"
-      (let [response (-> read-request
+      (let [response (-> (request :get "/api/applications/attachments" {:application-id app-id :field-id field-id})
                          (authenticate api-key "carl")
                          handler)]
         (is (response-is-forbidden? response))))
+    (testing "submit application"
+      (is (= {:success true} (send-dynamic-command user-id {:type :application.command/submit
+                                                            :application-id app-id}))))
     (testing "uploading attachment for a submitted application"
-      (assert (= {:success true} (send-command user-id {:type :application.command/submit
-                                                        :application-id app-id})))
-      (let [response (-> (upload-request filecontent)
+      (let [response (-> (request :post (str "/api/applications/add-attachment?application-id=" app-id "&field-id=" field-id))
+                         (assoc :params {"file" filecontent})
+                         (assoc :multipart-params {"file" filecontent})
                          (authenticate api-key user-id)
                          handler)]
         (is (response-is-forbidden? response))))))
 
-(deftest test-applications-api-security
-  (let [api-key "42"
-        applicant "alice"
-        cat-id (create-dymmy-catalogue-item)
-        app-id (create-application [cat-id] applicant)]
-
+(deftest applications-api-security-test
+  (let [cat-id (create-dymmy-catalogue-item)
+        app-id (create-v2-application [cat-id] "alice")]
     (testing "fetch application without authentication"
-      (let [req (request :get (str "/api/applications/" app-id))]
-        (assert-response-is-ok (-> req
-                                   (authenticate api-key applicant)
-                                   handler))
-        (is (response-is-unauthorized? (-> req
-                                           handler)))))
-
-    (testing "fetch deciders without authentication or as non-handler"
-      (let [req (request :get "/api/applications/deciders")]
-        (assert-response-is-ok (-> req
-                                   (authenticate api-key "developer")
-                                   handler))
-        (is (response-is-forbidden? (-> req
-                                        (authenticate api-key applicant)
-                                        handler)))
-        (is (response-is-unauthorized? (-> req
-                                           handler)))))
-
+      (is (response-is-unauthorized? (-> (request :get (str "/api/v2/applications/" app-id))
+                                         handler))))
+    (testing "fetch deciders without authentication"
+      (is (response-is-unauthorized? (-> (request :get "/api/applications/deciders")
+                                         handler))))
     (testing "create without authentication"
-      (let [req (-> (request :post "/api/applications/create")
-                    (json-body {:catalogue-item-ids [cat-id]}))]
-        (assert-response-is-ok (-> req
-                                   (authenticate api-key applicant)
-                                   handler))
-        (is (response-is-unauthorized? (-> req
-                                           handler)))))
-
-    (testing "create with wrong API key"
-      (let [req (-> (request :post "/api/applications/create")
-                    (authenticate api-key applicant)
-                    (json-body {:catalogue-item-ids [cat-id]}))]
-        (assert-response-is-ok (-> req
-                                   handler))
-        (is (response-is-unauthorized? (-> req
-                                           (assoc-in [:headers "x-rems-api-key"] "invalid-api-key")
-                                           handler)))))
-
+      (is (response-is-unauthorized? (-> (request :post "/api/v2/applications/create")
+                                         (json-body {:catalogue-item-ids [cat-id]})
+                                         handler))))
+    (testing "create with wrong API-Key"
+      (is (response-is-unauthorized? (-> (request :post "/api/v2/applications/create")
+                                         (assoc-in [:headers "x-rems-api-key"] "invalid-api-key")
+                                         (json-body {:catalogue-item-ids [cat-id]})
+                                         handler))))
     (testing "send command without authentication"
-      (let [req (-> (request :post "/api/applications/submit")
-                    (json-body {:application-id app-id}))]
-        (assert-response-is-ok (-> req
-                                   (authenticate api-key applicant)
-                                   handler))
-        (is (response-is-unauthorized? (-> req
-                                           handler)))))
-
-    (testing "send command with wrong API key"
-      (let [req (-> (request :post "/api/applications/submit")
-                    (authenticate api-key applicant)
-                    (json-body {:application-id app-id}))]
-        (assert-response-is-ok (-> req
-                                   handler))
-        (is (response-is-unauthorized? (-> req
-                                           (assoc-in [:headers "x-rems-api-key"] "invalid-api-key")
-                                           handler)))))))
-
-(deftest test-application-listing
-  (let [app-id (create-dummy-application "alice")]
+      (is (response-is-unauthorized? (-> (request :post "/api/applications/command")
+                                         (json-body {:type :application.command/submit
+                                                     :application-id app-id})
+                                         handler))))
+    (testing "send command with wrong api-key"
+      (is (response-is-unauthorized? (-> (request :post "/api/applications/command")
+                                         (authenticate "invalid-api-key" "alice")
+                                         (json-body {:type :application.command/submit
+                                                     :application-id app-id})
+                                         handler))))
+    (testing "upload attachment without authentication"
+      (is (response-is-unauthorized? (-> (request :post "/api/applications/add_attachment")
+                                         (assoc :params {"file" filecontent})
+                                         (assoc :multipart-params {"file" filecontent})
+                                         handler))))
+    (testing "upload attachment with wrong API-Key"
+      (is (response-is-unauthorized? (-> (request :post "/api/applications/add_attachment")
+                                         (assoc :params {"file" filecontent})
+                                         (assoc :multipart-params {"file" filecontent})
+                                         (authenticate "invalid-api-key" "developer")
+                                         handler))))))
+
+(deftest test-v2-application-api
+  (let [app-id (create-dynamic-application "alice")]
 
     (testing "list user applications"
-      (is (contains? (get-ids (get-applications "alice"))
-                     app-id)))))
+      (is (contains? (get-ids (get-v2-applications "alice"))
+                     app-id)))
+
+    (testing "get single application"
+      (is (= app-id
+             (:application/id (get-v2-application app-id "alice")))))))
 
-(deftest test-reviews
-  (let [app-id (create-dummy-application "alice")]
+(deftest test-v2-review-api
+  (let [app-id (create-dynamic-application "alice")]
 
     (testing "does not list drafts"
-      (is (not (contains? (get-ids (get-open-reviews "developer"))
+      (is (not (contains? (get-ids (get-v2-open-reviews "developer"))
                           app-id))))
 
     (testing "lists submitted in open reviews"
-      (is (= {:success true} (send-command "alice" {:type :application.command/submit
-                                                    :application-id app-id})))
-      (is (contains? (get-ids (get-open-reviews "developer"))
+      (is (= {:success true} (send-dynamic-command "alice" {:type :application.command/submit
+                                                            :application-id app-id})))
+      (is (contains? (get-ids (get-v2-open-reviews "developer"))
                      app-id))
-      (is (not (contains? (get-ids (get-handled-reviews "developer"))
+      (is (not (contains? (get-ids (get-v2-handled-reviews "developer"))
                           app-id))))
 
     (testing "lists handled in handled reviews"
-      (is (= {:success true} (send-command "developer" {:type :application.command/approve
-                                                        :application-id app-id
-                                                        :comment ""})))
-      (is (not (contains? (get-ids (get-open-reviews "developer"))
+      (is (= {:success true} (send-dynamic-command "developer" {:type :application.command/approve
+                                                                :application-id app-id
+                                                                :comment ""})))
+      (is (not (contains? (get-ids (get-v2-open-reviews "developer"))
                           app-id)))
-      (is (contains? (get-ids (get-handled-reviews "developer"))
+      (is (contains? (get-ids (get-v2-handled-reviews "developer"))
                      app-id)))))
diff --git a/test/clj/rems/api/test_forms.clj b/test/clj/rems/api/test_forms.clj
index 4b86d7cc8..ec54ff64d 100644
--- a/test/clj/rems/api/test_forms.clj
+++ b/test/clj/rems/api/test_forms.clj
@@ -190,8 +190,8 @@
                      read-body)]
     (is (coll-is-not-empty? unfiltered))
     (is (coll-is-not-empty? filtered))
-    (is (every? #(contains? % :active) unfiltered))
-    (is (every? :active filtered))
+    (is (every? #(contains? % :expired) unfiltered))
+    (is (not-any? :expired filtered))
     (is (< (count filtered) (count unfiltered)))))
 
 (deftest forms-api-security-test
diff --git a/test/clj/rems/api/test_resources.clj b/test/clj/rems/api/test_resources.clj
index 8e846c4f1..87f24e211 100644
--- a/test/clj/rems/api/test_resources.clj
+++ b/test/clj/rems/api/test_resources.clj
@@ -136,8 +136,8 @@
                      read-body)]
     (is (coll-is-not-empty? unfiltered))
     (is (coll-is-not-empty? filtered))
-    (is (every? #(contains? % :active) unfiltered))
-    (is (every? :active filtered))
+    (is (every? #(contains? % :expired) unfiltered))
+    (is (not-any? :expired filtered))
     (is (< (count filtered) (count unfiltered)))))
 
 (deftest resources-api-security-test
diff --git a/test/clj/rems/api/test_workflows.clj b/test/clj/rems/api/test_workflows.clj
index 03b8cb45e..6ce3f1ce8 100644
--- a/test/clj/rems/api/test_workflows.clj
+++ b/test/clj/rems/api/test_workflows.clj
@@ -109,8 +109,8 @@
                      read-body)]
     (is (coll-is-not-empty? unfiltered))
     (is (coll-is-not-empty? filtered))
-    (is (every? #(contains? % :active) unfiltered))
-    (is (every? :active filtered))
+    (is (every? #(contains? % :expired) unfiltered))
+    (is (not-any? :expired filtered))
     (is (< (count filtered) (count unfiltered)))))
 
 (deftest workflows-api-security-test
diff --git a/test/clj/rems/application/test_model.clj b/test/clj/rems/application/test_model.clj
index 18410f247..c0d8237f4 100644
--- a/test/clj/rems/application/test_model.clj
+++ b/test/clj/rems/application/test_model.clj
@@ -48,7 +48,7 @@
                                              :end nil
                                              :enabled true
                                              :archived false
-                                             :active true
+                                             :expired false
                                              :state "enabled"}
                                          20 {:id 20
                                              :resource-id 21
@@ -66,7 +66,7 @@
                                              :end nil
                                              :enabled true
                                              :archived false
-                                             :active true
+                                             :expired false
                                              :state "enabled"}}
 
                     :get-license {30 {:id 30
@@ -80,7 +80,7 @@
                                       :start (DateTime. 100)
                                       :end nil
                                       :enabled true
-                                      :active true
+                                      :expired false
                                       :archived false}
                                   31 {:id 31
                                       :licensetype "text"
@@ -93,7 +93,7 @@
                                       :start (DateTime. 100)
                                       :end nil
                                       :enabled true
-                                      :active true
+                                      :expired false
                                       :archived false}
                                   32 {:id 32
                                       :licensetype "attachment"
@@ -109,7 +109,7 @@
                                       :start (DateTime. 100)
                                       :end nil
                                       :enabled true
-                                      :active true
+                                      :expired false
                                       :archived false}}
 
                     :get-user {"applicant" {:eppn "applicant"
@@ -162,7 +162,7 @@
                                                            :catalogue-item/start (DateTime. 100)
                                                            :catalogue-item/end nil
                                                            :catalogue-item/enabled true
-                                                           :catalogue-item/active true
+                                                           :catalogue-item/expired false
                                                            :catalogue-item/archived false}
                                                           {:catalogue-item/id 20
                                                            :resource/id 21
@@ -173,7 +173,7 @@
                                                            :catalogue-item/start (DateTime. 100)
                                                            :catalogue-item/end nil
                                                            :catalogue-item/enabled true
-                                                           :catalogue-item/active true
+                                                           :catalogue-item/expired false
                                                            :catalogue-item/archived false}]
                                   :application/licenses [{:license/id 30
                                                           :license/accepted false
@@ -186,7 +186,7 @@
                                                                          :default "http://non-localized-license-link"}
                                                           :license/start (DateTime. 100)
                                                           :license/end nil
-                                                          :license/active true
+                                                          :license/expired false
                                                           :license/enabled true
                                                           :license/archived false}
                                                          {:license/id 31
@@ -200,7 +200,7 @@
                                                                          :default "non-localized license text"}
                                                           :license/start (DateTime. 100)
                                                           :license/end nil
-                                                          :license/active true
+                                                          :license/expired false
                                                           :license/enabled true
                                                           :license/archived false}
                                                          {:license/id 32
@@ -217,7 +217,7 @@
                                                                                         :default "non-localized filename"}
                                                           :license/start (DateTime. 100)
                                                           :license/end nil
-                                                          :license/active true
+                                                          :license/expired false
                                                           :license/enabled true
                                                           :license/archived false}]
                                   :application/accepted-licenses {"applicant" #{}}
diff --git a/test/clj/rems/db/test_core.clj b/test/clj/rems/db/test_core.clj
index 0e4228cb6..ab9288413 100644
--- a/test/clj/rems/db/test_core.clj
+++ b/test/clj/rems/db/test_core.clj
@@ -21,14 +21,17 @@
     (is (now-active? nil tomorrow) "still active")
     (is (not (now-active? nil yesterday)) "already expired")))
 
-(deftest test-assoc-active
-  (is (= {:active true} (assoc-active nil)))
-  (is (= {:active true :start nil :endt nil :foobar 42} (assoc-active {:start nil :endt nil :foobar 42})))
+(deftest test-assoc-expired
+  (is (= {:expired false} (assoc-expired nil)))
+  (is (= {:expired false :start nil :endt nil :foobar 42} (assoc-expired {:start nil :endt nil :foobar 42})))
   (let [today (time/now)
         yesterday (time/minus today (time/days 1))
         tomorrow (time/plus today (time/days 1))]
-    (is (= {:active false :start tomorrow :endt nil} (assoc-active {:start tomorrow :endt nil})))
-    (is (= {:active false :start nil :endt yesterday} (assoc-active {:start nil :endt yesterday})))))
+    (is (= {:expired true :start tomorrow :endt nil} (assoc-expired {:start tomorrow :endt nil})))
+    (is (= {:expired true :start nil :endt yesterday} (assoc-expired {:start nil :endt yesterday})))
+    (is (= {:expired false :start yesterday :endt tomorrow} (assoc-expired {:start yesterday :endt tomorrow})))
+    (is (= {:expired false :start yesterday :endt nil} (assoc-expired {:start yesterday :endt nil})))
+    (is (= {:expired false :start nil :endt tomorrow} (assoc-expired {:start nil :endt tomorrow})))))
 
 (defn- take-ids [items]
   (map :id items))
@@ -46,7 +49,7 @@
         ; the following idiom can be used when reading database entries with 'endt' field
         get-items (fn [filters]
                     (->> all-items
-                         (map assoc-active)
+                         (map assoc-expired)
                          (apply-filters filters)))]
 
     (testing "find all items"
@@ -54,10 +57,10 @@
       (is (= [:normal :expired] (take-ids (get-items nil)))))
 
     (testing "find active items"
-      (is (= [:normal] (take-ids (get-items {:active true})))))
+      (is (= [:normal] (take-ids (get-items {:expired false})))))
 
     (testing "find expired items"
-      (is (= [:expired] (take-ids (get-items {:active false})))))
+      (is (= [:expired] (take-ids (get-items {:expired true})))))
 
     (testing "calculates :active property"
-      (is (every? #(contains? % :active) (get-items {}))))))
+      (is (every? #(contains? % :expired) (get-items {}))))))
diff --git a/test/clj/rems/db/testing.clj b/test/clj/rems/db/testing.clj
index 33032e00d..23de51de1 100644
--- a/test/clj/rems/db/testing.clj
+++ b/test/clj/rems/db/testing.clj
@@ -8,7 +8,6 @@
             [rems.db.test-data :as test-data]))
 
 (defn test-db-fixture [f]
-  (mount/stop) ;; during interactive development, app might be running when tests start. we need to tear it down
   (mount/start-with-args {:test true}
                          #'rems.config/env
                          #'rems.db.core/*db*)