diff --git a/.docs/.swagger/api-analyse.yaml b/.docs/.swagger/api-analyse.yaml
index 4ec0ed6e72d74926538c22f42b92015730bb056a..d40208256c83e2f6ffef38f9bb1d2d517458c677 100644
--- a/.docs/.swagger/api-analyse.yaml
+++ b/.docs/.swagger/api-analyse.yaml
@@ -48,6 +48,8 @@ paths:
         '405':
           description: Invalid input
       summary: Determine datatypes
+      tags:
+        - analyse-endpoint
   /api/analyse/determinepk:
     post:
       consumes:
@@ -76,30 +78,109 @@ paths:
         '405':
           description: Invalid input
       summary: Determine primary keys
+      tags:
+        - analyse-endpoint
+  /api/analyse/determinestat:
+    post:
+      operationId: determinestat
+      requestBody:
+        content:
+          application/json:
+            schema:
+              properties:
+                database_id:
+                  example: 1
+                  type: integer
+                table_id:
+                  example: 1
+                  type: integer
+              required:
+                - database_id
+                - table_id
+              type: object
+      responses:
+        '200':
+          content:
+            application/json:
+              schema:
+                properties:
+                  message:
+                    example: Analysed statistical properties
+                    type: string
+                  status:
+                    example: '200'
+                    type: integer
+                required:
+                  - message
+                  - status
+                type: object
+          description: Determined statistics
+        '400':
+          description: Invalid input
+          ontent:
+            application/json:
+              schema:
+                properties:
+                  message:
+                    example: Analysed statistical properties
+                    type: string
+                  status:
+                    example: '200'
+                    type: integer
+                required:
+                  - message
+                  - status
+                type: object
+      summary: Determine statistics
+      tags:
+        - analyse-endpoint
+  /api/analyse/determinestats:
+    post:
+      operationId: determinestats
+      requestBody:
+        content:
+          application/json:
+            schema:
+              properties:
+                filepath:
+                  example: file.csv
+                  type: string
+                separator:
+                  example: ','
+                  type: string
+              required:
+                - filepath
+                - separator
+              type: object
+      responses:
+        '200':
+          description: Determined statistics
+        '400':
+          description: Invalid input
+      summary: Determine statistics
+      tags:
+        - analyse-endpoint
   /health:
     get:
       consumes:
         - application/json
       description: This is a simple API which checks if the application is healthy
-      parameters:
-        - description: to-do description
-          in: body
-          name: body
-          required: true
+      produces:
+        - application/json
+      responses:
+        '200':
+          description: OK
           schema:
             properties:
               status:
                 example: UP
                 type: string
             type: object
-      produces:
-        - application/json
-      responses:
-        '200':
-          description: OK
       summary: Check if application is running
+      tags:
+        - health-endpoint
 servers:
   - description: Generated server url
     url: http://localhost:5000
   - description: Sandbox
-    url: https://dbrepo2.tuwien.ac.at
+    url: https://test.dbrepo.tuwien.ac.at
diff --git a/.docs/.swagger/api-metadata.yaml b/.docs/.swagger/api-metadata.yaml
index 55cafa02395b0c4381155cb29be50279f4b8ff3c..ee2919a16ebb7cf5afe3308065e27e95ca3dbc0b 100644
--- a/.docs/.swagger/api-metadata.yaml
+++ b/.docs/.swagger/api-metadata.yaml
@@ -44,14 +44,16 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Find table history is not permitted
+        "200":
+          description: Find table history successfully
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Query store failed to query table history
+                type: array
+                items:
+                  $ref: '#/components/schemas/TableHistoryDto'
+        "403":
+          description: Find table history is not permitted
           content:
             application/json:
               schema:
@@ -62,14 +64,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "200":
-          description: Find table history successfully
+        "409":
+          description: Query store failed to query table history
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/TableHistoryDto'
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
     head:
@@ -97,14 +97,16 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Find table history is not permitted
+        "200":
+          description: Find table history successfully
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Query store failed to query table history
+                type: array
+                items:
+                  $ref: '#/components/schemas/TableHistoryDto'
+        "403":
+          description: Find table history is not permitted
           content:
             application/json:
               schema:
@@ -115,14 +117,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "200":
-          description: Find table history successfully
+        "409":
+          description: Query store failed to query table history
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/TableHistoryDto'
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/database/{databaseId}/table/{tableId}/data:
@@ -176,6 +176,12 @@ paths:
         schema:
           type: string
       responses:
+        "422":
+          description: Could not import csv via sidecar
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Access to the database is forbidden
           content:
@@ -200,12 +206,6 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "422":
-          description: Could not import csv via sidecar
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
     post:
@@ -233,20 +233,14 @@ paths:
               $ref: '#/components/schemas/TableCsvDto'
         required: true
       responses:
-        "403":
-          description: Access to the database is forbidden
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "202":
           description: Inserted data successfully
           content:
             '*/*':
               schema:
                 type: object
-        "400":
-          description: Insert table data is malformed
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
@@ -257,6 +251,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "400":
+          description: Insert table data is malformed
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
     delete:
@@ -286,20 +286,20 @@ paths:
       responses:
         "202":
           description: Deleted table data successfully
-        "403":
-          description: Access to the database is forbidden
+        "400":
+          description: Table data or query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Table or database could not be found
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Table data or query is malformed
+        "404":
+          description: Table or database could not be found
           content:
             application/json:
               schema:
@@ -356,6 +356,12 @@ paths:
         schema:
           type: string
       responses:
+        "422":
+          description: Could not import csv via sidecar
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Access to the database is forbidden
           content:
@@ -380,12 +386,6 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "422":
-          description: Could not import csv via sidecar
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/user/{id}:
@@ -441,32 +441,32 @@ paths:
               $ref: '#/components/schemas/UserUpdateDto'
         required: true
       responses:
-        "202":
-          description: Modified user information
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/UserDto'
         "404":
           description: User attribute was not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Modified user information
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/UserDto'
         "403":
           description: Modify user is not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Foreign user modification
+        "400":
+          description: Modify user query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Modify user query is malformed
+        "405":
+          description: Foreign user modification
           content:
             application/json:
               schema:
@@ -493,12 +493,6 @@ paths:
               $ref: '#/components/schemas/UserThemeSetDto'
         required: true
       responses:
-        "404":
-          description: User or user attribute was not found
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Modify user is not permitted
           content:
@@ -511,6 +505,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/UserDto'
+        "404":
+          description: User or user attribute was not found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "405":
           description: Foreign user modification
           content:
@@ -539,14 +539,8 @@ paths:
               $ref: '#/components/schemas/UserPasswordDto'
         required: true
       responses:
-        "202":
-          description: Modified user password
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/UserDto'
-        "405":
-          description: Foreign user modification
+        "503":
+          description: Authentication service does not respond
           content:
             application/json:
               schema:
@@ -557,14 +551,20 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Modified user password
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/UserDto'
         "403":
           description: Modify is not allowed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "503":
-          description: Authentication service does not respond
+        "405":
+          description: Foreign user modification
           content:
             application/json:
               schema:
@@ -585,18 +585,18 @@ paths:
           type: integer
           format: int64
       responses:
-        "404":
-          description: Could not find ontology
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "200":
           description: Find one ontology
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/OntologyDto'
+        "404":
+          description: Could not find ontology
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
     put:
       tags:
       - ontology-endpoint
@@ -616,18 +616,18 @@ paths:
               $ref: '#/components/schemas/OntologyModifyDto'
         required: true
       responses:
-        "202":
-          description: Updated ontology successfully
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/OntologyDto'
         "404":
           description: Could not find ontology
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Updated ontology successfully
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/OntologyDto'
       security:
       - bearerAuth: []
     delete:
@@ -643,16 +643,16 @@ paths:
           type: integer
           format: int64
       responses:
-        "202":
-          description: Deleted ontology successfully
-          content:
-            application/json: {}
         "404":
           description: Could not find ontology
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Deleted ontology successfully
+          content:
+            application/json: {}
       security:
       - bearerAuth: []
   /api/maintenance/message/{id}:
@@ -837,12 +837,6 @@ paths:
               $ref: '#/components/schemas/DatabaseModifyVisibilityDto'
         required: true
       responses:
-        "404":
-          description: Database could not be found
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Visibility modification is not permitted
           content:
@@ -855,6 +849,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/DatabaseDto'
+        "404":
+          description: Database could not be found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/database/{id}/transfer:
@@ -883,18 +883,18 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "202":
-          description: Transfer of ownership was successful
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/DatabaseDto'
         "403":
           description: Transfer of ownership is not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Transfer of ownership was successful
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/DatabaseDto'
       security:
       - bearerAuth: []
   /api/database/{id}/table/{tableId}/column/{columnId}:
@@ -934,21 +934,15 @@ paths:
               $ref: '#/components/schemas/ColumnSemanticsUpdateDto'
         required: true
       responses:
-        "403":
-          description: Access to the database is forbidden
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Table or database could not be found
+        "400":
+          description: Update semantic concept query is malformed or update unit of
+            measurement query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Update semantic concept query is malformed or update unit of
-            measurement query is malformed
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
@@ -959,6 +953,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ColumnDto'
+        "404":
+          description: Table or database could not be found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/database/{id}/access/{userId}:
@@ -987,27 +987,27 @@ paths:
               $ref: '#/components/schemas/DatabaseModifyAccessDto'
         required: true
       responses:
-        "403":
-          description: Modify access not permitted when no access is granted in the
-            first place
+        "400":
+          description: Modify access query or database connection is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Modify access query or database connection is malformed
+        "403":
+          description: Modify access not permitted when no access is granted in the
+            first place
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "202":
-          description: Modify access succeeded
         "404":
           description: Database or user not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Modify access succeeded
       security:
       - bearerAuth: []
     post:
@@ -1041,12 +1041,6 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Granting access not permitted
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "202":
           description: Granting access succeeded
         "404":
@@ -1055,6 +1049,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "405":
+          description: Granting access not permitted
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "400":
           description: Granting access query or database connection is malformed
           content:
@@ -1094,14 +1094,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "202":
-          description: Revoked access successfully
         "403":
           description: Revoke of access not permitted as no access was found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Revoked access successfully
       security:
       - bearerAuth: []
   /api/database/{databaseId}/query/{queryId}:
@@ -1124,20 +1124,20 @@ paths:
           type: integer
           format: int64
       responses:
-        "501":
-          description: Image is not supported
+        "404":
+          description: "Database, query or user could not be found"
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "504":
-          description: Query store failed to select query
+        "405":
+          description: Find query is not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: "Database, query or user could not be found"
+        "503":
+          description: Connection to the database failed
           content:
             application/json:
               schema:
@@ -1148,14 +1148,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/QueryDto'
-        "503":
-          description: Connection to the database failed
+        "501":
+          description: Image is not supported
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Find query is not permitted
+        "504":
+          description: Query store failed to select query
           content:
             application/json:
               schema:
@@ -1187,20 +1187,20 @@ paths:
               $ref: '#/components/schemas/QueryPersistDto'
         required: true
       responses:
-        "412":
-          description: Query is already persisted
+        "400":
+          description: Image not supported
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Not allowed to persist query
+        "404":
+          description: "Database, query or user could not be found"
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Image not supported
+        "403":
+          description: Not allowed to persist query
           content:
             application/json:
               schema:
@@ -1211,8 +1211,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: "Database, query or user could not be found"
+        "412":
+          description: Query is already persisted
           content:
             application/json:
               schema:
@@ -1252,12 +1252,18 @@ paths:
               $ref: '#/components/schemas/SignupRequestDto'
         required: true
       responses:
+        "201":
+          description: Created user
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/UserBriefDto'
         "400":
           description: Parameters are not well-formed (likely email)
           content:
             application/json: {}
-        "404":
-          description: default role not found
+        "417":
+          description: User with e-mail already exists
           content:
             application/json:
               schema:
@@ -1268,18 +1274,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "417":
-          description: User with e-mail already exists
+        "404":
+          description: default role not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "201":
-          description: Created user
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/UserBriefDto'
   /api/semantic/ontology:
     get:
       tags:
@@ -1375,12 +1375,6 @@ paths:
               $ref: '#/components/schemas/ImageCreateDto'
         required: true
       responses:
-        "400":
-          description: Image specification is invalid
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "201":
           description: Created image
           content:
@@ -1393,6 +1387,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "400":
+          description: Image specification is invalid
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/identifier:
@@ -1457,20 +1457,14 @@ paths:
               $ref: '#/components/schemas/IdentifierSaveDto'
         required: true
       responses:
-        "201":
-          description: Created identifier
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/IdentifierDto'
-        "409":
-          description: Identifier for this resource already exists
+        "502":
+          description: Query information could not be retrieved
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "503":
-          description: DataCite system did not respond
+        "405":
+          description: Creating identifier not permitted
           content:
             application/json:
               schema:
@@ -1481,14 +1475,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "502":
-          description: Query information could not be retrieved
+        "406":
+          description: Creating identifier not allowed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "406":
-          description: Creating identifier not allowed
+        "400":
+          description: Identifier form contains invalid request data
           content:
             application/json:
               schema:
@@ -1499,18 +1493,24 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Identifier form contains invalid request data
+        "503":
+          description: DataCite system did not respond
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Creating identifier not permitted
+        "409":
+          description: Identifier for this resource already exists
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "201":
+          description: Created identifier
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IdentifierDto'
         "403":
           description: Insufficient access rights or authorities
           content:
@@ -1558,9 +1558,8 @@ paths:
               $ref: '#/components/schemas/DatabaseCreateDto'
         required: true
       responses:
-        "403":
-          description: Database create permission is missing or grant permissions
-            at broker service failed
+        "503":
+          description: Connection to the database failed
           content:
             application/json:
               schema:
@@ -1571,24 +1570,25 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "201":
-          description: Created a new database
+        "400":
+          description: Database create query is malformed or image is not supported
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/DatabaseBriefDto'
-        "503":
-          description: Connection to the database failed
+                $ref: '#/components/schemas/ApiErrorDto'
+        "403":
+          description: Database create permission is missing or grant permissions
+            at broker service failed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Database create query is malformed or image is not supported
+        "201":
+          description: Created a new database
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
+                $ref: '#/components/schemas/DatabaseBriefDto'
         "404":
           description: "Container, user or database could not be found"
           content:
@@ -1609,6 +1609,12 @@ paths:
         schema:
           type: string
       responses:
+        "404":
+          description: User not found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "200":
           description: Count databases
           content:
@@ -1617,12 +1623,6 @@ paths:
                 type: array
                 items:
                   $ref: '#/components/schemas/DatabaseDto'
-        "404":
-          description: User not found
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
   /api/database/{databaseId}/view:
     get:
       tags:
@@ -1672,50 +1672,50 @@ paths:
               $ref: '#/components/schemas/ViewCreateDto'
         required: true
       responses:
-        "423":
-          description: Create view resulted in an invalid query statement
+        "403":
+          description: Credentials missing
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "201":
-          description: Create view successfully
+        "404":
+          description: Database or user could not be found
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ViewBriefDto'
-        "403":
-          description: Credentials missing
+                $ref: '#/components/schemas/ApiErrorDto'
+        "405":
+          description: Create view is not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "401":
-          description: Credentials missing
+        "201":
+          description: Create view successfully
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
+                $ref: '#/components/schemas/ViewBriefDto'
         "503":
           description: Connection to the database failed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Database or user could not be found
+        "401":
+          description: Credentials missing
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Create view is not permitted
+        "400":
+          description: Create view query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Create view query is malformed
+        "423":
+          description: Create view resulted in an invalid query statement
           content:
             application/json:
               schema:
@@ -1777,12 +1777,12 @@ paths:
               $ref: '#/components/schemas/TableCreateDto'
         required: true
       responses:
-        "404":
-          description: "Database, container or user could not be found"
+        "201":
+          description: Created a new table
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
+                $ref: '#/components/schemas/TableBriefDto'
         "409":
           description: Create table conflicts with existing table name
           content:
@@ -1795,12 +1795,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "201":
-          description: Created a new table
+        "404":
+          description: "Database, container or user could not be found"
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/TableBriefDto'
+                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Create table not permitted
           content:
@@ -1837,20 +1837,20 @@ paths:
       responses:
         "202":
           description: Import table data successfully
-        "403":
-          description: Access to the database is forbidden
+        "422":
+          description: Could not import csv via sidecar
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Table or database could not be found
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "422":
-          description: Could not import csv via sidecar
+        "404":
+          description: Table or database could not be found
           content:
             application/json:
               schema:
@@ -1882,8 +1882,16 @@ paths:
         schema:
           type: boolean
       responses:
-        "404":
-          description: "Database, container or user could not be found"
+        "200":
+          description: List queries
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/QueryBriefDto'
+        "405":
+          description: Find all queries is not permitted
           content:
             application/json:
               schema:
@@ -1895,14 +1903,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "200":
-          description: List queries
+        "503":
+          description: Connection to the database failed
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/QueryBriefDto'
+                $ref: '#/components/schemas/ApiErrorDto'
         "501":
           description: Image is not supported
           content:
@@ -1915,14 +1921,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "503":
-          description: Connection to the database failed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "405":
-          description: Find all queries is not permitted
+        "404":
+          description: "Database, container or user could not be found"
           content:
             application/json:
               schema:
@@ -1973,14 +1973,8 @@ paths:
               $ref: '#/components/schemas/ExecuteStatementDto'
         required: true
       responses:
-        "400":
-          description: Image is not supported
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Could not store query in query store
+        "404":
+          description: "Database, query or user could not be found"
           content:
             application/json:
               schema:
@@ -1991,8 +1985,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/QueryResultDto'
-        "404":
-          description: "Database, query or user could not be found"
+        "400":
+          description: Image is not supported
           content:
             application/json:
               schema:
@@ -2009,6 +2003,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "409":
+          description: Could not store query in query store
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/container:
@@ -2045,6 +2045,12 @@ paths:
               $ref: '#/components/schemas/ContainerCreateRequestDto'
         required: true
       responses:
+        "404":
+          description: Container image or user could not be found
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "201":
           description: Created a new container
           content:
@@ -2057,12 +2063,6 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Container image or user could not be found
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/semantic/unit:
@@ -2104,28 +2104,28 @@ paths:
         schema:
           type: string
       responses:
-        "417":
-          description: Generated query or uri is malformed
+        "404":
+          description: Could not find ontology
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "200":
-          description: Found entities
+        "400":
+          description: Filter params are invalid
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/EntityDto'
-        "404":
-          description: Could not find ontology
+                $ref: '#/components/schemas/ApiErrorDto'
+        "200":
+          description: Found entities
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Filter params are invalid
+                type: array
+                items:
+                  $ref: '#/components/schemas/EntityDto'
+        "417":
+          description: Generated query or uri is malformed
           content:
             application/json:
               schema:
@@ -2158,24 +2158,12 @@ paths:
           type: integer
           format: int64
       responses:
-        "417":
-          description: Generated query is malformed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "404":
           description: Could not find the table
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "422":
-          description: Ontology does not have rdf or sparql endpoint
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "200":
           description: Suggested table semantics successfully
           content:
@@ -2184,6 +2172,18 @@ paths:
                 type: array
                 items:
                   $ref: '#/components/schemas/TableColumnEntityDto'
+        "417":
+          description: Generated query is malformed
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
+        "422":
+          description: Ontology does not have rdf or sparql endpoint
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/semantic/database/{databaseId}/table/{tableId}/column/{columnId}:
@@ -2212,8 +2212,8 @@ paths:
           type: integer
           format: int64
       responses:
-        "417":
-          description: Generated query is malformed
+        "404":
+          description: Could not find the table column
           content:
             application/json:
               schema:
@@ -2226,8 +2226,8 @@ paths:
                 type: array
                 items:
                   $ref: '#/components/schemas/TableColumnEntityDto'
-        "404":
-          description: Could not find the table column
+        "417":
+          description: Generated query is malformed
           content:
             application/json:
               schema:
@@ -2274,12 +2274,6 @@ paths:
         schema:
           type: string
       responses:
-        "409":
-          description: Exported resource was not found
-          content:
-            text/csv:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "200":
           description: Found identifier successfully
           content:
@@ -2292,10 +2286,11 @@ paths:
             text/bibliography; style=apa: {}
             text/bibliography; style=ieee: {}
             text/bibliography; style=bibtex: {}
-        "422":
-          description: Failed to retrieve from database sidecar
+        "400":
+          description: "Identifier could not be exported, the requested style is not\
+            \ known"
           content:
-            text/csv:
+            text/bibliography:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
         "503":
@@ -2304,11 +2299,16 @@ paths:
             text/csv:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: "Identifier could not be exported, the requested style is not\
-            \ known"
+        "409":
+          description: Exported resource was not found
           content:
-            text/bibliography:
+            text/csv:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
+        "422":
+          description: Failed to retrieve from database sidecar
+          content:
+            text/csv:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
         "410":
@@ -2436,32 +2436,26 @@ paths:
           type: string
           format: date-time
       responses:
-        "201":
-          description: Created identifier
+        "404":
+          description: "Table, database or user was not found"
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/IdentifierDto'
+                $ref: '#/components/schemas/ApiErrorDto'
         "503":
           description: Database connection could not be established
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Operation is not allowed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "422":
           description: Sidecar operation could not be completed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: "Table, database or user was not found"
+        "403":
+          description: Operation is not allowed
           content:
             application/json:
               schema:
@@ -2478,6 +2472,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "201":
+          description: Created identifier
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/IdentifierDto'
       security:
       - bearerAuth: []
   /api/database/{id}/access:
@@ -2500,14 +2500,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/DatabaseAccessDto'
-        "404":
-          description: Database not found
+        "403":
+          description: No access to this database
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: No access to this database
+        "404":
+          description: Database not found
           content:
             application/json:
               schema:
@@ -2573,14 +2573,14 @@ paths:
           type: integer
           format: int64
       responses:
-        "400":
-          description: Delete view query is malformed
+        "403":
+          description: Deletion not allowed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Deletion not allowed
+        "503":
+          description: Connection to the database failed
           content:
             application/json:
               schema:
@@ -2591,8 +2591,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "503":
-          description: Connection to the database failed
+        "404":
+          description: "Database, view or user could not be found"
           content:
             application/json:
               schema:
@@ -2603,8 +2603,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: "Database, view or user could not be found"
+        "400":
+          description: Delete view query is malformed
           content:
             application/json:
               schema:
@@ -2645,30 +2645,30 @@ paths:
           type: integer
           format: int64
       responses:
-        "404":
-          description: "Database, view, container or user could not be found"
+        "403":
+          description: View data not allowed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "200":
-          description: Find data successfully
+        "404":
+          description: "Database, view, container or user could not be found"
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/QueryResultDto'
+                $ref: '#/components/schemas/ApiErrorDto'
         "400":
           description: Pagination not in valid range or find data query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: View data not allowed
+        "200":
+          description: Find data successfully
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/ApiErrorDto'
+                $ref: '#/components/schemas/QueryResultDto'
       security:
       - bearerAuth: []
   /api/database/{databaseId}/view/{viewId}/data/count:
@@ -2697,20 +2697,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Count data not allowed
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Could not count query data
+        "400":
+          description: Pagination not in valid range or find data query is malformed
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "400":
-          description: Pagination not in valid range or find data query is malformed
+        "403":
+          description: Count data not allowed
           content:
             application/json:
               schema:
@@ -2722,6 +2716,12 @@ paths:
               schema:
                 type: integer
                 format: int64
+        "409":
+          description: Could not count query data
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
       security:
       - bearerAuth: []
   /api/database/{databaseId}/table/{tableId}:
@@ -2744,14 +2744,14 @@ paths:
           type: integer
           format: int64
       responses:
-        "404":
-          description: "Table, database or container could not be found"
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Access to the database is forbidden
+        "404":
+          description: "Table, database or container could not be found"
           content:
             application/json:
               schema:
@@ -2789,20 +2789,20 @@ paths:
           type: integer
           format: int64
       responses:
-        "404":
-          description: "Table, database or container could not be found"
+        "202":
+          description: Delete table successfully
+        "403":
+          description: Access to the database is forbidden
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "403":
-          description: Access to the database is forbidden
+        "404":
+          description: "Table, database or container could not be found"
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "202":
-          description: Delete table successfully
         "400":
           description: Delete table query resulted in an invalid query statement
           content:
@@ -2837,6 +2837,12 @@ paths:
           type: string
           format: date-time
       responses:
+        "422":
+          description: Could not import csv via sidecar
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Access to the database is forbidden
           content:
@@ -2855,12 +2861,6 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "422":
-          description: Could not import csv via sidecar
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
         "202":
           description: Get table data count successfully
           content:
@@ -2895,8 +2895,8 @@ paths:
         schema:
           type: string
       responses:
-        "400":
-          description: Image is not supported
+        "404":
+          description: Database or query could not be found
           content:
             application/json:
               schema:
@@ -2907,8 +2907,8 @@ paths:
             '*/*':
               schema:
                 type: object
-        "410":
-          description: Could not find in S3 storage
+        "400":
+          description: Image is not supported
           content:
             application/json:
               schema:
@@ -2925,14 +2925,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Export of query failed
+        "410":
+          description: Could not find in S3 storage
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Database or query could not be found
+        "409":
+          description: Export of query failed
           content:
             application/json:
               schema:
@@ -2984,14 +2984,8 @@ paths:
         schema:
           type: string
       responses:
-        "400":
-          description: Image is not supported
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/ApiErrorDto'
-        "409":
-          description: Could not store query in query store
+        "404":
+          description: Database or query could not be found
           content:
             application/json:
               schema:
@@ -3002,6 +2996,12 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/QueryResultDto'
+        "400":
+          description: Image is not supported
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiErrorDto'
         "403":
           description: Execute query not permitted
           content:
@@ -3014,8 +3014,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Database or query could not be found
+        "409":
+          description: Could not store query in query store
           content:
             application/json:
               schema:
@@ -3042,8 +3042,8 @@ paths:
           type: integer
           format: int64
       responses:
-        "400":
-          description: Image is not supported
+        "404":
+          description: Database or query could not be found
           content:
             application/json:
               schema:
@@ -3054,20 +3054,20 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/QueryResultDto'
-        "403":
-          description: Execute query not permitted
+        "400":
+          description: Image is not supported
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "417":
-          description: Could not parse columns
+        "403":
+          description: Execute query not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "404":
-          description: Database or query could not be found
+        "417":
+          description: Could not parse columns
           content:
             application/json:
               schema:
@@ -3128,18 +3128,18 @@ paths:
           type: integer
           format: int64
       responses:
-        "202":
-          description: Deleted container successfully
-          content:
-            '*/*':
-              schema:
-                type: object
         "404":
           description: Container not found
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Deleted container successfully
+          content:
+            '*/*':
+              schema:
+                type: object
       security:
       - bearerAuth: []
   /api/pid/{id}:
@@ -3162,18 +3162,18 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
-        "202":
-          description: Deleted identifier
-          content:
-            '*/*':
-              schema:
-                type: object
         "403":
           description: Deleting identifier not permitted
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/ApiErrorDto'
+        "202":
+          description: Deleted identifier
+          content:
+            '*/*':
+              schema:
+                type: object
       security:
       - bearerAuth: []
 components:
@@ -6642,14 +6642,14 @@ components:
           type: string
         resumptionToken:
           type: string
+        parametersString:
+          type: string
         fromDate:
           type: string
           format: date-time
         untilDate:
           type: string
           format: date-time
-        parametersString:
-          type: string
     BannerMessageDto:
       required:
       - id
diff --git a/.docs/.swagger/api-search.yaml b/.docs/.swagger/api-search.yaml
index 3baf8363629ae3098dec59d62ecf3cfc99ce7c6d..6c6822d5fd8d8f683217ae0701058a385f97f013 100644
--- a/.docs/.swagger/api-search.yaml
+++ b/.docs/.swagger/api-search.yaml
@@ -14,7 +14,174 @@ info:
   title: Database Repository Search Service API
   version: $TAG
 openapi: 3.0.0
-paths: {}
+paths:
+  /api/search:
+    post:
+      consumes:
+        - application/json
+      description: Performs a fuzzy search
+      operationId: post_fuzzy_search
+      parameters:
+        - in: body
+          name: body
+          required: true
+          schema:
+            properties:
+              search_term:
+                example: air quality
+                type: string
+            type: object
+      produces:
+        - application/json
+      responses:
+        '200':
+          content:
+            application/json:
+              schema:
+                properties:
+                  results:
+                    items:
+                      type: object
+                    type: array
+                type: object
+          description: OK, contains the elements formatted as an array of JSON arrays
+      summary: Performs a fuzzy search
+      tags:
+        - search-endpoint
+  /api/search/{type}:
+    post:
+      consumes:
+        - application/json
+      description: Performs a general search
+      operationId: post_general_search
+      parameters:
+        - description: The search type.
+          in: path
+          name: type
+          required: true
+          schema:
+            enum:
+              - database
+              - table
+              - view
+              - column
+              - user
+              - identifier
+              - concept
+              - unit
+            type: string
+        - in: body
+          name: body
+          required: true
+          schema:
+            properties:
+              field_value_pairs:
+                type: object
+              search_term:
+                example: air quality
+                type: string
+              t1:
+                example: 0
+                type: integer
+              t2:
+                example: 100
+                type: integer
+            type: object
+      produces:
+        - application/json
+      responses:
+        '200':
+          content:
+            application/json:
+              schema:
+                properties:
+                  results:
+                    items:
+                      type: object
+                    type: array
+                  type:
+                    description: Same as the requested type
+                    enum:
+                      - database
+                      - table
+                      - view
+                      - column
+                      - user
+                      - identifier
+                      - concept
+                      - unit
+                    type: string
+                type: object
+          description: OK, contains the elements formatted as an array of JSON arrays
+      summary: Performs a general search
+      tags:
+        - search-endpoint
+  /api/search/{type}/fields:
+    get:
+      operationId: get_fields
+      parameters:
+        - description: The search type.
+          in: path
+          name: type
+          required: true
+          schema:
+            enum:
+              - database
+              - table
+              - view
+              - column
+              - user
+              - identifier
+              - concept
+              - unit
+            type: string
+      responses:
+        '200':
+          content:
+            application/json:
+              schema:
+                properties:
+                  results:
+                    items:
+                      properties:
+                        attr_friendly_name:
+                          example: Name
+                          type: string
+                        attr_name:
+                          example: name
+                          type: string
+                        type:
+                          description: OpenSearch data types.
+                          example: string
+                          type: string
+                      type: object
+                    type: array
+                type: object
+          description: List of fields
+        '404':
+          description: Invalid type.
+      summary: Get searchable fields
+      tags:
+        - search-endpoint
+  /health:
+    get:
+      consumes:
+        - application/json
+      description: 'Return UP if the instance is ready to serve connections.
+
+        '
+      produces:
+        - application/json
+      responses:
+        '200':
+          description: OK, service is up and running
+          schema:
+            $ref: '#/definitions/Column'
+        '404':
+          description: Service is not yet ready
+      summary: Return a healthcheck
+      tags:
+        - actuator
 servers:
   - description: Generated server url
     url: http://localhost:4000
diff --git a/.docs/DEVELOPMENT.md b/.docs/DEVELOPMENT.md
index 30aa4270e1d1711c65facc9d9b6d88dcdf7973b5..db427a33f97c4b7afdd0a6448e465577f10e4e77 100644
--- a/.docs/DEVELOPMENT.md
+++ b/.docs/DEVELOPMENT.md
@@ -27,6 +27,13 @@ We practice test-driven development and require contributors to test their code
 
 ## Code Versioning
 
+### Branching Strategy
+
+<p align="center">
+<img src="../.gitlab/branching-strategy.png" alt="Branching strategy from the master-dev-feature branches and release branches." width="732" height="391" /><br/>
+<i><strong>Figure 1.</strong> Branching strategy of the source code development.</i>
+</p>
+
 ### CI/CD
 
 We get compute resources in-kind from [dataLAB](https://www.it.tuwien.ac.at/en/services/network-and-servers/datalab)
@@ -34,7 +41,7 @@ to run our pipeline:
 
 <p align="center">
 <img src="../.gitlab/gitlab-runner.png" alt="Gitlab runner configuration in the cluster" width="732" height="262" /><br/>
-<i><strong>Figure 1.</strong> Gitlab runner configuration in the cluster.</i>
+<i><strong>Figure 2.</strong> Gitlab runner configuration in the cluster.</i>
 </p>
 
 Minikube cluster with 6vCPU and 28GB RAM. The CI pipeline is configured as follows in the `config.toml`:
@@ -78,4 +85,8 @@ cluster.
 
 The full CI/CD pipeline Helm chart is documented in 
 the [`fda-deployment`](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-deployment/-/tree/master/charts/dbrepo-devops)
-repository.
\ No newline at end of file
+repository.
+
+## Documentation
+
+For consistency reasons across the documentation, the resolution needs to be 1280x800 (16:10 ratio)
\ No newline at end of file
diff --git a/.docs/deployment-docker-compose.md b/.docs/deployment-docker-compose.md
index 45c327de8535cc14e7bbe04b74c40026686a4b8e..4e78dad081fe0cd6fdf065afbdd1408c97b719a4 100644
--- a/.docs/deployment-docker-compose.md
+++ b/.docs/deployment-docker-compose.md
@@ -9,7 +9,7 @@ author: Martin Weise
 If you have [Docker](https://docs.docker.com/engine/install/) already installed on your system, you can install DBRepo with:
 
 ```shell
-curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/install.sh | bash
+curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/install.sh | bash
 ```
 
 ## Requirements
@@ -19,15 +19,18 @@ curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-service
 For this small, local, test deployment any modern hardware would suffice, we recommend a dedicated virtual machine with
 the following settings.
 
+- min. 8 vCPU cores
+- min. 16GB RAM memory
+- min. 200GB SSD storage
+- min. 100Mbit/s connection
+
+*Optional*: public IP-address if you want to secure the deployment with a (free) TLS-certificate from Let's Encrypt.
+
 !!! tip "Resource Consumption"
 
     Note that most of the vCPU and RAM resources will be needed for starting the infrastructure, this is because of
     Docker. During operation and especially idle times, the deployment will use significantly less resources.
 
-- 8 vCPU cores
-- 16GB RAM memory
-- 100GB SSD storage
-
 ### Software
 
 We only test the Docker Compose deployment with the 
@@ -93,18 +96,38 @@ core infrastructure and a single Docker container for all user-generated databas
 
     Install DBRepo with the default configuration from the Debian container:
 
-        curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/install.sh | bash
+        curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/install.sh | bash
 
 View the logs:
 
     docker compose logs -f
 
-You should now be able to view the front end at [http://localhost:80](http://localhost:80).
+You should now be able to view the front end at [http://localhost](http://localhost).
 
 Please be warned that the default configuration is not intended for public deployments. It is only intended to have a
 running system within minutes to play around within the system and explore features. It is strongly advised to change 
 the default `.env` environment variables.
 
+### Troubleshooting
+
+In case the deployment is unsuccessful, we have explanations on their origin and solutions to the most common errors:
+
+**Are you trying to mount a directory onto a file (or vice-versa)?**
+
+:   *Origin*:   Docker Compose does not find all files referenced in the `volumes` section of your `docker-compose.yml`
+                file.
+:   *Solution*: Ensure all mounted files in the `volumes` section of your `docker-compose.yml` exist and have correct
+                file permissions (`0644`) to be found in the filesystem. Note that paths containing directories may not
+                work when using Windows instead of the supported Linux.
+
+**The Docker images have been updated but my deployment is not receiving the updates**
+
+:   *Origin*:   Your local Docker image cache is not up-to-date and needs to fetch the remote changes.
+:   *Solution*: Update your local Docker image cache by executing `docker compose pull`, it automatically downloads
+                all Docker images that have updates. Then apply the new images with `docker compose up -d`.
+
+## Security
+
 !!! warning "Known security issues with the default configuration"
 
     The system is auto-configured for a small, local, test deployment and is *not* secure! You need to make modifications
@@ -142,42 +165,6 @@ the default `.env` environment variables.
       [simple guide](http://nginx.org/en/docs/http/configuring_https_servers.html) on how to install a SSL/TLS
       certificate on NGINX.
 
-## Upgrade Guide
-
-### 1.2 to 1.3
-
-In case you have a previous deployment from version 1.2, shut down the containers and back them up manually. You can do
-this by using the `busybox` image. Replace `deadbeef` with your container name or hash:
-
-```console
-export NAME=dbrepo-userdb-xyz
-docker run --rm --volumes-from $NAME -v /home/$USER/backup:/backup busybox tar pcvfz /backup/$NAME.tar.gz /var/lib/mysql
-```
-
-!!! danger "Wipe all traces of DBRepo from your system"
-
-    To erase all traces of DBRepo from your computer or virtual machine, the following commands delete all containers,
-    volumes and networks that are present, execute the following **dangerous** command. It will **wipe** all information
-    about DBRepo from your system (excluding the images).
-    
-    ```console
-    docker container stop $(docker container ls -aq -f name=^/dbrepo-.*) || true
-    docker container rm $(docker container ls -aq -f name=^/dbrepo-.*) || true
-    docker volume rm $(docker volume ls -q -f name=^dbrepo-.*) || true
-    docker network rm $(docker network ls -q -f name=^dbrepo-.*) || true
-    ```
-
-You can restore the volume *after* downloading the new 1.3 images and creating the infrastructure:
-
-```console
-export NAME=dbrepo-userdb-xyz
-export PORT=12345
-docker container create -h $NAME --name $NAME -p $PORT:3306 -e MARIADB_ROOT_PASSWORD=mariadb --network userdb -v /backup mariadb:10.5
-docker run --rm --volumes-from $NAME -v /home/$USER/backup/.tar.gz:/backup/$NAME.tar.gz busybox sh -c 'cd /backup && tar xvfz /backup/$NAME.tar.gz && cp -r /backup/var/lib/mysql/* /var/lib/mysql'
-```
-
-Future releases will be backwards compatible and will come with migration scripts.
-
 ## Limitations
 
 !!! info "Alternative Deployments"
diff --git a/.docs/images/architecture-data-db.svg b/.docs/images/architecture-data-db.svg
index 696f4ed091f46505bc905c613978c305d9352cf3..788750a77ea797fec5210bd3f3dbb8e20dae6ddd 100644
--- a/.docs/images/architecture-data-db.svg
+++ b/.docs/images/architecture-data-db.svg
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="426px" height="168px" viewBox="-0.5 -0.5 426 168" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="37" width="248" height="130" rx="3.9" ry="3.9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 246px; height: 1px; padding-top: 164px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: normal; overflow-wrap: normal;">shared filesystem<br />/tmp</div></div></div></foreignObject><text x="124" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle" font-style="italic">shared filesystem...</text></switch></g><path d="M 47.5 47.63 L 47.49 30.49 L 47.71 7" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 47.5 52.88 L 44 45.88 L 47.5 47.63 L 51 45.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 22px; margin-left: 48px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">jdbc</div></div></div></foreignObject><text x="48" y="25" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">jdbc</text></switch></g><path d="M 22.5 62.6 C 22.5 57.85 33.69 54 47.5 54 C 54.13 54 60.49 54.91 65.18 56.52 C 69.87 58.13 72.5 60.32 72.5 62.6 L 72.5 109.4 C 72.5 114.15 61.31 118 47.5 118 C 33.69 118 22.5 114.15 22.5 109.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 72.5 62.6 C 72.5 67.35 61.31 71.2 47.5 71.2 C 33.69 71.2 22.5 67.35 22.5 62.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="6.5" y="116" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 126px; margin-left: 5px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="49" y="130" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><path d="M 160 59.63 L 160 36.49 L 160.1 7" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 160 64.88 L 156.5 57.88 L 160 59.63 L 163.5 57.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 23px; margin-left: 160px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">http</div></div></div></foreignObject><text x="160" y="26" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">http</text></switch></g><path d="M 231.37 86 L 288.63 86" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 226.12 86 L 233.12 82.5 L 231.37 86 L 233.12 89.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 293.88 86 L 286.88 89.5 L 288.63 86 L 286.88 82.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 86px; margin-left: 260px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="260" y="89" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="95" y="66" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 86px; margin-left: 96px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data DB Sidecar</div></div></div></foreignObject><text x="160" y="90" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data DB Sidecar</text></switch></g><rect x="295" y="66" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 86px; margin-left: 296px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br />(minIO)</div></div></div></foreignObject><text x="360" y="90" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="426px" height="214px" viewBox="-0.5 -0.5 426 214"><defs/><g><rect x="0" y="37" width="248" height="130" rx="3.9" ry="3.9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 246px; height: 1px; padding-top: 164px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: normal; overflow-wrap: normal;">shared filesystem<br />/tmp</div></div></div></foreignObject><text x="124" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle" font-style="italic">shared filesystem...</text></switch></g><path d="M 47.5 47.63 L 47.5 31 L 47.71 7" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 47.5 52.88 L 44 45.88 L 47.5 47.63 L 51 45.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 22px; margin-left: 48px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">jdbc</div></div></div></foreignObject><text x="48" y="25" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">jdbc</text></switch></g><path d="M 22.5 62.6 C 22.5 57.85 33.69 54 47.5 54 C 54.13 54 60.49 54.91 65.18 56.52 C 69.87 58.13 72.5 60.32 72.5 62.6 L 72.5 109.4 C 72.5 114.15 61.31 118 47.5 118 C 33.69 118 22.5 114.15 22.5 109.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 72.5 62.6 C 72.5 67.35 61.31 71.2 47.5 71.2 C 33.69 71.2 22.5 67.35 22.5 62.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="6.5" y="116" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 126px; margin-left: 5px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="49" y="130" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><path d="M 160 59.63 L 160 37 L 160.1 7" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 160 64.88 L 156.5 57.88 L 160 59.63 L 163.5 57.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 23px; margin-left: 160px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">http</div></div></div></foreignObject><text x="160" y="26" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">http</text></switch></g><path d="M 231.37 86 L 288.63 86" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 226.12 86 L 233.12 82.5 L 231.37 86 L 233.12 89.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 293.88 86 L 286.88 89.5 L 288.63 86 L 286.88 82.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 86px; margin-left: 260px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="260" y="89" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="95" y="66" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 86px; margin-left: 96px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data DB Sidecar</div></div></div></foreignObject><text x="160" y="90" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data DB Sidecar</text></switch></g><rect x="295" y="66" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 86px; margin-left: 296px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br style="border-color: var(--border-color);" />(SeaweedFS)</div></div></div></foreignObject><text x="360" y="90" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g><rect x="242.5" y="177" width="30" height="16" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="280" y="177" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 185px; margin-left: 282px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">External images</div></div></div></foreignObject><text x="282" y="189" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">External images</text></switch></g><rect x="242.5" y="197" width="30" height="16" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="280" y="197" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 205px; margin-left: 282px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Maintained images</div></div></div></foreignObject><text x="282" y="209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Maintained images</text></switch></g><rect x="257.5" y="177" width="15" height="16" fill="#dae8fc" stroke="#000000" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/.docs/images/architecture-docker-compose.svg b/.docs/images/architecture-docker-compose.svg
index f4761f7ae450d88f225de62948d8b838ed3fcd08..08c9b5b80474c6b175c4965069a6d158ab5128ad 100644
--- a/.docs/images/architecture-docker-compose.svg
+++ b/.docs/images/architecture-docker-compose.svg
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="859px" height="669px" viewBox="-0.5 -0.5 859 669" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 367 90.37 L 367 108 L 366.63 125.63" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 367 85.12 L 370.5 92.12 L 367 90.37 L 363.5 92.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.52 130.88 L 363.17 123.81 L 366.63 125.63 L 370.17 123.96 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="367.5" cy="7.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 367.5 15 L 367.5 40 M 367.5 20 L 352.5 20 M 367.5 20 L 382.5 20 M 367.5 40 L 352.5 60 M 367.5 40 L 382.5 60" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 67px; margin-left: 368px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Researcher</div></div></div></foreignObject><text x="368" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Resea...</text></switch></g><path d="M 295.13 152 L 265.37 152" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 300.38 152 L 293.38 155.5 L 295.13 152 L 293.38 148.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 260.12 152 L 267.12 148.5 L 265.37 152 L 267.12 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 152px; margin-left: 281px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="281" y="155" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 334 172 L 334 200 L 194 200 L 194 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 226.88 L 190.5 219.88 L 194 221.63 L 197.5 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 399 172 L 399 200 L 544 200 L 544 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 226.88 L 540.5 219.88 L 544 221.63 L 547.5 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.5 178.37 L 366.5 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 366.5 173.12 L 370 180.12 L 366.5 178.37 L 363 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.5 226.88 L 363 219.88 L 366.5 221.63 L 370 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 200px; margin-left: 367px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="367" y="203" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 334 178.37 L 334 200 L 281 200 L 281 294 L 194 294 L 194 317.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 334 173.12 L 337.5 180.12 L 334 178.37 L 330.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 322.88 L 190.5 315.88 L 194 317.63 L 197.5 315.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 201px; margin-left: 310px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="310" y="203" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 437.87 152 L 472.63 152" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 432.62 152 L 439.62 148.5 L 437.87 152 L 439.62 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 477.88 152 L 470.88 155.5 L 472.63 152 L 470.88 148.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 152px; margin-left: 456px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="456" y="155" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">S3</text></switch></g><path d="M 399 178.37 L 399 200 L 457 200 L 457 394 L 544 394 L 544 413.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 399 173.12 L 402.5 180.12 L 399 178.37 L 395.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 544 418.88 L 540.5 411.88 L 544 413.63 L 547.5 411.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 200px; margin-left: 424px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="424" y="202" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><rect x="301.5" y="132" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 303px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Gateway Service</div></div></div></foreignObject><text x="367" y="156" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Gateway Service</text></switch></g><path d="M 431.5 248 L 445 248 L 445 203 C 448.9 203 448.9 197 445 197 L 445 197 L 445 189 L 544 189 L 544 178.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 173.12 L 547.5 180.12 L 544 178.37 L 540.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 473px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="473" y="193" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="301.5" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 303px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Analyse Service</div></div></div></foreignObject><text x="367" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Analyse Service</text></switch></g><path d="M 194 370.37 L 194 397.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 365.12 L 197.5 372.12 L 194 370.37 L 190.5 372.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 402.88 L 190.5 395.88 L 194 397.63 L 197.5 395.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="129" y="324" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 344px; margin-left: 130px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Authentication Service<br />(Keycloak)</div></div></div></foreignObject><text x="194" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Authentication Servic...</text></switch></g><path d="M 615.37 440 L 652.63 440" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 440 L 617.12 436.5 L 615.37 440 L 617.12 443.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 657.88 440 L 650.88 443.5 L 652.63 440 L 650.88 436.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 441px; margin-left: 634px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">JDBC</div></div></div></foreignObject><text x="634" y="443" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">JDBC</text></switch></g><path d="M 544 460 L 544 521.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 526.88 L 540.5 519.88 L 544 521.63 L 547.5 519.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="479" y="420" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 440px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Metadata Service</div></div></div></foreignObject><text x="544" y="444" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Metadata Service</text></switch></g><path d="M 259 248 L 278 248 C 278 244.1 284 244.1 284 248 L 284 248 L 289 248 L 289 394 L 367.5 394 L 367.5 413.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="1 1" pointer-events="stroke"/><path d="M 367.5 418.88 L 364 411.88 L 367.5 413.63 L 371 411.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 394px; margin-left: 329px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">Spring AMQP</div></div></div></foreignObject><text x="329" y="397" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">Spring AMQP</text></switch></g><rect x="129" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 130px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Broker Service<br />(RabbitMQ)</div></div></div></foreignObject><text x="194" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Broker Service...</text></switch></g><path d="M 615.37 248 L 652.63 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 248 L 617.12 244.5 L 615.37 248 L 617.12 251.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 657.88 248 L 650.88 251.5 L 652.63 248 L 650.88 244.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 248px; margin-left: 634px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="634" y="251" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><rect x="479" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Search Service</div></div></div></foreignObject><text x="544" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Search Service</text></switch></g><rect x="129" y="132" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 130px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UI</div></div></div></foreignObject><text x="194" y="156" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">UI</text></switch></g><path d="M 659 224.6 C 659 219.85 670.19 216 684 216 C 690.63 216 696.99 216.91 701.68 218.52 C 706.37 220.13 709 222.32 709 224.6 L 709 271.4 C 709 276.15 697.81 280 684 280 C 670.19 280 659 276.15 659 271.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 709 224.6 C 709 229.35 697.81 233.2 684 233.2 C 670.19 233.2 659 229.35 659 224.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 715.37 440 L 769 440" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 710.12 440 L 717.12 436.5 L 715.37 440 L 717.12 443.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 659 416.6 C 659 411.85 670.19 408 684 408 C 690.63 408 696.99 408.91 701.68 410.52 C 706.37 412.13 709 414.32 709 416.6 L 709 463.4 C 709 468.15 697.81 472 684 472 C 670.19 472 659 468.15 659 463.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 709 416.6 C 709 421.35 697.81 425.2 684 425.2 C 670.19 425.2 659 421.35 659 416.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="641.5" y="472" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 482px; margin-left: 640px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">metadata-db</div></div></div></foreignObject><text x="684" y="486" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">metadata-db</text></switch></g><path d="M 342.5 524.6 C 342.5 519.85 353.69 516 367.5 516 C 374.13 516 380.49 516.91 385.18 518.52 C 389.87 520.13 392.5 522.32 392.5 524.6 L 392.5 571.4 C 392.5 576.15 381.31 580 367.5 580 C 353.69 580 342.5 576.15 342.5 571.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 392.5 524.6 C 392.5 529.35 381.31 533.2 367.5 533.2 C 353.69 533.2 342.5 529.35 342.5 524.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="326.5" y="578" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 588px; margin-left: 325px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="369" y="592" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><path d="M 169 412.6 C 169 407.85 180.19 404 194 404 C 200.63 404 206.99 404.91 211.68 406.52 C 216.37 408.13 219 410.32 219 412.6 L 219 459.4 C 219 464.15 207.81 468 194 468 C 180.19 468 169 464.15 169 459.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 219 412.6 C 219 417.35 207.81 421.2 194 421.2 C 180.19 421.2 169 417.35 169 412.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="151.5" y="468" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 478px; margin-left: 150px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">auth-db</div></div></div></foreignObject><text x="194" y="482" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">auth-db</text></switch></g><path d="M 615.37 152 L 849 152 L 849 548 L 615.37 548" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 152 L 617.12 148.5 L 615.37 152 L 617.12 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 610.12 548 L 617.12 544.5 L 615.37 548 L 617.12 551.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 350px; margin-left: 849px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="849" y="353" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="479" y="132" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br />(minIO)</div></div></div></foreignObject><text x="544" y="156" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g><rect x="729.5" y="454" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 464px; margin-left: 728px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">metadata-db-data</div></div></div></foreignObject><text x="784" y="468" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">metadata-db-data</text></switch></g><ellipse cx="783.5" cy="440" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="729.5" y="262" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 272px; margin-left: 728px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">search-db-data</div></div></div></foreignObject><text x="784" y="276" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">search-db-data</text></switch></g><path d="M 769.5 248 L 715.37 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 710.12 248 L 717.12 244.5 L 715.37 248 L 717.12 251.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="783.5" cy="248" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="315" y="648" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 658px; margin-left: 313px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db-data</div></div></div></foreignObject><text x="369" y="662" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db-data</text></switch></g><path d="M 369 620 L 369 600 L 369 618 L 369 604.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 369 599.12 L 372.5 606.12 L 369 604.37 L 365.5 606.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="369" cy="634" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><path d="M 194 510 L 194 494.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 489.12 L 197.5 496.12 L 194 494.37 L 190.5 496.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="194" cy="524" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="140" y="538" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 548px; margin-left: 138px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">auth-db-data</div></div></div></foreignObject><text x="194" y="552" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">auth-db-data</text></switch></g><path d="M 367.5 460 L 367.5 509.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 367.5 514.88 L 364 507.88 L 367.5 509.63 L 371 507.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 488px; margin-left: 368px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">JDBC</div></div></div></foreignObject><text x="368" y="491" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">JDBC</text></switch></g><rect x="302.5" y="420" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 440px; margin-left: 304px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data Service</div></div></div></foreignObject><text x="368" y="444" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data Service</text></switch></g><path d="M 609 344 L 684 344 L 684 286.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 684 281.12 L 687.5 288.12 L 684 286.37 L 680.5 288.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 324px; margin-left: 686px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="686" y="326" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 609 344 L 684 344 L 684 401.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 684 406.88 L 680.5 399.88 L 684 401.63 L 687.5 399.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 374px; margin-left: 683px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">JDBC</div></div></div></foreignObject><text x="683" y="377" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">JDBC</text></switch></g><rect x="479" y="324" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 344px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Mirror Service</div></div></div></foreignObject><text x="544" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Mirror Service</text></switch></g><rect x="641.5" y="291" width="85" height="17" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 300px; margin-left: 640px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">search-db</div></div></div></foreignObject><text x="684" y="303" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">search-db</text></switch></g><path d="M 68 248 L 122.63 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 127.88 248 L 120.88 251.5 L 122.63 248 L 120.88 244.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="54" cy="248" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="0" y="262" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 272px; margin-left: -2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">broker-service-data</div></div></div></foreignObject><text x="54" y="276" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">broker-service-data</text></switch></g><path d="M 479 548 L 398.87 548" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 393.62 548 L 400.62 544.5 L 398.87 548 L 400.62 551.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="479" y="528" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 548px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data DB Sidecar</div></div></div></foreignObject><text x="544" y="552" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data DB Sidecar</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="838px" height="559px" viewBox="-0.5 -0.5 838 559"><defs/><g><path d="M 367.13 90.37 L 367.5 108.5 L 366.5 108.5 L 366.5 125.63" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 367.02 85.12 L 370.66 92.04 L 367.13 90.37 L 363.67 92.19 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.5 130.88 L 363 123.88 L 366.5 125.63 L 370 123.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="367.5" cy="7.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 367.5 15 L 367.5 40 M 367.5 20 L 352.5 20 M 367.5 20 L 382.5 20 M 367.5 40 L 352.5 60 M 367.5 40 L 382.5 60" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 67px; margin-left: 368px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Researcher</div></div></div></foreignObject><text x="368" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Resea...</text></switch></g><path d="M 295.13 152 L 265.37 152" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 300.38 152 L 293.38 155.5 L 295.13 152 L 293.38 148.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 260.12 152 L 267.12 148.5 L 265.37 152 L 267.12 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 152px; margin-left: 281px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="281" y="155" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 334 172 L 334 200 L 194 200 L 194 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 226.88 L 190.5 219.88 L 194 221.63 L 197.5 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 399 172 L 399 200 L 544 200 L 544 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 226.88 L 540.5 219.88 L 544 221.63 L 547.5 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.5 178.37 L 366.5 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 366.5 173.12 L 370 180.12 L 366.5 178.37 L 363 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 366.5 226.88 L 363 219.88 L 366.5 221.63 L 370 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 200px; margin-left: 367px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="367" y="203" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 334 178.37 L 334 200 L 281 200 L 281 294 L 194 294 L 194 317.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 334 173.12 L 337.5 180.12 L 334 178.37 L 330.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 322.88 L 190.5 315.88 L 194 317.63 L 197.5 315.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 201px; margin-left: 310px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="310" y="203" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><path d="M 437.87 152 L 472.63 152" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 432.62 152 L 439.62 148.5 L 437.87 152 L 439.62 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 477.88 152 L 470.88 155.5 L 472.63 152 L 470.88 148.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 152px; margin-left: 456px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="456" y="155" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">S3</text></switch></g><path d="M 399 178.37 L 399 200 L 457 200 L 457 294 L 544 294 L 544 317.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 399 173.12 L 402.5 180.12 L 399 178.37 L 395.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 544 322.88 L 540.5 315.88 L 544 317.63 L 547.5 315.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 200px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="411" y="202" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><rect x="301.5" y="132" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 303px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Gateway Service<br />(NGINX)</div></div></div></foreignObject><text x="367" y="156" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Gateway Service...</text></switch></g><path d="M 431.5 248 L 445 248 L 445 203 C 448.9 203 448.9 197 445 197 L 445 197 L 445 189 L 544 189 L 544 178.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 173.12 L 547.5 180.12 L 544 178.37 L 540.5 180.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 473px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="473" y="193" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="301.5" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 303px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Analyse Service</div></div></div></foreignObject><text x="367" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Analyse Service</text></switch></g><path d="M 194 370.37 L 194 397.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 365.12 L 197.5 372.12 L 194 370.37 L 190.5 372.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 194 402.88 L 190.5 395.88 L 194 397.63 L 197.5 395.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="129" y="324" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 344px; margin-left: 130px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Authentication Service<br />(Keycloak)</div></div></div></foreignObject><text x="194" y="348" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Authentication Servic...</text></switch></g><path d="M 615.37 344.12 L 634.5 344.5 L 652.63 344.13" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 344.02 L 617.19 340.66 L 615.37 344.12 L 617.05 347.66 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 657.88 344.02 L 650.96 347.66 L 652.63 344.13 L 650.81 340.67 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 345px; margin-left: 633px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">JDBC</div></div></div></foreignObject><text x="633" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">JDBC</text></switch></g><path d="M 544 364 L 544 410.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 544 415.88 L 540.5 408.88 L 544 410.63 L 547.5 408.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="479" y="324" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 344px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Metadata Service</div></div></div></foreignObject><text x="544" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Metadata Service</text></switch></g><path d="M 259 248 L 278 248 C 278 244.1 284 244.1 284 248 L 284 248 L 289 248 L 289 294 L 369 294 L 369 317.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="1 1" pointer-events="stroke"/><path d="M 369 322.88 L 365.5 315.88 L 369 317.63 L 372.5 315.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 294px; margin-left: 356px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">Spring AMQP</div></div></div></foreignObject><text x="356" y="297" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">Spring AMQP</text></switch></g><rect x="129" y="228" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 130px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Broker Service<br />(RabbitMQ)</div></div></div></foreignObject><text x="194" y="252" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Broker Service...</text></switch></g><path d="M 615.37 248 L 652.63 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 248 L 617.12 244.5 L 615.37 248 L 617.12 251.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 657.88 248 L 650.88 251.5 L 652.63 248 L 650.88 244.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 248px; margin-left: 634px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">HTTP</div></div></div></foreignObject><text x="634" y="251" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">HTTP</text></switch></g><rect x="479" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Search Service</div></div></div></foreignObject><text x="544" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Search Service</text></switch></g><rect x="129" y="132" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 130px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UI</div></div></div></foreignObject><text x="194" y="156" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">UI</text></switch></g><path d="M 659 224.6 C 659 219.85 670.19 216 684 216 C 690.63 216 696.99 216.91 701.68 218.52 C 706.37 220.13 709 222.32 709 224.6 L 709 271.4 C 709 276.15 697.81 280 684 280 C 670.19 280 659 276.15 659 271.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 709 224.6 C 709 229.35 697.81 233.2 684 233.2 C 670.19 233.2 659 229.35 659 224.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 715.37 344 L 739 344 L 769 344" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 710.12 344 L 717.12 340.5 L 715.37 344 L 717.12 347.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 659 320.6 C 659 315.85 670.19 312 684 312 C 690.63 312 696.99 312.91 701.68 314.52 C 706.37 316.13 709 318.32 709 320.6 L 709 367.4 C 709 372.15 697.81 376 684 376 C 670.19 376 659 372.15 659 367.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 709 320.6 C 709 325.35 697.81 329.2 684 329.2 C 670.19 329.2 659 325.35 659 320.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="641.5" y="376" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 386px; margin-left: 640px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">metadata-db</div></div></div></foreignObject><text x="684" y="390" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">metadata-db</text></switch></g><path d="M 342.5 413.6 C 342.5 408.85 353.69 405 367.5 405 C 374.13 405 380.49 405.91 385.18 407.52 C 389.87 409.13 392.5 411.32 392.5 413.6 L 392.5 460.4 C 392.5 465.15 381.31 469 367.5 469 C 353.69 469 342.5 465.15 342.5 460.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 392.5 413.6 C 392.5 418.35 381.31 422.2 367.5 422.2 C 353.69 422.2 342.5 418.35 342.5 413.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="326.5" y="467" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 477px; margin-left: 325px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="369" y="481" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><path d="M 169 412.6 C 169 407.85 180.19 404 194 404 C 200.63 404 206.99 404.91 211.68 406.52 C 216.37 408.13 219 410.32 219 412.6 L 219 459.4 C 219 464.15 207.81 468 194 468 C 180.19 468 169 464.15 169 459.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 219 412.6 C 219 417.35 207.81 421.2 194 421.2 C 180.19 421.2 169 417.35 169 412.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="151.5" y="468" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 478px; margin-left: 150px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">auth-db</div></div></div></foreignObject><text x="194" y="482" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">auth-db</text></switch></g><rect x="479" y="132" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 152px; margin-left: 480px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br />(SeaweedFS)</div></div></div></foreignObject><text x="544" y="156" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g><rect x="729.5" y="358" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 368px; margin-left: 728px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">metadata-db-data</div></div></div></foreignObject><text x="784" y="372" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">metadata-db-data</text></switch></g><ellipse cx="783.5" cy="344" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="729.5" y="262" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 272px; margin-left: 728px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">search-db-data</div></div></div></foreignObject><text x="784" y="276" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">search-db-data</text></switch></g><path d="M 769.5 248 L 715.37 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 710.12 248 L 717.12 244.5 L 715.37 248 L 717.12 251.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="783.5" cy="248" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="313.5" y="538" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 548px; margin-left: 312px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db-data</div></div></div></foreignObject><text x="368" y="552" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db-data</text></switch></g><path d="M 368 509 L 368 489 L 368 493.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 368 488.12 L 371.5 495.12 L 368 493.37 L 364.5 495.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="368" cy="523" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><path d="M 194 510 L 194 494.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 194 489.12 L 197.5 496.12 L 194 494.37 L 190.5 496.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="194" cy="524" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="140" y="538" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 548px; margin-left: 138px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">auth-db-data</div></div></div></foreignObject><text x="194" y="552" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">auth-db-data</text></switch></g><path d="M 369 364 L 369 384.5 L 367.5 384.5 L 367.5 398.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 367.5 403.88 L 364 396.88 L 367.5 398.63 L 371 396.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 385px; margin-left: 369px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">JDBC</div></div></div></foreignObject><text x="369" y="387" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="9px" text-anchor="middle">JDBC</text></switch></g><rect x="304" y="324" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 344px; margin-left: 305px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data Service</div></div></div></foreignObject><text x="369" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data Service</text></switch></g><rect x="641.5" y="291" width="85" height="17" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 300px; margin-left: 640px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">search-db</div></div></div></foreignObject><text x="684" y="303" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">search-db</text></switch></g><path d="M 68 248 L 98.5 248 L 122.63 248" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 127.88 248 L 120.88 251.5 L 122.63 248 L 120.88 244.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="54" cy="248" rx="14" ry="14" fill="#e1d5e7" stroke="#000000" pointer-events="all"/><rect x="0" y="262" width="108" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 112px; height: 1px; padding-top: 272px; margin-left: -2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">broker-service-data</div></div></div></foreignObject><text x="54" y="276" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">broker-service-data</text></switch></g><path d="M 479 437 L 398.87 437" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 393.62 437 L 400.62 433.5 L 398.87 437 L 400.62 440.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="479" y="417" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 437px; margin-left: 480px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data DB Sidecar</div></div></div></foreignObject><text x="544" y="441" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data DB Sidecar</text></switch></g><ellipse cx="281" cy="414.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 281 422 L 281 447 M 281 427 L 266 427 M 281 427 L 296 427 M 281 447 L 266 467 M 281 447 L 296 467" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 474px; margin-left: 281px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Researcher</div></div></div></foreignObject><text x="281" y="486" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Resea...</text></switch></g><path d="M 302.37 437 L 336.13 437" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 297.12 437 L 304.12 433.5 L 302.37 437 L 304.12 440.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 341.38 437 L 334.38 440.5 L 336.13 437 L 334.38 433.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 615.37 152 L 729 152 L 729 245 C 732.9 245 732.9 251 729 251 L 729 251 L 729 341 C 732.9 341 732.9 347 729 347 L 729 347 L 729 437 L 615.37 437" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 610.12 152 L 617.12 148.5 L 615.37 152 L 617.12 155.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 610.12 437 L 617.12 433.5 L 615.37 437 L 617.12 440.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 174px; margin-left: 729px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">S3</div></div></div></foreignObject><text x="729" y="177" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">S3</text></switch></g><rect x="649" y="514" width="30" height="16" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="686.5" y="514" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 522px; margin-left: 689px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">External images</div></div></div></foreignObject><text x="689" y="526" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">External images</text></switch></g><rect x="649" y="534" width="30" height="16" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="686.5" y="534" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 542px; margin-left: 689px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Maintained images</div></div></div></foreignObject><text x="689" y="546" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Maintained images</text></switch></g><rect x="664" y="514" width="15" height="16" fill="#dae8fc" stroke="#000000" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/.docs/images/architecture-ui.png b/.docs/images/architecture-ui.png
deleted file mode 100644
index ec4d56dcfdb5df8f414139df0e360a84fe6f84fa..0000000000000000000000000000000000000000
Binary files a/.docs/images/architecture-ui.png and /dev/null differ
diff --git a/.docs/images/architecture-ui.svg b/.docs/images/architecture-ui.svg
new file mode 100644
index 0000000000000000000000000000000000000000..10f75224a108321f594ee7ea688e00f06da4d5f2
--- /dev/null
+++ b/.docs/images/architecture-ui.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="551px" height="393px" viewBox="-0.5 -0.5 551 393"><defs/><g><rect x="0" y="212" width="320" height="136" rx="2.72" ry="2.72" fill="#ffffff" stroke="#000000" pointer-events="all"/><rect x="0" y="0" width="320" height="204" rx="4.08" ry="4.08" fill="#ffffff" stroke="#000000" pointer-events="all"/><rect x="170" y="10" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 30px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UI</div></div></div></foreignObject><text x="235" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">UI</text></switch></g><path d="M 235 73.63 L 235 56.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 235 78.88 L 231.5 71.88 L 235 73.63 L 238.5 71.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 51.12 L 238.5 58.12 L 235 56.37 L 231.5 58.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="170" y="80" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 100px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Vue.js</div></div></div></foreignObject><text x="235" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Vue.js</text></switch></g><path d="M 163.63 170 L 146.37 170" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 168.88 170 L 161.88 173.5 L 163.63 170 L 161.88 166.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 141.12 170 L 148.12 166.5 L 146.37 170 L 148.12 173.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 150 L 235 130 L 235 140 L 235 126.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 235 121.12 L 238.5 128.12 L 235 126.37 L 231.5 128.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 143.63 L 235 130 L 235 140 L 235 126.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 235 148.88 L 231.5 141.88 L 235 143.63 L 238.5 141.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 121.12 L 238.5 128.12 L 235 126.37 L 231.5 128.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 196.37 L 235 221.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 235 191.12 L 238.5 198.12 L 235 196.37 L 231.5 198.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 226.88 L 231.5 219.88 L 235 221.63 L 238.5 219.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="170" y="150" width="130" height="40" rx="6" ry="6" fill="#dae8fc" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 170px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Vuex<br />(state)</div></div></div></foreignObject><text x="235" y="174" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Vuex...</text></switch></g><path d="M 75 143.63 L 75 126.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 75 148.88 L 71.5 141.88 L 75 143.63 L 78.5 141.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 75 121.12 L 78.5 128.12 L 75 126.37 L 71.5 128.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="10" y="150" width="130" height="40" rx="6" ry="6" fill="#dae8fc" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 170px; margin-left: 11px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Vuex Persist<br />Plugin</div></div></div></foreignObject><text x="75" y="174" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Vuex Persist...</text></switch></g><path d="M 45 55 C 45 46.72 58.43 40 75 40 C 82.96 40 90.59 41.58 96.21 44.39 C 101.84 47.21 105 51.02 105 55 L 105 105 C 105 113.28 91.57 120 75 120 C 58.43 120 45 113.28 45 105 Z" fill="#dae8fc" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 105 55 C 105 63.28 91.57 70 75 70 C 58.43 70 45 63.28 45 55" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 93px; margin-left: 46px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Local Storage</div></div></div></foreignObject><text x="75" y="96" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Local Stor...</text></switch></g><path d="M 235 274.37 L 235 288 L 235 278 L 235 291.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 235 269.12 L 238.5 276.12 L 235 274.37 L 231.5 276.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 235 296.88 L 231.5 289.88 L 235 291.63 L 238.5 289.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="170" y="228" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 248px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Node.js<br />(api client)</div></div></div></foreignObject><text x="235" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Node.js...</text></switch></g><path d="M 306.37 318 L 413.63 318" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 301.12 318 L 308.12 314.5 L 306.37 318 L 308.12 321.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 418.88 318 L 411.88 321.5 L 413.63 318 L 411.88 314.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 485 298 L 485 196.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 485 191.12 L 488.5 198.12 L 485 196.37 L 481.5 198.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 249px; margin-left: 486px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">refresh_token</div></div></div></foreignObject><text x="486" y="252" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">refresh_token</text></switch></g><rect x="170" y="298" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 318px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Axios<br />(+request interceptor)</div></div></div></foreignObject><text x="235" y="322" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Axios...</text></switch></g><rect x="420" y="298" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 318px; margin-left: 421px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br style="border-color: var(--border-color);" />(SeaweedFS)</div></div></div></foreignObject><text x="485" y="322" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g><rect x="420" y="150" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 170px; margin-left: 421px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Authentication Service<br style="border-color: var(--border-color);" />(Keycloak)</div></div></div></foreignObject><text x="485" y="174" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Authentication Servic...</text></switch></g><rect x="6" y="7" width="60" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 17px; margin-left: 7px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">client-side</div></div></div></foreignObject><text x="36" y="21" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">client-side</text></switch></g><rect x="7" y="223" width="64" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 62px; height: 1px; padding-top: 233px; margin-left: 8px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">server-side<br />(Nuxt v2)</div></div></div></foreignObject><text x="39" y="237" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">server-sid...</text></switch></g><image x="70.5" y="6.5" width="20" height="20" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Google_Chrome_icon_%28February_2022%29.svg/2048px-Google_Chrome_icon_%28February_2022%29.svg.png" preserveAspectRatio="none"/><image x="95.5" y="6.1" width="20" height="20.8" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Firefox_logo%2C_2019.svg/1200px-Firefox_logo%2C_2019.svg.png" preserveAspectRatio="none"/><image x="74.5" y="222.66" width="28" height="20.84" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Nuxt_logo.svg/2560px-Nuxt_logo.svg.png" preserveAspectRatio="none"/><rect x="371" y="356" width="30" height="16" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="408.5" y="356" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 364px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">External images</div></div></div></foreignObject><text x="411" y="368" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">External images</text></switch></g><rect x="371" y="376" width="30" height="16" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="408.5" y="376" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 384px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Maintained images</div></div></div></foreignObject><text x="411" y="388" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Maintained images</text></switch></g><rect x="386" y="356" width="15" height="16" fill="#dae8fc" stroke="#000000" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/.docs/images/architecture.drawio b/.docs/images/architecture.drawio
index 025aef75dc8ed81db45c57998133f3ab8b316ee9..f493f476b2e933ed3c1fc5d78ef864dd629ae9b2 100644
--- a/.docs/images/architecture.drawio
+++ b/.docs/images/architecture.drawio
@@ -1,4 +1,4 @@
-<mxfile host="Electron" modified="2023-11-22T22:51:30.674Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.1.2 Chrome/106.0.5249.199 Electron/21.4.3 Safari/537.36" etag="rfDZiCzC6Lc0py7Ucjta" version="21.1.2" type="device" pages="7">
+<mxfile host="Electron" modified="2024-01-18T09:36:17.787Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.18 Chrome/120.0.6099.199 Electron/28.1.2 Safari/537.36" etag="VyIG_SLmjDzwPbzvCqrk" version="22.1.18" type="device" pages="7">
   <diagram id="mvBsv1rP8O80Qe3yGnn_" name="docker-compose">
     <mxGraphModel dx="1434" dy="822" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
       <root>
@@ -52,8 +52,8 @@
             <Array as="points">
               <mxPoint x="480" y="346" />
               <mxPoint x="538" y="346" />
-              <mxPoint x="538" y="540" />
-              <mxPoint x="625" y="540" />
+              <mxPoint x="538" y="440" />
+              <mxPoint x="625" y="440" />
             </Array>
           </mxGeometry>
         </mxCell>
@@ -62,7 +62,7 @@
             <mxPoint as="offset" />
           </mxGeometry>
         </mxCell>
-        <mxCell id="CohMdi7D_fRk0dSxzjYi-1" value="Gateway Service" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="CohMdi7D_fRk0dSxzjYi-1" value="Gateway Service&lt;br&gt;(NGINX)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;fontColor=#000000;strokeColor=#000000;" parent="1" vertex="1">
           <mxGeometry x="382.5" y="278" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="iy0HhJzZLXsiPmpU2ukH-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;jumpStyle=arc;" parent="1" source="13tBXMPt0xomx7MP2VuM-1" target="V1Wl26Vbpgnno5Lb-wtg-38" edge="1">
@@ -85,12 +85,12 @@
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;" parent="1" source="O_ELZSFbvl3Butg3bv_j-1" target="V1Wl26Vbpgnno5Lb-wtg-36" edge="1">
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
-        <mxCell id="O_ELZSFbvl3Butg3bv_j-1" value="Authentication Service&lt;br&gt;(Keycloak)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="O_ELZSFbvl3Butg3bv_j-1" value="Authentication Service&lt;br&gt;(Keycloak)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;fontColor=#000000;strokeColor=#000000;" parent="1" vertex="1">
           <mxGeometry x="210" y="470" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;" parent="1" target="V1Wl26Vbpgnno5Lb-wtg-32" edge="1">
           <mxGeometry relative="1" as="geometry">
-            <mxPoint x="689.9999999999998" y="586" as="sourcePoint" />
+            <mxPoint x="689.9999999999998" y="490" as="sourcePoint" />
           </mxGeometry>
         </mxCell>
         <mxCell id="YJRAzF6yD4Hh-bAvO1PB-16" value="JDBC" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=9;" parent="V1Wl26Vbpgnno5Lb-wtg-48" vertex="1" connectable="0">
@@ -102,19 +102,19 @@
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
         <mxCell id="hBEam5F8n4ZBPeoiEcWH-1" value="Metadata Service" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="560" y="566" width="130" height="40" as="geometry" />
+          <mxGeometry x="560" y="470" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="YJRAzF6yD4Hh-bAvO1PB-15" value="Spring AMQP" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;jumpStyle=arc;dashed=1;strokeWidth=1;dashPattern=1 1;fontSize=9;" parent="1" source="AQz-Vj6r_5Wor37pQVs6-1" target="YJRAzF6yD4Hh-bAvO1PB-1" edge="1">
           <mxGeometry x="0.54" relative="1" as="geometry">
             <Array as="points">
               <mxPoint x="370" y="394" />
-              <mxPoint x="370" y="540" />
-              <mxPoint x="449" y="540" />
+              <mxPoint x="370" y="440" />
+              <mxPoint x="450" y="440" />
             </Array>
             <mxPoint as="offset" />
           </mxGeometry>
         </mxCell>
-        <mxCell id="AQz-Vj6r_5Wor37pQVs6-1" value="Broker Service&lt;br&gt;(RabbitMQ)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="AQz-Vj6r_5Wor37pQVs6-1" value="Broker Service&lt;br&gt;(RabbitMQ)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;fontColor=#000000;strokeColor=#000000;" parent="1" vertex="1">
           <mxGeometry x="210" y="374" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-49" value="HTTP" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;fontSize=9;" parent="1" source="SsHHCok0RUWS7ODwTELy-4" target="V1Wl26Vbpgnno5Lb-wtg-26" edge="1">
@@ -131,20 +131,20 @@
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" parent="1" source="V1Wl26Vbpgnno5Lb-wtg-32" edge="1">
           <mxGeometry relative="1" as="geometry">
-            <mxPoint x="850" y="586" as="targetPoint" />
+            <mxPoint x="850" y="490" as="targetPoint" />
           </mxGeometry>
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-32" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="740" y="554" width="50" height="64" as="geometry" />
+          <mxGeometry x="740" y="458" width="50" height="64" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-33" value="metadata-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
-          <mxGeometry x="722.5" y="618" width="85" height="20" as="geometry" />
+          <mxGeometry x="722.5" y="522" width="85" height="20" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-34" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="423.5" y="662" width="50" height="64" as="geometry" />
+          <mxGeometry x="423.5" y="551" width="50" height="64" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-35" value="data-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
-          <mxGeometry x="407.5" y="724" width="85" height="20" as="geometry" />
+          <mxGeometry x="407.5" y="613" width="85" height="20" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-36" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
           <mxGeometry x="250" y="550" width="50" height="64" as="geometry" />
@@ -152,22 +152,14 @@
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-37" value="auth-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
           <mxGeometry x="232.5" y="614" width="85" height="20" as="geometry" />
         </mxCell>
-        <mxCell id="iy0HhJzZLXsiPmpU2ukH-8" value="S3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;" parent="1" source="V1Wl26Vbpgnno5Lb-wtg-38" target="iy0HhJzZLXsiPmpU2ukH-4" edge="1">
-          <mxGeometry relative="1" as="geometry">
-            <Array as="points">
-              <mxPoint x="930" y="298" />
-              <mxPoint x="930" y="694" />
-            </Array>
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="V1Wl26Vbpgnno5Lb-wtg-38" value="Storage Service&lt;br&gt;(minIO)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="V1Wl26Vbpgnno5Lb-wtg-38" value="Storage Service&lt;br&gt;(SeaweedFS)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;fontColor=#000000;strokeColor=#000000;" parent="1" vertex="1">
           <mxGeometry x="560" y="278" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-3" value="metadata-db-data" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
-          <mxGeometry x="810.5" y="600" width="108" height="20" as="geometry" />
+          <mxGeometry x="810.5" y="504" width="108" height="20" as="geometry" />
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-6" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#e1d5e7;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="850.5" y="572" width="28" height="28" as="geometry" />
+          <mxGeometry x="850.5" y="476" width="28" height="28" as="geometry" />
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-7" value="search-db-data" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
           <mxGeometry x="810.5" y="408" width="108" height="20" as="geometry" />
@@ -179,13 +171,15 @@
           <mxGeometry x="850.5" y="380" width="28" height="28" as="geometry" />
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-10" value="data-db-data" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
-          <mxGeometry x="396" y="794" width="108" height="20" as="geometry" />
+          <mxGeometry x="394.5" y="684" width="108" height="20" as="geometry" />
         </mxCell>
-        <mxCell id="A18w2Y2_AVEIFkgUy5Lv-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="A18w2Y2_AVEIFkgUy5Lv-11" target="V1Wl26Vbpgnno5Lb-wtg-35" edge="1">
-          <mxGeometry relative="1" as="geometry" />
+        <mxCell id="A18w2Y2_AVEIFkgUy5Lv-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="A18w2Y2_AVEIFkgUy5Lv-11" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <mxPoint x="449" y="633" as="targetPoint" />
+          </mxGeometry>
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-11" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#e1d5e7;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="436" y="766" width="28" height="28" as="geometry" />
+          <mxGeometry x="435" y="655" width="28" height="28" as="geometry" />
         </mxCell>
         <mxCell id="A18w2Y2_AVEIFkgUy5Lv-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="A18w2Y2_AVEIFkgUy5Lv-15" target="V1Wl26Vbpgnno5Lb-wtg-37" edge="1">
           <mxGeometry relative="1" as="geometry" />
@@ -202,27 +196,7 @@
           </mxGeometry>
         </mxCell>
         <mxCell id="YJRAzF6yD4Hh-bAvO1PB-1" value="Data Service" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="383.5" y="566" width="130" height="40" as="geometry" />
-        </mxCell>
-        <mxCell id="YJRAzF6yD4Hh-bAvO1PB-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="YJRAzF6yD4Hh-bAvO1PB-12" target="V1Wl26Vbpgnno5Lb-wtg-26" edge="1">
-          <mxGeometry relative="1" as="geometry">
-            <Array as="points">
-              <mxPoint x="765" y="490" />
-            </Array>
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="YJRAzF6yD4Hh-bAvO1PB-17" value="HTTP" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=9;" parent="YJRAzF6yD4Hh-bAvO1PB-13" vertex="1" connectable="0">
-          <mxGeometry x="0.3792" y="-1" relative="1" as="geometry">
-            <mxPoint as="offset" />
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="YJRAzF6yD4Hh-bAvO1PB-14" value="JDBC" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;fontSize=9;" parent="1" source="YJRAzF6yD4Hh-bAvO1PB-12" target="V1Wl26Vbpgnno5Lb-wtg-32" edge="1">
-          <mxGeometry x="0.5121" y="-1" relative="1" as="geometry">
-            <mxPoint as="offset" />
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="YJRAzF6yD4Hh-bAvO1PB-12" value="Mirror Service" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="560" y="470" width="130" height="40" as="geometry" />
+          <mxGeometry x="385" y="470" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="V1Wl26Vbpgnno5Lb-wtg-27" value="search-db" style="text;html=1;strokeColor=none;fillColor=default;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
           <mxGeometry x="722.5" y="437" width="85" height="17" as="geometry" />
@@ -242,20 +216,54 @@
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
         <mxCell id="iy0HhJzZLXsiPmpU2ukH-4" value="Data DB Sidecar" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="560" y="674" width="130" height="40" as="geometry" />
+          <mxGeometry x="560" y="563" width="130" height="40" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-2" value="Researcher" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
+          <mxGeometry x="347" y="553" width="30" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-3" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#000000;startArrow=classic;startFill=1;dashed=1;entryPerimeter=0;" parent="1" source="ZFea1dL5_0zV0EoV6Noq-2" target="V1Wl26Vbpgnno5Lb-wtg-34" edge="1">
+          <mxGeometry x="-0.028" relative="1" as="geometry">
+            <mxPoint x="458" y="240" as="sourcePoint" />
+            <mxPoint as="offset" />
+            <mxPoint x="458" y="288" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="iy0HhJzZLXsiPmpU2ukH-8" value="S3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;jumpStyle=arc;" parent="1" source="V1Wl26Vbpgnno5Lb-wtg-38" target="iy0HhJzZLXsiPmpU2ukH-4" edge="1">
+          <mxGeometry x="-0.4591" relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="810" y="298" />
+              <mxPoint x="810" y="583" />
+            </Array>
+            <mxPoint as="offset" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-4" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="1" vertex="1">
+          <mxGeometry x="730" y="660" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-5" value="External images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="767.5" y="660" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-6" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="730" y="680" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-7" value="Maintained images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="767.5" y="680" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="ZFea1dL5_0zV0EoV6Noq-8" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="745" y="660" width="15" height="16" as="geometry" />
         </mxCell>
       </root>
     </mxGraphModel>
   </diagram>
-  <diagram name="Frontend" id="GYXS_N4ymJ7hX3zLKvDC">
+  <diagram name="ui" id="GYXS_N4ymJ7hX3zLKvDC">
     <mxGraphModel dx="1434" dy="822" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="583" pageHeight="413" math="0" shadow="0">
       <root>
         <mxCell id="ihsuRJ9dWuDPEHVUeUyY-0" />
         <mxCell id="ihsuRJ9dWuDPEHVUeUyY-1" parent="ihsuRJ9dWuDPEHVUeUyY-0" />
-        <mxCell id="IRxpwOfG2jHF0YoYJLJK-1" value="" style="rounded=1;whiteSpace=wrap;html=1;arcSize=2;fillColor=#dae8fc;strokeColor=#000000;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="IRxpwOfG2jHF0YoYJLJK-1" value="" style="rounded=1;whiteSpace=wrap;html=1;arcSize=2;fillColor=#FFFFFF;strokeColor=#000000;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="17" y="232" width="320" height="136" as="geometry" />
         </mxCell>
-        <mxCell id="IRxpwOfG2jHF0YoYJLJK-0" value="" style="rounded=1;whiteSpace=wrap;html=1;arcSize=2;fillColor=#d5e8d4;strokeColor=#000000;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="IRxpwOfG2jHF0YoYJLJK-0" value="" style="rounded=1;whiteSpace=wrap;html=1;arcSize=2;fillColor=#FFFFFF;strokeColor=#000000;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="17" y="20" width="320" height="204" as="geometry" />
         </mxCell>
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-0" value="UI" style="rounded=1;whiteSpace=wrap;html=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
@@ -279,16 +287,16 @@
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startArrow=classic;startFill=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" source="kLNLoM7m2o6o68vp3Wb9-2" target="kLNLoM7m2o6o68vp3Wb9-10" edge="1">
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
-        <mxCell id="kLNLoM7m2o6o68vp3Wb9-2" value="Vuex&lt;br&gt;(state)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="kLNLoM7m2o6o68vp3Wb9-2" value="Vuex&lt;br&gt;(state)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="187" y="170" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" source="kLNLoM7m2o6o68vp3Wb9-3" target="kLNLoM7m2o6o68vp3Wb9-4" edge="1">
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
-        <mxCell id="kLNLoM7m2o6o68vp3Wb9-3" value="Vuex Persist&lt;br&gt;Plugin" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="kLNLoM7m2o6o68vp3Wb9-3" value="Vuex Persist&lt;br&gt;Plugin" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="27" y="170" width="130" height="40" as="geometry" />
         </mxCell>
-        <mxCell id="kLNLoM7m2o6o68vp3Wb9-4" value="Local Storage" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#FFF2CC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="kLNLoM7m2o6o68vp3Wb9-4" value="Local Storage" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#DAE8FC;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="62" y="60" width="60" height="80" as="geometry" />
         </mxCell>
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startArrow=classic;startFill=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" source="kLNLoM7m2o6o68vp3Wb9-10" target="kLNLoM7m2o6o68vp3Wb9-12" edge="1">
@@ -305,22 +313,22 @@
         </mxCell>
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-20" value="refresh_token" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="kLNLoM7m2o6o68vp3Wb9-19" vertex="1" connectable="0">
           <mxGeometry x="0.5604" y="1" relative="1" as="geometry">
-            <mxPoint x="-21" y="34" as="offset" />
+            <mxPoint x="1" y="34" as="offset" />
           </mxGeometry>
         </mxCell>
         <mxCell id="kLNLoM7m2o6o68vp3Wb9-12" value="Axios&lt;br&gt;(+request interceptor)" style="rounded=1;whiteSpace=wrap;html=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="187" y="318" width="130" height="40" as="geometry" />
         </mxCell>
-        <mxCell id="kLNLoM7m2o6o68vp3Wb9-13" value="Gateway Service" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#B3B3B3;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="kLNLoM7m2o6o68vp3Wb9-13" value="Storage Service&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;(SeaweedFS)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="437" y="318" width="130" height="40" as="geometry" />
         </mxCell>
-        <mxCell id="kLNLoM7m2o6o68vp3Wb9-18" value="Authentication Service" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#B3B3B3;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="kLNLoM7m2o6o68vp3Wb9-18" value="Authentication Service&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;(Keycloak)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="437" y="170" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="4DtipyiVSSVc0IyAwunU-1" value="client-side" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="23" y="27" width="60" height="20" as="geometry" />
         </mxCell>
-        <mxCell id="4DtipyiVSSVc0IyAwunU-2" value="server-side&lt;br&gt;(nuxt.js)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+        <mxCell id="4DtipyiVSSVc0IyAwunU-2" value="server-side&lt;br&gt;(Nuxt v2)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="24" y="243" width="64" height="20" as="geometry" />
         </mxCell>
         <mxCell id="4DtipyiVSSVc0IyAwunU-4" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Google_Chrome_icon_%28February_2022%29.svg/2048px-Google_Chrome_icon_%28February_2022%29.svg.png;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
@@ -332,6 +340,21 @@
         <mxCell id="4DtipyiVSSVc0IyAwunU-7" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Nuxt_logo.svg/2560px-Nuxt_logo.svg.png;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
           <mxGeometry x="92" y="243.15999999999997" width="28" height="20.84" as="geometry" />
         </mxCell>
+        <mxCell id="GqgzYKxcxpW_CC4_t2HJ-0" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+          <mxGeometry x="388" y="376" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="GqgzYKxcxpW_CC4_t2HJ-1" value="External images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+          <mxGeometry x="425.5" y="376" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="GqgzYKxcxpW_CC4_t2HJ-2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+          <mxGeometry x="388" y="396" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="GqgzYKxcxpW_CC4_t2HJ-3" value="Maintained images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+          <mxGeometry x="425.5" y="396" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="GqgzYKxcxpW_CC4_t2HJ-4" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#000000;" parent="ihsuRJ9dWuDPEHVUeUyY-1" vertex="1">
+          <mxGeometry x="403" y="376" width="15" height="16" as="geometry" />
+        </mxCell>
       </root>
     </mxGraphModel>
   </diagram>
@@ -559,7 +582,7 @@
     </mxGraphModel>
   </diagram>
   <diagram id="e2fuorb2m_XjboQ7R7_y" name="Data Ingest">
-    <mxGraphModel dx="1434" dy="822" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
+    <mxGraphModel dx="1147" dy="658" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
       <root>
         <mxCell id="0" />
         <mxCell id="1" parent="0" />
@@ -577,13 +600,14 @@
             <mxPoint as="offset" />
           </mxGeometry>
         </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=27.5;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-3" target="0VJCIkSjTVNNat6pGbHc-13" edge="1">
+        <mxCell id="0VJCIkSjTVNNat6pGbHc-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=27.5;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-3" edge="1">
           <mxGeometry relative="1" as="geometry">
             <Array as="points">
               <mxPoint x="480" y="340" />
               <mxPoint x="530" y="340" />
               <mxPoint x="530" y="428" />
             </Array>
+            <mxPoint x="575" y="427.5" as="targetPoint" />
           </mxGeometry>
         </mxCell>
         <mxCell id="0VJCIkSjTVNNat6pGbHc-36" value="3306/tcp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="0VJCIkSjTVNNat6pGbHc-35" vertex="1" connectable="0">
@@ -618,7 +642,7 @@
             <mxPoint as="offset" />
           </mxGeometry>
         </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-3" value="Gateway Service" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="0VJCIkSjTVNNat6pGbHc-3" value="Gateway Service&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;(NGINX)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="1" vertex="1">
           <mxGeometry x="382.5" y="278" width="130" height="40" as="geometry" />
         </mxCell>
         <mxCell id="0VJCIkSjTVNNat6pGbHc-7" value="&lt;b&gt;JDBC&lt;/b&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
@@ -644,11 +668,10 @@
             </Array>
           </mxGeometry>
         </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-13" value="data-db" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#fff2cc;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="575" y="400" width="60" height="80" as="geometry" />
-        </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-26" target="0VJCIkSjTVNNat6pGbHc-13" edge="1">
-          <mxGeometry relative="1" as="geometry" />
+        <mxCell id="0VJCIkSjTVNNat6pGbHc-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-26" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <mxPoint x="575" y="440" as="targetPoint" />
+          </mxGeometry>
         </mxCell>
         <mxCell id="0VJCIkSjTVNNat6pGbHc-38" value="3306/tcp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="0VJCIkSjTVNNat6pGbHc-37" vertex="1" connectable="0">
           <mxGeometry x="-0.1716" y="1" relative="1" as="geometry">
@@ -661,15 +684,16 @@
         <mxCell id="0VJCIkSjTVNNat6pGbHc-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-29" target="0VJCIkSjTVNNat6pGbHc-26" edge="1">
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-29" value="Broker Service&lt;br&gt;(RabbitMQ)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="0VJCIkSjTVNNat6pGbHc-29" value="Broker Service&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;(RabbitMQ)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="1" vertex="1">
           <mxGeometry x="399.5" y="360" width="96" height="40" as="geometry" />
         </mxCell>
-        <mxCell id="0VJCIkSjTVNNat6pGbHc-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=52.5;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-33" target="0VJCIkSjTVNNat6pGbHc-13" edge="1">
+        <mxCell id="0VJCIkSjTVNNat6pGbHc-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=52.5;entryPerimeter=0;" parent="1" source="0VJCIkSjTVNNat6pGbHc-33" edge="1">
           <mxGeometry relative="1" as="geometry">
             <Array as="points">
               <mxPoint x="530" y="500" />
               <mxPoint x="530" y="453" />
             </Array>
+            <mxPoint x="575" y="452.5" as="targetPoint" />
           </mxGeometry>
         </mxCell>
         <mxCell id="0VJCIkSjTVNNat6pGbHc-40" value="3306/tcp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="0VJCIkSjTVNNat6pGbHc-39" vertex="1" connectable="0">
@@ -683,9 +707,83 @@
         <mxCell id="SPLHNWc1rHttcZ-O3PPf-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="JkB3rZmVi6YrdEwAjtGV-5" target="0VJCIkSjTVNNat6pGbHc-33" edge="1">
           <mxGeometry relative="1" as="geometry" />
         </mxCell>
-        <mxCell id="JkB3rZmVi6YrdEwAjtGV-5" value="Storage Service&lt;br&gt;(minIO)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+        <mxCell id="JkB3rZmVi6YrdEwAjtGV-5" value="Storage Service&lt;br&gt;(SeaweedFS)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="1" vertex="1">
           <mxGeometry x="237" y="394" width="96" height="40" as="geometry" />
         </mxCell>
+        <mxCell id="yvNGLmbJRMNvVS071MuP-1" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" vertex="1" parent="1">
+          <mxGeometry x="575" y="408" width="50" height="64" as="geometry" />
+        </mxCell>
+        <mxCell id="yvNGLmbJRMNvVS071MuP-2" value="data-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" vertex="1" parent="1">
+          <mxGeometry x="559" y="470" width="85" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="jJosZR_OhRTGx9p3jnjP-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" vertex="1" parent="1">
+          <mxGeometry x="447.5" y="540" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="jJosZR_OhRTGx9p3jnjP-2" value="External images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="485" y="540" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="jJosZR_OhRTGx9p3jnjP-3" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="447.5" y="560" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="jJosZR_OhRTGx9p3jnjP-4" value="Maintained images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="485" y="560" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="jJosZR_OhRTGx9p3jnjP-5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#000000;" vertex="1" parent="1">
+          <mxGeometry x="462.5" y="540" width="15" height="16" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="n3Gsc6DDUkQ8nNTTz0wk" name="data-db">
+    <mxGraphModel dx="1434" dy="172" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1019" pageHeight="650" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-9" value="shared filesystem&lt;br&gt;/tmp" style="rounded=1;whiteSpace=wrap;html=1;arcSize=3;verticalAlign=bottom;fontStyle=2" parent="1" vertex="1">
+          <mxGeometry x="425" y="840" width="248" height="130" as="geometry" />
+        </mxCell>
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-11" value="jdbc" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;exitPerimeter=0;endArrow=none;endFill=0;startArrow=classic;startFill=1;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-1" edge="1">
+          <mxGeometry x="0.3769" relative="1" as="geometry">
+            <mxPoint x="472.71428571428555" y="810" as="targetPoint" />
+            <mxPoint as="offset" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-1" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="447.5" y="857" width="50" height="64" as="geometry" />
+        </mxCell>
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-2" value="data-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
+          <mxGeometry x="431.5" y="919" width="85" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-12" value="http" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-7" edge="1">
+          <mxGeometry x="0.4743" relative="1" as="geometry">
+            <mxPoint x="585.0952380952381" y="810" as="targetPoint" />
+            <mxPoint as="offset" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="m0IQrUpga-DAo2afT193-3" value="S3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-7" target="m0IQrUpga-DAo2afT193-1" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-7" value="Data DB Sidecar" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="520" y="869" width="130" height="40" as="geometry" />
+        </mxCell>
+        <mxCell id="m0IQrUpga-DAo2afT193-1" value="Storage Service&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;(SeaweedFS)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" parent="1" vertex="1">
+          <mxGeometry x="720" y="869" width="130" height="40" as="geometry" />
+        </mxCell>
+        <mxCell id="WQwfQuj7Yb_D7RAfNHcl-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" vertex="1" parent="1">
+          <mxGeometry x="667.5" y="980" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="WQwfQuj7Yb_D7RAfNHcl-2" value="External images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="705" y="980" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="WQwfQuj7Yb_D7RAfNHcl-3" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="667.5" y="1000" width="30" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="WQwfQuj7Yb_D7RAfNHcl-4" value="Maintained images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="705" y="1000" width="140" height="16" as="geometry" />
+        </mxCell>
+        <mxCell id="WQwfQuj7Yb_D7RAfNHcl-5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#000000;" vertex="1" parent="1">
+          <mxGeometry x="682.5" y="980" width="15" height="16" as="geometry" />
+        </mxCell>
       </root>
     </mxGraphModel>
   </diagram>
@@ -797,42 +895,4 @@
       </root>
     </mxGraphModel>
   </diagram>
-  <diagram id="n3Gsc6DDUkQ8nNTTz0wk" name="data-db">
-    <mxGraphModel dx="1434" dy="172" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1019" pageHeight="650" math="0" shadow="0">
-      <root>
-        <mxCell id="0" />
-        <mxCell id="1" parent="0" />
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-9" value="shared filesystem&lt;br&gt;/tmp" style="rounded=1;whiteSpace=wrap;html=1;arcSize=3;verticalAlign=bottom;fontStyle=2" parent="1" vertex="1">
-          <mxGeometry x="425" y="840" width="248" height="130" as="geometry" />
-        </mxCell>
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-11" value="jdbc" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;exitPerimeter=0;endArrow=none;endFill=0;startArrow=classic;startFill=1;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-1" edge="1">
-          <mxGeometry x="0.3769" relative="1" as="geometry">
-            <mxPoint x="472.71428571428555" y="810" as="targetPoint" />
-            <mxPoint as="offset" />
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-1" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=8.600000000000023;fillColor=#dae8fc;strokeColor=#000000;" parent="1" vertex="1">
-          <mxGeometry x="447.5" y="857" width="50" height="64" as="geometry" />
-        </mxCell>
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-2" value="data-db" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;spacing=-1;" parent="1" vertex="1">
-          <mxGeometry x="431.5" y="919" width="85" height="20" as="geometry" />
-        </mxCell>
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-12" value="http" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-7" edge="1">
-          <mxGeometry x="0.4743" relative="1" as="geometry">
-            <mxPoint x="585.0952380952381" y="810" as="targetPoint" />
-            <mxPoint as="offset" />
-          </mxGeometry>
-        </mxCell>
-        <mxCell id="m0IQrUpga-DAo2afT193-3" value="S3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;" parent="1" source="S8wz9ZtwZs3Sd4maCRdY-7" target="m0IQrUpga-DAo2afT193-1" edge="1">
-          <mxGeometry relative="1" as="geometry" />
-        </mxCell>
-        <mxCell id="S8wz9ZtwZs3Sd4maCRdY-7" value="Data DB Sidecar" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="520" y="869" width="130" height="40" as="geometry" />
-        </mxCell>
-        <mxCell id="m0IQrUpga-DAo2afT193-1" value="Storage Service&lt;br&gt;(minIO)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
-          <mxGeometry x="720" y="869" width="130" height="40" as="geometry" />
-        </mxCell>
-      </root>
-    </mxGraphModel>
-  </diagram>
 </mxfile>
diff --git a/.docs/images/data-ingest.svg b/.docs/images/data-ingest.svg
index f399f752d9df00ffdf1b0835c625580cf3c543b3..7d2d1c383092ca7be8be502a74d8f1df3c09f920 100644
--- a/.docs/images/data-ingest.svg
+++ b/.docs/images/data-ingest.svg
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="447px" height="384px" viewBox="-0.5 -0.5 447 384" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 259 83 L 259 112 L 258.61 134.63" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 258.52 139.88 L 255.14 132.82 L 258.61 134.63 L 262.14 132.94 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 111px; margin-left: 259px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">5672/tcp</div></div></div></foreignObject><text x="259" y="114" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">5672/tcp</text></switch></g><ellipse cx="258.5" cy="7.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 258.5 15 L 258.5 40 M 258.5 20 L 243.5 20 M 258.5 20 L 273.5 20 M 258.5 40 L 243.5 60 M 258.5 40 L 273.5 60" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 67px; margin-left: 259px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>AMQP</b></div></div></div></foreignObject><text x="259" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">AMQP</text></switch></g><path d="M 258.5 181 L 258.5 216.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 258.5 221.88 L 255 214.88 L 258.5 216.63 L 262 214.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 198px; margin-left: 258px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">5672/tcp</div></div></div></foreignObject><text x="258" y="201" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">5672/tcp</text></switch></g><path d="M 291 181 L 291 203 L 341 203 L 341 290.5 L 379.63 290.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 384.88 290.5 L 377.88 294 L 379.63 290.5 L 377.88 287 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 256px; margin-left: 341px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="341" y="259" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><path d="M 226 181 L 226 203 L 175 203 L 175 336.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 175 341.88 L 171.5 334.88 L 175 336.63 L 178.5 334.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 251px; margin-left: 175px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">80/tcp</div></div></div></foreignObject><text x="175" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">80/tcp</text></switch></g><rect x="193.5" y="141" width="130" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 161px; margin-left: 195px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Gateway Service</div></div></div></foreignObject><text x="259" y="165" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Gateway Service</text></switch></g><ellipse cx="410" cy="40.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 410 48 L 410 73 M 410 53 L 395 53 M 410 53 L 425 53 M 410 73 L 395 93 M 410 73 L 425 93" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 100px; margin-left: 410px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>JDBC</b></div></div></div></foreignObject><text x="410" y="112" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">JDBC</text></switch></g><path d="M 330.37 163 L 411 163 L 411 119.37" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 325.12 163 L 332.12 159.5 L 330.37 163 L 332.12 166.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 411 114.12 L 414.5 121.12 L 411 119.37 L 407.5 121.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 163px; margin-left: 371px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="371" y="166" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><path d="M 91 63 L 28 63 L 28 277 L 48 277" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 44 281 L 36 273 M 44 273 L 36 281" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 149px; margin-left: 28px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><font color="#b3b3b3">(not used in<br />the default<br />config)</font></div></div></div></foreignObject><text x="28" y="152" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">(not used in...</text></switch></g><ellipse cx="106" cy="40.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 106 48 L 106 73 M 106 53 L 91 53 M 106 53 L 121 53 M 106 73 L 91 93 M 106 73 L 121 93" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 100px; margin-left: 106px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>API</b></div></div></div></foreignObject><text x="106" y="112" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">API</text></switch></g><path d="M 106 119.37 L 106 163 L 187.63 163" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 106 114.12 L 109.5 121.12 L 106 119.37 L 102.5 121.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 192.88 163 L 185.88 166.5 L 187.63 163 L 185.88 159.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 163px; margin-left: 141px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">80/tcp</div></div></div></foreignObject><text x="141" y="166" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">80/tcp</text></switch></g><path d="M 386 278 C 386 269.72 399.43 263 416 263 C 423.96 263 431.59 264.58 437.21 267.39 C 442.84 270.21 446 274.02 446 278 L 446 328 C 446 336.28 432.57 343 416 343 C 399.43 343 386 336.28 386 328 Z" fill="#fff2cc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 446 278 C 446 286.28 432.57 293 416 293 C 399.43 293 386 286.28 386 278" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 316px; margin-left: 387px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="416" y="319" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><path d="M 306.5 303 L 379.63 303" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 384.88 303 L 377.88 306.5 L 379.63 303 L 377.88 299.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 303px; margin-left: 340px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="340" y="306" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><rect x="210.5" y="283" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 303px; margin-left: 212px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data Service<br />(Spring AMQP)</div></div></div></foreignObject><text x="259" y="307" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data Service...</text></switch></g><path d="M 258.5 263 L 258.5 276.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 258.5 281.88 L 255 274.88 L 258.5 276.63 L 262 274.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="210.5" y="223" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 243px; margin-left: 212px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Broker Service<br />(RabbitMQ)</div></div></div></foreignObject><text x="259" y="247" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Broker Service...</text></switch></g><path d="M 223 363 L 341 363 L 341 315.5 L 379.63 315.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 384.88 315.5 L 377.88 319 L 379.63 315.5 L 377.88 312 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 364px; margin-left: 292px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="292" y="367" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><rect x="127" y="343" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 363px; margin-left: 128px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Metadata Service<br />(Spring AMQP)</div></div></div></foreignObject><text x="175" y="367" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Metadata Service...</text></switch></g><path d="M 96 250.63 L 96 193 L 207.4 193 L 207.41 180.64" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 96 255.88 L 92.5 248.88 L 96 250.63 L 99.5 248.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 216px; margin-left: 99px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">80/tcp</div></div></div></foreignObject><text x="99" y="219" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">80/tcp</text></switch></g><path d="M 96 297 L 96 363 L 120.63 363" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 125.88 363 L 118.88 366.5 L 120.63 363 L 118.88 359.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="48" y="257" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 277px; margin-left: 49px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Upload Service<br />(TUS)</div></div></div></foreignObject><text x="96" y="281" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Upload Service...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="408px" height="440px" viewBox="-0.5 -0.5 408 440"><defs/><g><path d="M 211 83 L 211.52 112.52 L 210.48 112.52 L 210.5 134.63" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 210.5 139.88 L 206.99 132.88 L 210.5 134.63 L 213.99 132.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 112px; margin-left: 212px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">5672/tcp</div></div></div></foreignObject><text x="212" y="115" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">5672/tcp</text></switch></g><ellipse cx="210.5" cy="7.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 210.5 15 L 210.5 40 M 210.5 20 L 195.5 20 M 210.5 20 L 225.5 20 M 210.5 40 L 195.5 60 M 210.5 40 L 225.5 60" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 67px; margin-left: 211px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>AMQP</b></div></div></div></foreignObject><text x="211" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">AMQP</text></switch></g><path d="M 210.5 181 L 210.5 216.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 210.5 221.88 L 207 214.88 L 210.5 216.63 L 214 214.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 198px; margin-left: 210px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">5672/tcp</div></div></div></foreignObject><text x="210" y="201" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">5672/tcp</text></switch></g><path d="M 243 181 L 243.04 203 L 293.04 203 L 293.04 290.52 L 331.63 290.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 336.88 290.5 L 329.88 294 L 331.63 290.5 L 329.88 287 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 255px; margin-left: 292px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="292" y="259" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><path d="M 178 181 L 178 203 L 127.04 203 L 127 336.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 127 341.88 L 123.5 334.88 L 127 336.63 L 130.5 334.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 250px; margin-left: 126px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">80/tcp</div></div></div></foreignObject><text x="126" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">80/tcp</text></switch></g><path d="M 178 181 L 178 203 L 48 203 L 48 250.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 48 255.88 L 44.5 248.88 L 48 250.63 L 51.5 248.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 220px; margin-left: 46px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">9000/tcp</div></div></div></foreignObject><text x="46" y="224" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">9000/tcp</text></switch></g><rect x="145.5" y="141" width="130" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 161px; margin-left: 147px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Gateway Service<br style="border-color: var(--border-color);" />(NGINX)</div></div></div></foreignObject><text x="211" y="165" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Gateway Service...</text></switch></g><ellipse cx="362" cy="40.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 362 48 L 362 73 M 362 53 L 347 53 M 362 53 L 377 53 M 362 73 L 347 93 M 362 73 L 377 93" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 100px; margin-left: 362px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>JDBC</b></div></div></div></foreignObject><text x="362" y="112" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">JDBC</text></switch></g><path d="M 282.37 163.03 L 363.52 163.48 L 363.07 119.37" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 277.12 163.01 L 284.14 159.54 L 282.37 163.03 L 284.1 166.54 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 363.01 114.12 L 366.58 121.08 L 363.07 119.37 L 359.58 121.15 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 163px; margin-left: 323px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="323" y="167" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><ellipse cx="58" cy="40.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 58 48 L 58 73 M 58 53 L 43 53 M 58 53 L 73 53 M 58 73 L 43 93 M 58 73 L 73 93" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 100px; margin-left: 58px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><b>API</b></div></div></div></foreignObject><text x="58" y="112" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">API</text></switch></g><path d="M 58 119.37 L 58 163 L 139.63 163" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 58 114.12 L 61.5 121.12 L 58 119.37 L 54.5 121.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 144.88 163 L 137.88 166.5 L 139.63 163 L 137.88 159.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 163px; margin-left: 93px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">80/tcp</div></div></div></foreignObject><text x="93" y="166" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">80/tcp</text></switch></g><path d="M 258.5 303 L 298.24 303 L 331.63 303" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 336.88 303 L 329.88 306.5 L 331.63 303 L 329.88 299.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 302px; margin-left: 292px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="292" y="306" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><rect x="162.5" y="283" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 303px; margin-left: 164px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Data Service<br />(Spring AMQP)</div></div></div></foreignObject><text x="211" y="307" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Data Service...</text></switch></g><path d="M 210.5 263 L 210.5 276.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 210.5 281.88 L 207 274.88 L 210.5 276.63 L 214 274.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="162.5" y="223" width="96" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 243px; margin-left: 164px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Broker Service<br style="border-color: var(--border-color);" />(RabbitMQ)</div></div></div></foreignObject><text x="211" y="247" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Broker Service...</text></switch></g><path d="M 175 363 L 293.04 363 L 293.04 315.48 L 331.63 315.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 336.88 315.5 L 329.88 319 L 331.63 315.5 L 329.88 312 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 363px; margin-left: 243px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">3306/tcp</div></div></div></foreignObject><text x="243" y="367" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">3306/tcp</text></switch></g><rect x="79" y="343" width="96" height="40" rx="6" ry="6" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 363px; margin-left: 80px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Metadata Service<br />(Spring AMQP)</div></div></div></foreignObject><text x="127" y="367" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Metadata Service...</text></switch></g><path d="M 48 297 L 48 363 L 72.63 363" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 77.88 363 L 70.88 366.5 L 72.63 363 L 70.88 359.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="0" y="257" width="96" height="40" rx="6" ry="6" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 277px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage Service<br />(SeaweedFS)</div></div></div></foreignObject><text x="48" y="281" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage Service...</text></switch></g><path d="M 338 279.6 C 338 274.85 349.19 271 363 271 C 369.63 271 375.99 271.91 380.68 273.52 C 385.37 275.13 388 277.32 388 279.6 L 388 326.4 C 388 331.15 376.81 335 363 335 C 349.19 335 338 331.15 338 326.4 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 388 279.6 C 388 284.35 376.81 288.2 363 288.2 C 349.19 288.2 338 284.35 338 279.6" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="322" y="333" width="85" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 89px; height: 1px; padding-top: 343px; margin-left: 320px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">data-db</div></div></div></foreignObject><text x="365" y="347" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">data-db</text></switch></g><rect x="210.5" y="403" width="30" height="16" fill="#e6e6e6" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="248" y="403" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 411px; margin-left: 250px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">External images</div></div></div></foreignObject><text x="250" y="415" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">External images</text></switch></g><rect x="210.5" y="423" width="30" height="16" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="248" y="423" width="140" height="16" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 138px; height: 1px; padding-top: 431px; margin-left: 250px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Maintained images</div></div></div></foreignObject><text x="250" y="435" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Maintained images</text></switch></g><rect x="225.5" y="403" width="15" height="16" fill="#dae8fc" stroke="#000000" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/.docs/images/identifier-doi.png b/.docs/images/identifier-doi.png
deleted file mode 100644
index 114f42c224a95651fbd7216b5d8c3d5e0a826898..0000000000000000000000000000000000000000
Binary files a/.docs/images/identifier-doi.png and /dev/null differ
diff --git a/.docs/images/mark.psd b/.docs/images/mark.psd
new file mode 100644
index 0000000000000000000000000000000000000000..2fd9b01604470ebbd270fc089fd5c890461f360e
Binary files /dev/null and b/.docs/images/mark.psd differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-1.png b/.docs/images/screenshots/assign-database-pid-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4dfd9fa6f15f6a871aeeae3873b5ce7441acffc
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-1.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-2.png b/.docs/images/screenshots/assign-database-pid-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..3532e7b86d925936542c85ac5effe1faafca3158
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-2.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-3.png b/.docs/images/screenshots/assign-database-pid-step-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..258feda852d4935ca0d659dd207f0459bed5ecad
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-3.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-4.png b/.docs/images/screenshots/assign-database-pid-step-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e6bea832e52a9c22f2365b0c82634b9cac6b5f6
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-4.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-5.png b/.docs/images/screenshots/assign-database-pid-step-5.png
new file mode 100644
index 0000000000000000000000000000000000000000..418771db5c228ae9b9a793fd80ca74a0287411f2
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-5.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-6.png b/.docs/images/screenshots/assign-database-pid-step-6.png
new file mode 100644
index 0000000000000000000000000000000000000000..9d91e07576220f603f2d7036a3a0e767c6f0450a
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-6.png differ
diff --git a/.docs/images/screenshots/assign-database-pid-step-7.png b/.docs/images/screenshots/assign-database-pid-step-7.png
new file mode 100644
index 0000000000000000000000000000000000000000..22db3694bab7fefead7c37f1fe6b801fb5975f67
Binary files /dev/null and b/.docs/images/screenshots/assign-database-pid-step-7.png differ
diff --git a/.docs/images/screenshots/create-account-step-1.png b/.docs/images/screenshots/create-account-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..774fb5f3071cd9c8b5085746669fe092daedf2b2
Binary files /dev/null and b/.docs/images/screenshots/create-account-step-1.png differ
diff --git a/.docs/images/screenshots/create-account-step-2.png b/.docs/images/screenshots/create-account-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..07ea7ae5c40582a72f238a465a0ac243aa5e93d8
Binary files /dev/null and b/.docs/images/screenshots/create-account-step-2.png differ
diff --git a/.docs/images/screenshots/create-account-step-3.png b/.docs/images/screenshots/create-account-step-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..4174652e9610433428fba59cb38aa33b866c890a
Binary files /dev/null and b/.docs/images/screenshots/create-account-step-3.png differ
diff --git a/.docs/images/screenshots/create-database-step-1.png b/.docs/images/screenshots/create-database-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ccea22e4f22844f9da417a9a55e6f5192fd7bc1a
Binary files /dev/null and b/.docs/images/screenshots/create-database-step-1.png differ
diff --git a/.docs/images/screenshots/create-database-step-2.png b/.docs/images/screenshots/create-database-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae399a58eda6a5a7cb0a9e9381d2981ddae938f2
Binary files /dev/null and b/.docs/images/screenshots/create-database-step-2.png differ
diff --git a/.docs/images/screenshots/create-database-step-3.png b/.docs/images/screenshots/create-database-step-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..6381712733252828a68084daf471be1449524b4b
Binary files /dev/null and b/.docs/images/screenshots/create-database-step-3.png differ
diff --git a/.docs/images/screenshots/database-jdbc.png b/.docs/images/screenshots/database-jdbc.png
new file mode 100644
index 0000000000000000000000000000000000000000..05f66a0ac84f23086c50de88c060ba708f50836b
Binary files /dev/null and b/.docs/images/screenshots/database-jdbc.png differ
diff --git a/.docs/images/screenshots/export-subset-step-1.png b/.docs/images/screenshots/export-subset-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ae19286755958112e71689cc6b331ed479f25cb
Binary files /dev/null and b/.docs/images/screenshots/export-subset-step-1.png differ
diff --git a/.docs/images/screenshots/export-subset-step-2.png b/.docs/images/screenshots/export-subset-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..e555416a3ae52118e7606ee71e515dfda83779c9
Binary files /dev/null and b/.docs/images/screenshots/export-subset-step-2.png differ
diff --git a/.docs/images/screenshots/export-subset-step-3.png b/.docs/images/screenshots/export-subset-step-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b98232bad7517b3d822cfec6cb0b0c6fec351c8
Binary files /dev/null and b/.docs/images/screenshots/export-subset-step-3.png differ
diff --git a/.docs/images/screenshots/export-subset-step-4.png b/.docs/images/screenshots/export-subset-step-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..8279eda3828600ce530f5dbb1b51670e38ecccd2
Binary files /dev/null and b/.docs/images/screenshots/export-subset-step-4.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-1.png b/.docs/images/screenshots/import-dataset-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ac971983db7fd533807f821bbf13984571c0a51
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-1.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-2.png b/.docs/images/screenshots/import-dataset-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..71eba84a62eb322cd80e15038bdb1ecbb73db053
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-2.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-3.png b/.docs/images/screenshots/import-dataset-step-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f763332cab44a8cf629151a0def8fac577135bd
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-3.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-4.png b/.docs/images/screenshots/import-dataset-step-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..888a3557d74baebfb583a74535f5514d8378c7f6
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-4.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-5.png b/.docs/images/screenshots/import-dataset-step-5.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5f441247633b6fe47d84c02737b30392be9a408
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-5.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-6.png b/.docs/images/screenshots/import-dataset-step-6.png
new file mode 100644
index 0000000000000000000000000000000000000000..734a4f0fa3d620e6d93b53b98158f0061ac7b622
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-6.png differ
diff --git a/.docs/images/screenshots/import-dataset-step-7.png b/.docs/images/screenshots/import-dataset-step-7.png
new file mode 100644
index 0000000000000000000000000000000000000000..deccd46b17a9d8d2f36dc296f9e3895a662961b9
Binary files /dev/null and b/.docs/images/screenshots/import-dataset-step-7.png differ
diff --git a/.docs/images/screenshots/private-database-access-step-1.png b/.docs/images/screenshots/private-database-access-step-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c942f0858948e515714a131a92fc33a569a4880
Binary files /dev/null and b/.docs/images/screenshots/private-database-access-step-1.png differ
diff --git a/.docs/images/screenshots/private-database-access-step-2.png b/.docs/images/screenshots/private-database-access-step-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..e90cdc7412bd355f4ccd1131eb51d3952951a6ac
Binary files /dev/null and b/.docs/images/screenshots/private-database-access-step-2.png differ
diff --git a/.docs/images/screenshots/search-faceted.png b/.docs/images/screenshots/search-faceted.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d233c585c14c702a462e80074da02a4cf44c93f
Binary files /dev/null and b/.docs/images/screenshots/search-faceted.png differ
diff --git a/.docs/images/screenshots/table-amqp.png b/.docs/images/screenshots/table-amqp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0351ccdf13dcec3efb3480d605a5f34c22dfb97f
Binary files /dev/null and b/.docs/images/screenshots/table-amqp.png differ
diff --git a/.docs/images/statistics-example-unit-independent-search.png b/.docs/images/statistics-example-unit-independent-search.png
new file mode 100644
index 0000000000000000000000000000000000000000..27325eb67eec0a20d78386e914028662e3ab7485
Binary files /dev/null and b/.docs/images/statistics-example-unit-independent-search.png differ
diff --git a/.docs/images/statistics-example.png b/.docs/images/statistics-example.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbca0835ddb180384a96eba654c179db433de50d
Binary files /dev/null and b/.docs/images/statistics-example.png differ
diff --git a/.docs/images/statistics-mirror.png b/.docs/images/statistics-mirror.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecc52de9c08779853fc35c0796799dffdda38c3a
Binary files /dev/null and b/.docs/images/statistics-mirror.png differ
diff --git a/.docs/index.md b/.docs/index.md
index d1b032955813e1dea68be4205a1663e6c73b78e0..0ac7b018dff1a0422f69d9661f67ba2d762920a6 100644
--- a/.docs/index.md
+++ b/.docs/index.md
@@ -14,8 +14,8 @@ collection. Challenges revolve around organizing, searching and retrieving conte
 constitute a major technical burden as their internal representation greatly differs from static documents most digital
 repositories are designed for.
 
-[Get Started](./deployment-docker-compose){ .action-button .md-button .md-button--primary }
-[Learn More](./system){ .action-button .md-button .md-button--secondary }
+[System Description](./system){ .action-button .md-button .md-button--secondary }
+[How to use](./usage-overview){ .action-button .md-button .md-button--primary }
 
 ## Application Areas
 
@@ -26,5 +26,5 @@ evolving, allows reproducing of query results and supports findable-, accessible
 ## More Information
 
 - Demonstration instance [https://dbrepo1.ec.tuwien.ac.at](https://dbrepo1.ec.tuwien.ac.at)
-- Sandbox instance [https://test.dbrepo.tuwien.ac.at](https://dbrepo2.ec.tuwien.ac.at)
+- Test instance [https://test.dbrepo.tuwien.ac.at](https://test.dbrepo.tuwien.ac.at)
 - System description [https://doi.org/10.2218/ijdc.v17i1.825](https://doi.org/10.2218/ijdc.v17i1.825)
diff --git a/.docs/overrides/main.html b/.docs/overrides/main.html
index a637efc3f7d7664e00bc893e345f433762f0b61f..5da83ed9258551258c3a8bc9458d678d66ee62bb 100644
--- a/.docs/overrides/main.html
+++ b/.docs/overrides/main.html
@@ -4,16 +4,17 @@
 <label for="version">Version</label>
 <select style="margin-left:8px;" id="version" name="version" onchange="switchVersion(this.options[this.selectedIndex].value)">
     <option value="1.4.0">1.4.0</option>
-    <option value="1.3.9">1.3.9</option>
+    <option value="1.3.0">1.3.0</option>
     <option value="latest">latest</option>
 </select>
 <script>
     function getVersion() {
         const segments = location.pathname.split('/')
+        console.debug('segments', segments)
         if (segments.length >= 4) {
             return segments[3]
         } else {
-            return '$TAG'
+            return '$VERSION'
         }
     }
     function switchVersion(value) {
diff --git a/.docs/publications.md b/.docs/publications.md
index 9129d12e9762a9fc0d75666715566c83a5368766..8da7c4f985f920458f8813bbb90942b520f2a92b 100644
--- a/.docs/publications.md
+++ b/.docs/publications.md
@@ -6,6 +6,18 @@ hide:
 
 # Publications
 
+## Logos
+
+DBRepo logo in various formats:
+
+* [logo.png](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-ui/static/logo.png)
+* [logo.svg](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-ui/static/logo.svg)
+
+DBRepo logo (short) in various formats:
+
+* [favicon.svg](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-ui/static/favicon.svg)
+* [favicon.png](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-ui/static/favicon.png)
+
 ## Refereed
 
 ##### 2023
diff --git a/.docs/redirect.html b/.docs/redirect.html
index 9c4c9805eecc1d43bcd50dc95750ecf336736423..de670e15b3b0a0832987928fcf6a2a5a81a4ce9f 100644
--- a/.docs/redirect.html
+++ b/.docs/redirect.html
@@ -1,18 +1,20 @@
 <!DOCTYPE html>
 <html lang="en">
+<!-- This file exists only once
+     in the final documentation -->
 <head>
     <meta charset="UTF-8">
     <title>Redirect Notice</title>
-    <meta http-equiv="Refresh" content="0; url='https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/latest/'" />
+    <meta http-equiv="Refresh" content="0; url='https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/$VERSION/'" />
 </head>
 <body>
 <h1>Redirect Notice</h1>
 <p>
-    This page should automatically open the documentation for version <code>latest</code>. In case this page does not load the site is
+    This page should automatically open the documentation for version <code>$VERSION</code>. In case this page does not load the site is
     available at:
 </p>
 <p>
-    <a href="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/latest/">https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/latest/</a>
+    <a href="https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/$VERSION/">https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/$VERSION/</a>
 </p>
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/.docs/system-databases-auth.md b/.docs/system-databases-auth.md
index c368151a4c7fab0c78c1c6555003ca35efc15f92..90ba31bcf55c6e53ef2471f45911c02a69d425fa 100644
--- a/.docs/system-databases-auth.md
+++ b/.docs/system-databases-auth.md
@@ -8,7 +8,7 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`bitnami/mariadb:10.5`](https://hub.docker.com/r/bitnami/mariadb)
+    Image: [`bitnami/mariadb:11.2.2-debian-11-r0`](https://hub.docker.com/r/bitnami/mariadb)
 
     * Ports: 3306/tcp
     * JDBC: `jdbc://mariadb:<hostname>:3306`
diff --git a/.docs/system-databases-data.md b/.docs/system-databases-data.md
index ff62c19476839a92c7c612a1f12dcfbfbf2f113f..7e02599f943a14283429d179a91315a6bd316d72 100644
--- a/.docs/system-databases-data.md
+++ b/.docs/system-databases-data.md
@@ -8,11 +8,18 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`bitnami/mariadb:10.5`](https://hub.docker.com/r/bitnami/mariadb)
+    Image: [`bitnami/mariadb-galera:11.2.2-debian-11-r0`](https://hub.docker.com/r/bitnami/mariadb-galera)
 
     * Ports: 3306/tcp
     * JDBC: `jdbc://mariadb:<hostname>:3306`
 
+!!! debug "Debug Information"
+
+    Image: [`dbrepo/data-db-sidecar:$TAG`](https://hub.docker.com/r/dbrepo/data-db-sidecar)
+
+    * Ports: 3305/tcp
+    * Swagger UI: `http://<hostname>:1080/swagger-ui/` <a href="../swagger/sidecar" target="_blank">:fontawesome-solid-square-up-right: view online</a>
+
 ## Overview
 
 By default, only one Data Database is deployed. You can deploy multiple (different) Data Database instances and make
@@ -21,7 +28,7 @@ them available in the repository as follows:
 ```console
 curl \
    -sSL \
-   http://<hostname>:9093/api/container \
+   http://<hostname>/api/container \
    -X POST \
    -d '{"name": "Data Database 2", "imageId": 1, "host": "example.com", "port": 3306, "privilegedUsername": "root", "privilegedPassword": "s3cr3t" }'
 ```
diff --git a/.docs/system-databases-metadata.md b/.docs/system-databases-metadata.md
index 1cfcf69885006ca8ed560142fd4103ab5eb92bc0..326ed3874e3f968fb28f5eaba677c53f9d71b7fa 100644
--- a/.docs/system-databases-metadata.md
+++ b/.docs/system-databases-metadata.md
@@ -8,7 +8,7 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`bitnami/mariadb:10.5`](https://hub.docker.com/r/bitnami/mariadb)
+    Image: [`dbrepo/metadata-db:$TAG`](https://hub.docker.com/r/dbrepo/metadata-db)
 
     * Ports: 3306/tcp
     * JDBC: `jdbc://mariadb:<hostname>:3306`
diff --git a/.docs/system-databases-search.md b/.docs/system-databases-search.md
index ce9965ee12e33c66f25639c79bb8109aff19b10d..c01fa7c638d126148aa8925b02df3eb71af5ffdb 100644
--- a/.docs/system-databases-search.md
+++ b/.docs/system-databases-search.md
@@ -8,11 +8,9 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/search-db:1.4`](https://hub.docker.com/r/dbrepo/search-db)
+    Image: [`dbrepo/search-db:$TAG`](https://hub.docker.com/r/dbrepo/search-db)
 
     * Ports: 9200/tcp
-    * Indexes: `http://:9200/_all`
-    * Health: `http://:9200/_cluster/health`
 
 ## Overview
 
diff --git a/.docs/system-other-search-dashboard.md b/.docs/system-other-search-dashboard.md
index a2ac309560e7cb6bf987c8f11ad0e7cdbd53b78e..a3d0e9ae12c590a226eb94afcc3c8034e4376eca 100644
--- a/.docs/system-other-search-dashboard.md
+++ b/.docs/system-other-search-dashboard.md
@@ -11,7 +11,7 @@ author: Martin Weise
     Image: [`opensearchproject/opensearch-dashboards:2.10.0`](https://hub.docker.com/r/opensearchproject/opensearch-dashboards)
 
     * Ports: 5601/tcp
-    * UI: `http://:5601/admin/dashboard/`
+    * UI: `http://<hostname>/admin/dashboard/`
 
 ## Overview
 
diff --git a/.docs/system-other-ui.md b/.docs/system-other-ui.md
index 6ea29369f743f6a806c3135f04f8116cc59dc5e6..00fc3113c6149e2653a98344259f5317a814031c 100644
--- a/.docs/system-other-ui.md
+++ b/.docs/system-other-ui.md
@@ -8,23 +8,23 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/ui:1.4`](https://hub.docker.com/r/dbrepo/ui)
+    Image: [`dbrepo/ui:$TAG`](https://hub.docker.com/r/dbrepo/ui)
 
     * Ports: 3000/tcp, 9100/tcp
-    * Prometheus: `http://:9100/metrics`
-    * UI: `http://:3000/`
+    * Prometheus: `http://<hostname>:9100/metrics`
+    * UI: `http://<hostname>/`
 
 ## Overview
 
 It provides a *user interface* (UI) for a researcher to interact with the database repository's API.
 
 <figure markdown>
-   ![Data ingest](images/ui.png){ .img-border }
-   <figcaption>User Interface</figcaption>
+![Data ingest](images/ui.png){ .img-border }
+<figcaption>User Interface</figcaption>
 </figure>
 
 <figure markdown>
-![UI microservice architecture detailed](images/architecture-ui.png)
+![UI microservice architecture detailed](images/architecture-ui.svg)
 <figcaption>Architecture of the UI microservice</figcaption>
 </figure>
 
diff --git a/.docs/system-services-analyse.md b/.docs/system-services-analyse.md
index 93b188279e47e9e1ad5c85b66057737493e91365..66ee40d47789180e4ad4d5c47e200aba7d493ff6 100644
--- a/.docs/system-services-analyse.md
+++ b/.docs/system-services-analyse.md
@@ -8,12 +8,12 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/analyse-service:1.4`](https://hub.docker.com/r/dbrepo/analyse-service)
+    Image: [`dbrepo/analyse-service:$TAG`](https://hub.docker.com/r/dbrepo/analyse-service)
 
     * Ports: 5000/tcp
     * Prometheus: `http://<hostname>:5000/metrics`
     * Health: `http://<hostname>:5000/health`
-    * Swagger UI: `http://<hostname>:5000/swagger-ui/index.html` <a href="../swagger/analyse" target="_blank">:fontawesome-solid-square-up-right: view online</a>
+    * Swagger UI: `http://<hostname>:5000/swagger-ui/` <a href="../swagger/analyse" target="_blank">:fontawesome-solid-square-up-right: view online</a>
 
 ## Overview
 
diff --git a/.docs/system-services-authentication.md b/.docs/system-services-authentication.md
index 1eec90ea7703bb865c1be8ef3d65f7b78fa0ff9a..41cea49974dfc7dff90ca6b2ca7ef46d0afa9a03 100644
--- a/.docs/system-services-authentication.md
+++ b/.docs/system-services-authentication.md
@@ -8,12 +8,12 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/authentication-service:1.4`](https://hub.docker.com/r/dbrepo/authentication-service)
+    Image: [`dbrepo/authentication-service:$TAG`](https://hub.docker.com/r/dbrepo/authentication-service)
 
     * Ports: 8080/tcp
-    * Admin Console: `http://<hostname>:8080/api/auth/admin/`
     * Health: `http://<hostname>:8080/api/auth/health`
     * Prometheus: `http://<hostname>:8080/api/auth/metrics`
+    * UI: `http://<hostname>/api/auth/admin/`
 
 ## Overview
 
diff --git a/.docs/system-services-broker.md b/.docs/system-services-broker.md
index f7919f8bd2855a0c3db7e9fcd215b87fe2d1e6bd..cc4b775c1fe20a27eabad6761e9cf4a223ed94cb 100644
--- a/.docs/system-services-broker.md
+++ b/.docs/system-services-broker.md
@@ -12,8 +12,8 @@ author: Martin Weise
 
     * Ports: 5672/tcp, 15672/tcp, 15692/tcp
     * AMQP: `amqp://<hostname>:5672`
-    * Management: `http://<hostname>:15672`
     * Prometheus: `http://<hostname>:15692/metrics`
+    * Management: `http://<hostname>/admin/broker`
 
 ## Overview
 
diff --git a/.docs/system-services-data.md b/.docs/system-services-data.md
index 698fc3bbb4a044b47092888c7e44c82c644367f7..88e781e6e8bc22af2dc6299037a164300cafdb8c 100644
--- a/.docs/system-services-data.md
+++ b/.docs/system-services-data.md
@@ -8,7 +8,7 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/data-service:1.4`](https://hub.docker.com/r/dbrepo/data-service)
+    Image: [`dbrepo/data-service:$TAG`](https://hub.docker.com/r/dbrepo/data-service)
 
     * Ports: 9093/tcp
     * Info: `http://<hostname>:9093/actuator/info`
diff --git a/.docs/system-services-metadata.md b/.docs/system-services-metadata.md
index a44316cc07954d2b24e73bedfcb6d1dfa0a08376..434a8318388afb326a14722486bbc60e628def9b 100644
--- a/.docs/system-services-metadata.md
+++ b/.docs/system-services-metadata.md
@@ -8,15 +8,15 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [`dbrepo/metadata-service:1.4`](https://hub.docker.com/r/dbrepo/metadata-service)
+    Image: [`dbrepo/metadata-service:$TAG`](https://hub.docker.com/r/dbrepo/metadata-service)
 
     * Ports: 9099/tcp
-    * Info: `http://9093:9099/actuator/info`
-    * Health: `http://9093:9099/actuator/health`
-        - Readiness: `http://9093:9099/actuator/health/readiness`
-        - Liveness: `http://9093:9099/actuator/health/liveness`
-    * Prometheus: `http://9093:9099/actuator/prometheus`
-    * Swagger UI: `http://9093:9099/swagger-ui/index.html` <a href="../swagger/metadata" target="_blank">:fontawesome-solid-square-up-right: view online</a>
+    * Info: `http://<hostname>:9099/actuator/info`
+    * Health: `http://<hostname>:9099/actuator/health`
+        - Readiness: `http://<hostname>:9099/actuator/health/readiness`
+        - Liveness: `http://<hostname>:9099/actuator/health/liveness`
+    * Prometheus: `http://<hostname>:9099/actuator/prometheus`
+    * Swagger UI: `http://<hostname>:9099/swagger-ui/index.html` <a href="../swagger/metadata" target="_blank">:fontawesome-solid-square-up-right: view online</a>
 
 ## Overview
 
@@ -32,47 +32,99 @@ This service manages the following topics:
 
 ### Databases
 
-The service handles table operations inside a database. We use [Hibernate](https://hibernate.org/orm/) for schema and 
+The service handles table operations inside a database. We use [Hibernate](https://hibernate.org/orm/) for schema and
 data ingest operations.
 
 ### Identifiers
 
-The service is responsible for creating and resolving a *persistent identifier* (PID) attached to a query to
-obtain the metadata attached to it and allow re-execution of a query. We store both the query and hashes of the query
-and result set to allow equality checks of the originally obtained result set and the currently obtained result set. In
-the reference implementation we currently only use a numerical id column and plan to integrate *digital object
-identifier* (DOI) through our institutional library soon.
-
-This service provides an OAI-PMH endpoint for metadata aggregators.
+The service is responsible for creating and resolving a *persistent identifier* (PID) attached to a database, subset,
+table or view to obtain the metadata attached to it and allow reproduction of the exact same result.
+
+This service also provides an OAI-PMH endpoint for metadata aggregators 
+(e.g. [OpenAIRE Graph](https://graph.openaire.eu/)). Through the User Interface, it also exposes metadata through
+JSON-LD to metadata aggregators (e.g. [Google Datasets](https://datasetsearch.research.google.com/)). PID metadata
+is always exposed, even for private databases.
+
+The service generates internal PIDs, essentially representing internal URIs in 
+the [DataCite Metadata Schema 4.4](https://doi.org/10.14454/3w3z-sa82). This can be enhanced with activating the 
+external DataCite Fabrica system to generate DOIs, this is disabled by default. 
+
+To activate DOI minting, pass your DataCite Fabrica credentials in the environment variables:
+
+```yaml title="docker-compose.yml"
+services:
+  dbrepo-metadata-service:
+    image: docker.io/dbrepo/metadata-service:1.4.0
+    environment:
+      spring_profiles_active: doi
+      DATACITE_URL: https://api.datacite.org
+      DATACITE_PREFIX: 10.12345
+      DATACITE_USERNAME: username
+      DATACITE_PASSWORD: password
+  ...
+```
 
 ### Queries
 
-It provides an interface to insert data into the tables. It also allows for view-only, paginated and versioned query 
-execution to the raw data.
+It provides an interface to insert data into the tables. It also allows for view-only, paginated and versioned query
+execution to the raw data. Any stale queries (query that have been executed by users in DBRepo but were not saved) are
+periodically being deleted from the query store based on the `DELETE_STALE_QUERIES_RATE` environment variable (defaults
+to 60 seconds).
 
 ### Semantics
 
 The service provides metadata to the table columns in the [Metadata Database](../system-databases-metadata) from
-registered ontologies like Wikidata [`wd:`](https://wikidata.org), Ontology of Units of 
-Measurement [`om2:`](https://www.ontology-of-units-of-measure.org/resource/om-2), Friend of a 
+registered ontologies like Wikidata [`wd:`](https://wikidata.org), Ontology of Units of
+Measurement [`om2:`](https://www.ontology-of-units-of-measure.org/resource/om-2), Friend of a
 Friend [`foaf:`](http://xmlns.com/foaf/0.1/), the [`prov:`](http://www.w3.org/ns/prov#) namespace, etc.
 
-
 ### Tables
 
 The service manages tables in the [Data Database](../system-databases-data) and manages the metadata of these tables
-in the [Metadata Database](../system-databases-metadata).
+in the [Metadata Database](../system-databases-metadata). Any tables that are created outside of DBRepo (e.g. directly via the JDBC API) are
+periodically fetched by this service (based on the `OBTAIN_METADATA_RATE` environment variable, default interval is 60
+seconds).
 
 ### Users
 
-The service manages users in the [Data Database](../system-databases-data) 
+The service manages users in the [Data Database](../system-databases-data)
 and [Metadata Database](../system-databases-metadata), as well as in the [Broker Service](../system-services-broker)
 and the [Authentication Service](../system-services-authentication).
 
+The default configuration grants the users only very basic permissions on the databases:
+
+* `SELECT`
+* `CREATE`
+* `CREATE VIEW`
+* `CREATE ROUTINE`
+* `CREATE TEMPORARY TABLES`
+* `LOCK TABLES`
+* `INDEX`
+* `TRIGGER`
+* `INSERT`
+* `UPDATE`
+* `DELETE`
+
+This configuration is passed as environment variable `GRANT_PRIVILEGES` to the service as comma-separated string. You
+can add/remove grants by setting this environment variable, e.g. allow the users to only select data and create
+temporary tables:
+
+```yaml title="docker-compose.yml"
+services:
+  dbrepo-metadata-service:
+    environment:
+      GRANT_PRIVILEGES=SELECT,CREATE TEMPORARY TABLES
+      ...
+```
+
+A list of all grants is available in the MariaDB documentation for [`GRANT`](https://mariadb.com/kb/en/grant/)
+
 ### Views
 
 The service manages views in the [Data Database](../system-databases-data)
-and [Metadata Database](../system-databases-metadata).
+and [Metadata Database](../system-databases-metadata). Any views that are created outside of DBRepo (e.g. directly via 
+the JDBC API) are periodically fetched by this service (based on the `OBTAIN_METADATA_RATE` environment variable,
+default interval is 60 seconds).
 
 ## Limitations
 
diff --git a/.docs/system-services-search.md b/.docs/system-services-search.md
new file mode 100644
index 0000000000000000000000000000000000000000..397feff381a68adcbcbc13998e860f8ae7a0593c
--- /dev/null
+++ b/.docs/system-services-search.md
@@ -0,0 +1,86 @@
+---
+author: Martin Weise
+---
+
+# Search Service
+
+## tl;dr
+
+!!! debug "Debug Information"
+
+    Image: [`dbrepo/search-service:$TAG`](https://hub.docker.com/r/dbrepo/search-service)
+
+    * Ports: 4000/tcp
+    * Health: `http://<hostname>:4000/api/search/health`
+    * Prometheus: `http://<hostname>:4000/metrics`
+    * Swagger UI: `http://<hostname>:4000/swagger-ui/` <a href="../swagger/search" target="_blank">:fontawesome-solid-square-up-right: view online</a>
+
+## Overview
+
+This service communicates between the [Search Database](../system-databases-search) and 
+the [User Interface](../system-other-ui) to allow structured search of databases, tables, columns, users, identifiers,
+views, semantic concepts &amp; units of measurements used in databases.
+
+## Index
+
+There is only one 
+index [`database`](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-search-db/init/indices/database.json)
+that holds all the metadata information which is mirrored from the [Metadata Database](../system-databases-metadata).
+
+<figure markdown>
+![Mirroring statistical properties in Metadata Database and Search Database](images/statistics-mirror.png)
+<figcaption>Statistical properties in Metadata Database and Search Database</figcaption>
+</figure>
+
+## Faceted Browsing
+
+This service enables the frontend to search the `database` index with eight different *types* of desired results 
+(database, table, column, view, identifier, user, concept, unit) and their *facets*.
+
+For example, the [User Interface](../system-other-ui) allows for the search of databases that contain a certain
+semantic concept (provided as URI, e.g. 
+temperature [http://www.wikidata.org/entity/Q11466](http://www.wikidata.org/entity/Q11466)) and unit of measurement 
+(provided as URI, e.g. degree 
+Celsius [http://www.ontology-of-units-of-measure.org/resource/om-2/degreeCelsius](http://www.ontology-of-units-of-measure.org/resource/om-2/degreeCelsius)).
+
+An example on faceted browsing is found in the [usage examples](../usage-search).
+
+## Unit Independent Search
+
+Since the repository automatically collects statistical properties (min, max, mean, median, std.dev) in both the
+[Metadata Database](../system-databases-metadata) and the [Search Database](../system-databases-search), a special
+search can be performed when at least two columns have the same semantic concept (e.g. temperature) annotated and
+the units of measurements can be transformed.
+
+<figure markdown>
+![Two tables with compatible semantic concepts (Temperature) and units of measurement (left is in degree Celsius, right is in degree Fahrenheit)](images/statistics-example.png)
+<figcaption>Two tables with compatible semantic concepts and units of measurement</figcaption>
+</figure>
+
+In short, the search service transforms the statistical properties not in the target unit of measurements is transformed
+by using the [`omlib`](https://github.com/dieudonneWillems/OMLib) package. 
+
+For example: a user wants to find datasets that contain *"temperature measurements between 0 - 10 &deg;C"*. Then the 
+search service transforms the query to the dataset on the right from &deg;F to contain *"temperature measurements
+between 32 - 50 &deg;F"* instead.
+
+<figure markdown>
+![Unit independent search query transformation](images/statistics-example-unit-independent-search.png)
+<figcaption>Unit independent search query transformation</figcaption>
+</figure>
+
+## Examples
+
+TBD
+
+## Limitations
+
+!!! question "Do you miss functionality? Do these limitations affect you?"
+
+    We strongly encourage you to help us implement it as we are welcoming contributors to open-source software and get
+    in [contact](../contact) with us, we happily answer requests for collaboration with attached CV and your programming 
+    experience!
+
+## Security
+
+(nothing)
diff --git a/.docs/system-services-upload.md b/.docs/system-services-upload.md
index 656b82b8692a80aaacac6f8a1283492c9ea2ee61..0047179600eb6365e69b4970e1eb9f4bfca7eb8e 100644
--- a/.docs/system-services-upload.md
+++ b/.docs/system-services-upload.md
@@ -8,11 +8,12 @@ author: Martin Weise
 
 !!! debug "Debug Information"
 
-    Image: [tusproject/tusd:v1.12`](https://hub.docker.com/r/tusproject/tusd)
+    Image: [`tusproject/tusd:v1.12`](https://hub.docker.com/r/tusproject/tusd)
 
     * Ports: 1080/tcp
     * Prometheus: `http://<hostname>:1080/api/upload/metrics`
     * API: `http://<hostname>:1080/api/upload`
+    * Swagger UI: <a href="../swagger/upload" target="_blank">:fontawesome-solid-square-up-right: view online</a>
 
 ## Overview
 
diff --git a/.docs/usage-overview.md b/.docs/usage-overview.md
index db65d7cc824ba5406599a29495aa0220bfb91144..af1ce9cbf8ea18645c2795b3d390e49ab41d6208 100644
--- a/.docs/usage-overview.md
+++ b/.docs/usage-overview.md
@@ -4,8 +4,1236 @@ author: Martin Weise
 
 # Overview
 
-!!! abstract "Abstract"
+We give usage examples of the most important use-cases we identified.
 
-    We modified some services and exchanged them with reviewed, open-source implementations that extend the functionality
-    even more from version 1.2 onwards. On this page, some of the configuration possible is summarized.
+|                                                           |         UI         |      Terminal      |        JDBC        |       Python       |
+|-----------------------------------------------------------|:------------------:|:------------------:|:------------------:|:------------------:|
+| [Create User Account](#create-user-account)               | :white_check_mark: | :white_check_mark: |        :x:         | :white_check_mark: | 
+| [Create Database](#create-database)                       | :white_check_mark: | :white_check_mark: |        :x:         | :white_check_mark: | 
+| [Import Dataset](#import-dataset)                         | :white_check_mark: | :white_check_mark: |        :x:         | :white_check_mark: | 
+| [Import Database Dump](#import-database-dump)             |        :x:         |        :x:         | :white_check_mark: |        :x:         | 
+| [Import Live Data](#import-live-data)                     |        :x:         | :white_check_mark: | :white_check_mark: | :white_check_mark: | 
+| [Export Subset](#export-subset)                           | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | 
+| [Assign Database PID](#assign-database-pid)               | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | 
+| [Private Database &amp; Access](#private-database-access) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | 
 
+## Create User Account
+
+A user wants to create an account in DBRepo.
+
+=== "UI"
+
+    To create a new user account in DBRepo, navigate to the signup page by clicking the ":material-account-plus: SIGNUP"
+    button and provide a valid work e-mail address :material-numeric-1-circle-outline: and a username (in lowercase
+    alphanumeric characters) :material-numeric-2-circle-outline:. Choose a secure password in field 
+    :material-numeric-3-circle-outline: and repeat it in field :material-numeric-4-circle-outline:. Click "SUBMIT" and
+    the system creates a user account in Figure 1 with the [default roles](../system-services-authentication/#roles)
+    that your administrator has assigned.
+
+    <figure markdown>
+    ![Create user account](images/screenshots/create-account-step-1.png){ .img-border }
+    <figcaption>Figure 1: Create user account.</figcaption>
+    </figure>
+
+    To login in DBRepo, navigate to the login page by clicking the ":material-login: LOGIN" button and provide the
+    username :material-numeric-1-circle-outline: and the password from the previous step
+    :material-numeric-2-circle-outline:. After clicking "LOGIN", you will acquire the roles assigned to you and are now
+    authenticated with DBRepo in Figure 2.
+
+    <figure markdown>
+    ![Create user account](images/screenshots/create-account-step-2.png){ .img-border }
+    <figcaption>Figure 2: Login to the user account.</figcaption>
+    </figure>
+
+    You can view your user information upon clicking on your username :material-numeric-1-circle-outline: on the top. To
+    change your password in all components of DBRepo, click the "AUTHENTICATION" tab :material-numeric-2-circle-outline:
+    and change your password by typing a new one into fields :material-numeric-3-circle-outline: and repeat it 
+    identically in field :material-numeric-4-circle-outline:. 
+
+    <figure markdown>
+    ![Change user account password](images/screenshots/create-account-step-3.png){ .img-border }
+    <figcaption>Figure 3: Change user account password.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    To create a new user account in DBRepo with the Terminal, provide your details in the following REST HTTP-API call.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Content-Type: application/json" \
+      -d '{"username":"foo","email":"foo.bar@example.com","password":"bar"}' \
+      http://localhost/api/user | jq .id
+    ```
+
+    To login in DBRepo, obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    You can view your user information by sending a request to the user endpoint with your access token.
+
+    ```bash
+    curl -sSL \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      http://localhost/api/user/USER_ID | jq
+    ```
+
+    To change your password in all components of DBRepo:
+
+    ```bash
+    curl -sSL \
+      -X PUT \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"password":"s3cr3tp4ss0rd"}' \
+      http://localhost/api/user/USER_ID/password | jq
+    ```
+
+=== "Python"
+
+    To create a new user account in DBRepo with the Terminal, provide your details in the following REST HTTP-API call.
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/user", json={
+        "username": "foo",
+        "password": "bar",
+        "email": "foo.bar@example.com"
+    })
+    user_id = response.json()["id"]
+    print(user_id)
+    ```
+
+    To login in DBRepo, obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    You can view your user information by sending a request to the user endpoint with your access token.
+
+    ```python
+    import requests
+    
+    response = requests.get("http://localhost/api/user/" + user_id, header={
+        "Authorization": "Bearer " + access_token
+    })
+    user_id = response.json()["id"]
+    print(user_id)
+    ```
+
+    To change your password in all components of DBRepo:
+
+    ```python
+    import requests
+    
+    requests.put("http://localhost/api/user/" + user_id + "/password", header={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "password": "s3cr3tp4ssw0rd"
+    })
+    ```
+
+## Create Database
+
+A user wants to create a database in DBRepo.
+
+=== "UI"
+
+    Login and press the ":material-plus: DATABASE" button on the top right :material-numeric-1-circle-outline: as seen in Figure 4.
+
+    <figure markdown>
+    ![Open the create database dialog](images/screenshots/create-database-step-1.png){ .img-border }
+    <figcaption>Figure 4: Open the create database dialog.</figcaption>
+    </figure>
+
+    Give the database a meaningful title :material-numeric-1-circle-outline: that describes the contained data in few 
+    words and select a pre-configured container :material-numeric-2-circle-outline: from the list for this database. To
+    finally create the database, press "Create" :material-numeric-3-circle-outline: as seen in Figure 5.
+
+    <figure markdown>
+    ![Create database form](images/screenshots/create-database-step-2.png){ .img-border }
+    <figcaption>Figure 5: Create database form.</figcaption>
+    </figure>
+
+    After a few seconds, you can see the created database in the "Recent Databases" list, as seen in Figure 6.
+
+    <figure markdown>
+    ![View the created database](images/screenshots/create-database-step-3.png){ .img-border }
+    <figcaption>Figure 6: View the created database.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Then list all available containers with their database engine descriptions and obtain a container id.
+
+    ```bash
+    curl -sSL \
+      http://localhost/api/container | jq
+    ```
+
+    Create a public databse with the container id from the previous step. You can also create a private database in this
+    step, others can still see the metadata.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"name":"Danube Water Quality Measurements","container_id":1,"is_public":true}' \
+      http://localhost/api/database | jq .id
+    ```
+
+=== "Python"
+
+    Obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Then list all available containers with their database engine descriptions and obtain a container id.
+
+    ```python
+    import requests
+    
+    response = requests.get("http://localhost/api/container")
+    print(response.json())
+    ```
+
+    Create a public databse with the container id from the previous step. You can also create a private database in this
+    step, others can still see the metadata.
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/database", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "name": "Danube Water Quality Measurements",
+        "container_id": 1,
+        "is_public": True
+    })
+    print(response.json()["id"])
+    ```
+
+## Import Dataset
+
+A user wants to import a static dataset (e.g. from a .csv file) into a database that they have at least `write-own`
+access to. This is the default for self-created databases like above in [Create Databases](#create-database).
+
+=== "UI"
+
+    Login and select a database where you have at least `write-all` access (this is the case for e.g. self-created 
+    databases). Click the ":material-cloud-upload: IMPORT CSV" button :material-numeric-1-circle-outline: as seen in 
+    Figure 7.
+
+    <figure markdown>
+    ![Open the import CSV form](images/screenshots/import-dataset-step-1.png){ .img-border }
+    <figcaption>Figure 7: Open the import CSV form.</figcaption>
+    </figure>
+
+    Provide the table name :material-numeric-1-circle-outline: and optionally a table description :material-numeric-2-circle-outline:
+    as seen in Figure 8.
+
+    <figure markdown>
+    ![Basic table information](images/screenshots/import-dataset-step-2.png){ .img-border }
+    <figcaption>Figure 8: Basic table information.</figcaption>
+    </figure>
+
+    Next, provide the dataset metadata that is necessary for import into the table by providing the dataset separator
+    (e.g. `,` or `;` or `\t`) in :material-numeric-1-circle-outline:. If your dataset has a header line (the first line
+    containing the names of the columns) set the number of lines to skip to 1 in field :material-numeric-2-circle-outline:.
+    If your dataset contains more lines that should be ignored, set the number of lines accordingly. If your dataset
+    contains quoted values, indicate this by setting the field :material-numeric-3-circle-outline: accordingly
+    in Figure 9.
+
+    If your dataset contains encodings for `NULL` (e.g. `NA`), provide this encoding information 
+    in :material-numeric-4-circle-outline:. Similar, if it contains encodings for boolean `true` (e.g. `1` or `YES`),
+    provide this encoding information in :material-numeric-5-circle-outline:. For boolean `false` (e.g. `0` or `NO`),
+    provide this information in :material-numeric-6-circle-outline:.
+
+    <figure markdown>
+    ![Dataset metadata necessary for import](images/screenshots/import-dataset-step-3.png){ .img-border }
+    <figcaption>Figure 9: Dataset metadata necessary for import.</figcaption>
+    </figure>
+
+    Select the dataset file from your local computer by clicking :material-numeric-1-circle-outline: or dragging the
+    dataset file onto the field in Figure 10.
+
+    <figure markdown>
+    ![Dataset import file](images/screenshots/import-dataset-step-4.png){ .img-border }
+    <figcaption>Figure 10: Dataset import file.</figcaption>
+    </figure>
+
+    The table schema is suggested based on heuristics between the upload and the suggested schema in Figure 8. If your
+    dataset has no column names present, e.g. you didn't provide a *Number of lines to skip* (c.f. Figure 6), then you
+    need to provide a column name in :material-numeric-1-circle-outline:. Provide a data type from the list of MySQL 8
+    available data types :material-numeric-2-circle-outline:. Indicate if the column is (part of) a primary key 
+    :material-numeric-4-circle-outline: or if `NULL` values are allowed in :material-numeric-5-circle-outline: or if a
+    unique constraint is needed (no values in this column are then allowed to repeat) in :material-numeric-6-circle-outline:.
+
+    Optionally, you can remove table column definitions by clicking the "REMOVE" button or add additional table column
+    definitions by clicking the "ADD COLUMN" button in Figure 11.
+
+    <figure markdown>
+    ![Confirm the table schema and provide missing information](images/screenshots/import-dataset-step-5.png){ .img-border }
+    <figcaption>Figure 11: Confirm the table schema and provide missing information.</figcaption>
+    </figure>
+
+    If a table column data type is of `DATE` or `TIMESTAMP` (or similar), provide a date format 
+    :material-numeric-3-circle-outline: from the list of available formats that are most similar to the one in the
+    dataset as seen in Figure 12.
+
+    <figure markdown>
+    ![Confirm the table schema and provide missing information](images/screenshots/import-dataset-step-6.png){ .img-border }
+    <figcaption>Figure 12: Confirm the table schema and provide missing information.</figcaption>
+    </figure>
+
+    When you are finished with the table schema definition, the dataset is imported and a table is created. You are
+    being redirected automatically to the table info page upon success, navigate to the "DATA" tab 
+    :material-numeric-1-circle-outline:. You can still delete the table :material-numeric-2-circle-outline: as long as
+    no identifier is associated with it :material-numeric-3-circle-outline:.
+
+    Public databases allow anyone to download :material-numeric-4-circle-outline: the table data as dataset file. Also
+    it allows anyone to view the recent history of inserted data :material-numeric-5-circle-outline: dialog in Figure
+    13.
+
+    <figure markdown>
+    ![Table data](images/screenshots/import-dataset-step-7.png){ .img-border }
+    <figcaption>Figure 13: Table data.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Select a database where you have at least `write-all` access (this is the case for e.g. self-created databases).
+
+    Upload the dataset via the [`tusc`](https://github.com/adhocore/tusc.sh) terminal application or use Python and
+    copy the file key.
+
+    ```bash
+    tusc -H http://localhost/api/upload/files -f danube.csv -b /dbrepo-upload/
+    ```
+
+    Analyse the dataset and get the table column names and datatype suggestion.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"filename":"FILEKEY","separator":","}' \
+      http://localhost/api/analyse/determinedt | jq
+    ```
+
+    Provide the table name and optionally a table description along with the table columns.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"name":"Danube water levels","description":"Measurements of the river danube water levels","columns":[{"name":"datetime","type":"timestamp","dfid":1,"primary_key":false,"null_allowed":true},{"name":"level","type":"bigint","size":255,"primary_key":false,"null_allowed":true}]}' \
+      http://localhost/api/database/1/table | jq .id
+    ```
+
+    Next, provide the dataset metadata that is necessary for import into the table by providing the dataset separator
+    (e.g. `,` or `;` or `\t`). If your dataset has a header line (the first line containing the names of the columns) 
+    set the number of lines to skip to 1. If your dataset contains more lines that should be ignored, set the number of
+    lines accordingly. If your dataset contains quoted values, indicate this by setting the field accordingly.
+
+    If your dataset contains encodings for `NULL` (e.g. `NA`), provide this encoding information. Similar, if it 
+    contains encodings for boolean `true` (e.g. `1` or `YES`), provide this encoding information. For boolean `false`
+    (e.g. `0` or `NO`), provide this information.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"location":"FILEKEY","separator":",","quote":"\"","skip_lines":1,"null_element":"NA"}' \
+      http://localhost/api/database/1/table/1/data/import | jq
+    ```
+
+    When you are finished with the table schema definition, the dataset is imported and a table is created. View the
+    table data:
+
+    ```bash
+    curl -sSL \
+      http://localhost/api/database/1/table/1/data?page=0&size=10 | jq
+    ```
+
+=== "Python"
+
+    Obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Select a database where you have at least `write-all` access (this is the case for e.g. self-created databases).
+
+    Upload the dataset via the Python [`boto3`](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) 
+    client to the `dbrepo-upload` bucket.
+
+    ```python
+    import boto3
+    import os
+    
+    client = boto3.client(service_name='s3', endpoint_url='http://localhost:9000',
+                          aws_access_key_id='seaweedfsadmin',
+                          aws_secret_access_key='seaweedfsadmin')
+    filepath = os.path.join('/path/to', 'your_dataset.csv')
+    client.upload_file(filepath, 'dbrepo-upload', 'your_dataset.csv')
+    ```
+
+    Analyse the dataset and get the table column names and datatype suggestion.
+
+    ```python
+    import requests
+
+    response = requests.post("http://localhost/api/analyse/determinedt", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "filename": "your_dataset.csv",
+        "separator": ","
+    })
+    print(response.json()["columns"])
+    ```
+
+    Provide the table name and optionally a table description along with the table columns.
+
+    ```python
+    import requests
+
+    response = requests.post("http://localhost/api/database/1/table", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={"name": "Danube water levels", "description": "Measurements of the river danube water levels",
+             "columns": [{"name": "datetime", "type": "timestamp", "dfid": 1, "primary_key": False, "null_allowed": True},
+                         {"name": "level", "type": "bigint", "size": 255, "primary_key": False, "null_allowed": True}]})
+    print(response.json()["id"])
+    ```
+
+    Next, provide the dataset metadata that is necessary for import into the table by providing the dataset separator
+    (e.g. `,` or `;` or `\t`). If your dataset has a header line (the first line containing the names of the columns) 
+    set the number of lines to skip to 1. If your dataset contains more lines that should be ignored, set the number of
+    lines accordingly. If your dataset contains quoted values, indicate this by setting the field accordingly.
+
+    If your dataset contains encodings for `NULL` (e.g. `NA`), provide this encoding information. Similar, if it 
+    contains encodings for boolean `true` (e.g. `1` or `YES`), provide this encoding information. For boolean `false`
+    (e.g. `0` or `NO`), provide this information.
+
+    ```python
+    import requests
+
+    response = requests.post("http://localhost/api/database/1/table/1/data/import", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "location": "your_dataset.csv",
+        "separator": ",",
+        "quote": "\"",
+        "skip_lines": 1,
+        "null_element": "NA"
+    })
+    ```
+
+    When you are finished with the table schema definition, the dataset is imported and a table is created. View the
+    table data:
+
+    ```python
+    import requests
+
+    response = requests.get("http://localhost/api/database/1/table/1/data?page=0&size=10", headers={
+        "Authorization": "Bearer " + access_token
+    })
+    ```
+
+## Import Database Dump
+
+A user wants to import a database dump in `.sql` (or in `.sql.gz`) format into DBRepo.
+
+=== "JDBC API"
+
+    First, create a new database as descriped in the [Create Database](#create-database) use-case above. Then, import
+    the database dump `dump.sql` via the `mariadb` client.
+
+    ```bash
+    mariadb -u USERNAME -pYOURPASSWORD db_name < dump.sql
+    ```
+
+    Alternatively, if your database dump is compressed, import the `dump.sql.gz` by piping it through `gunzip`.
+
+    ```bash
+    gunzip < dump.sql.gz | mysql -u root -pYOURPASSWORD db_name
+    ```
+
+    The [Metadata Service](../system-services-metadata) periodically (by default configuration every 60 seconds) checks
+    and adds missing tables and views to the [Metadata Database](../system-databases-metadata), the database dump
+    will be visible afterwards. Currently, date formats for columns with time types (e.g. `DATE`, `TIMESTAMP`) are
+    assumed to match the first date format found for the database image. This may need to be manually specified by the
+    administrator.
+
+    !!! example "Specifying a custom date format"
+
+        In case the pre-defined date formats are not matching the found date format in the database dump, the system
+        administrator needs to add it manually in the [Metadata Database](../system-databases-metadata).
+
+        ```sql
+        INSERT INTO `mdb_images_date` (`iid`, `database_format`, `unix_format`, `example`, `has_time`)
+        VALUES (1, '%d.%c.%Y', 'dd.MM.yyyy', '15.01.2024', false),
+               (1, '%Y-%c-%d %l:%i:%S %p', 'yyyy-MM-dd ll:mm:ss r', '2024-01-15 06:23:12 AM', true);
+        ```
+
+## Import Live Data
+
+A user wants to import live data from e.g. sensor measurements fast and without delay into a table in DBRepo.
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    !!! warning
+
+        Beware that access tokens are short lived (default is 15 minutes) and need to be refreshed regularly with
+        refresh tokens (default is 10 days). See the usage page 
+        on [how to refresh access tokens](../usage-auth/#refresh-access-token).
+
+    Add a data tuple to an already existing table where the user has at least `write-own` access.
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"data":{"column1":"value1","column2":"value2"}}' \
+      http://localhost/api/database/1/table/1/data
+    ```
+
+=== "JDBC API"
+
+    Add a data tuple to an already existing table where the user has at least `write-own` access. Connect to the
+    database via JDBC, you can obtain the connection string in the UI under the database info (c.f. Figure 14).
+
+    <figure markdown>
+    ![JDBC connection information](images/screenshots/database-jdbc.png){ .img-border }
+    <figcaption>Figure 14: JDBC connection information.</figcaption>
+    </figure>
+    
+
+    ```sql
+    INSERT INTO `danube_water_levels` (`datetime`, `level`)
+    VALUES (NOW(), '10')
+    ```
+
+=== "Python"
+
+    Add a data tuple to an already existing table where the user has at least `write-own` access. Connect to the
+    database via AMQP, you can obtain the connection string in the UI under the table info (c.f. Figure 14).
+
+    <figure markdown>
+    ![AMQP connection information](images/screenshots/table-amqp.png){ .img-border }
+    <figcaption>Figure 14: AMQP connection information.</figcaption>
+    </figure>
+
+    ```python
+    import pika
+    import json
+
+    credentials = pika.credentials.PlainCredentials('foo', 'bar')
+    # credentials = pika.credentials.PlainCredentials('', 'ACCESS_TOKEN')
+    parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)
+    connection = pika.BlockingConnection(parameters)
+    channel = connection.channel()
+    channel.basic_publish(exchange='dbrepo',
+        routing_key='dbrepo.test_fiyg.dabube_water_levels',
+        body=json.dumps({"data":{"column1":"value1","column2":"value2"}}))
+    print(" [x] Sent tuple!")
+    connection.close()
+    ```
+
+## Export Subset
+
+A user wants to create a subset and export it as csv file.
+
+=== "UI"
+
+    Login and select a database where you have at least `read` access (this is the case for e.g. self-created 
+    databases). Click the ":material-wrench: CREATE SUBSET" button :material-numeric-1-circle-outline: as seen in 
+    Figure 16.
+
+    <figure markdown>
+    ![Open the create subset form](images/screenshots/export-subset-step-1.png){ .img-border }
+    <figcaption>Figure 16: Open the create subset form.</figcaption>
+    </figure>
+
+    A subset can be created by using our query builder that is visible by default in the "SIMPLE" tab. First, a source 
+    table :material-numeric-1-circle-outline: needs to be selected, then the columns that are part of the subset in
+    :material-numeric-2-circle-outline:. Optionally the subset can be filtered. The subset query (=SQL) is displayed
+    in :material-numeric-3-circle-outline: in Figure 17. 
+
+    Once you are confident the query covers the desired result, click ":material-run: Create".
+
+    <figure markdown>
+    ![Subset query building](images/screenshots/export-subset-step-2.png){ .img-border }
+    <figcaption>Figure 17: Subset query building.</figcaption>
+    </figure>
+
+    Once the subset is created (may take some seconds), the user is presented with the result set in
+    :material-numeric-1-circle-outline:, more information on the subset can be obtained by clicking ":material-run:
+    View" on the top (c.f. Figure 18).
+
+    <figure markdown>
+    ![Subset result set](images/screenshots/export-subset-step-3.png){ .img-border }
+    <figcaption>Figure 18: Subset result set.</figcaption>
+    </figure>
+
+    The subset information page in Figure 19 shows the most important metadata like subset query hash and result hash
+    (e.g. for reproducability) and subset result count. Note that although this subset is stored in the query store
+    already, it is only temporarly stored there for 24 hours (default configuration). 
+
+    After that the subset is deleted from the query store. If you wish to keep the subset (with metadata information), 
+    click ":material-content-save-outline: SAVE" in :material-numeric-1-circle-outline:. The subset can be exported to
+    a csv file by clicking the ":material-download: DATA .CSV" button :material-numeric-2-circle-outline:.
+
+    <figure markdown>
+    ![Subset information](images/screenshots/export-subset-step-4.png){ .img-border }
+    <figcaption>Figure 19: Subset information.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    A subset can be created by passing a SQL query to a database where you have at least `read` access (this is the case
+    for e.g. self-created databases).
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"statement":"SELECT `id`,`datetime`,`level` FROM `danube_water_levels`"}' \
+      http://localhost/api/database/1/query?page=0&sort=10 | jq .id
+    ```
+
+    !!! note
+
+        An optional field `"timestamp":"2024-01-16 23:00:00"` can be provided to execute a query with a system time of
+        2024-01-16 23:00:00 (UTC). Make yourself familiar with the concept
+        of [System Versioned Tables](https://mariadb.com/kb/en/system-versioned-tables/) for more information.
+
+    ```bash
+    curl -sSL \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      http://localhost/api/database/1/query/1 | jq
+    ```
+
+    The subset information shows the most important metadata like subset query hash and result hash (e.g. for 
+    reproducability) and subset result count. Note that although this subset is stored in the query store already, it is
+    only temporarly stored there for 24 hours (default configuration).
+
+    After that the subset is deleted from the query store. If you wish to keep the subset (with metadata information),
+    persist it.
+
+    ```bash
+    curl -sSL \
+      -X PUT \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"persist":true}' \
+      http://localhost/api/database/1/query/1 | jq
+    ```
+
+    The subset can be exported to a `subset_export.csv` file (this also works for non-persisted subsets).
+
+    ```bash
+    curl -sSL \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -H "Accept: text/csv" \
+      -o subset_export.csv \
+      http://localhost/api/database/1/query/1
+    ```
+
+=== "JDBC"
+
+    A subset can be created by passing a SQL query to a database where you have at least `read` access (this is the case
+    for e.g. self-created databases). Connect to the database via JDBC, you can obtain the connection string in the UI
+    under the database info (c.f. Figure 20).
+
+    <figure markdown>
+    ![JDBC connection information](images/screenshots/database-jdbc.png){ .img-border }
+    <figcaption>Figure 20: JDBC connection information.</figcaption>
+    </figure>
+
+    ```sql
+    CALL store_query('SELECT `id`,`datetime`,`level` FROM `danube_water_levels`',
+        NOW(), @subsetId)
+    ```
+
+    Afterwards, you can see the subset in the UI with subset id `@subsetId` and persist it there. Only the administrator
+    can persist the subset in the [Data Database](../system-databases-data) through JDBC by setting the `persisted`
+    column to `true` in the `qs_queries` table.
+
+=== "Python"
+
+    Obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    A subset can be created by passing a SQL query to a database where you have at least `read` access (this is the case
+    for e.g. self-created databases).
+
+    ```python
+    import requests
+
+    response = requests.post("http://localhost/api/database/1/query?page=0&sort=10", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "statement": "SELECT `id`,`datetime`,`level` FROM `danube_water_levels`"
+    })
+    query_id = response.json()["id"]
+    ```
+
+    !!! note
+
+        An optional field `"timestamp":"2024-01-16 23:00:00"` can be provided to execute a query with a system time of
+        2024-01-16 23:00:00 (UTC). Make yourself familiar with the concept
+        of [System Versioned Tables](https://mariadb.com/kb/en/system-versioned-tables/) for more information.
+
+    ```python
+    import requests
+
+    response = requests.get("http://localhost/api/database/1/query/1", headers={
+        "Authorization": "Bearer " + access_token
+    })
+    print(response.json())
+    ```
+
+    The subset information shows the most important metadata like subset query hash and result hash (e.g. for 
+    reproducability) and subset result count. Note that although this subset is stored in the query store already, it is
+    only temporarly stored there for 24 hours (default configuration).
+
+    After that the subset is deleted from the query store. If you wish to keep the subset (with metadata information),
+    persist it.
+
+    ```python
+    import requests
+    
+    response = requests.put("http://localhost/api/database/1/query/1", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "persist": True
+    })
+    ```
+
+    The subset can be exported to a `subset_export.csv` file (this also works for non-persisted subsets).
+
+    ```python
+    import requests
+
+    headers = {
+        "Authorization": "Bearer " + access_token,
+        "Accept": "text/csv"
+    }
+    
+    with requests.Session() as s:
+        response = s.get("http://localhost/api/database/1/query/1",
+                         headers=headers, stream=True)
+        decoded_content = response.content.decode('utf-8')
+        with open("subset_export.csv", "w") as f:
+            f.write(decoded_content)
+    ```
+
+## Assign Database PID
+
+A user wants to assign a persistent identifier to a database owned by them.
+
+=== "UI"
+
+    Login and select a database where you are the owner (this is the case for e.g. self-created databases). Click 
+    the ":material-identifier: GET PID" button :material-numeric-1-circle-outline: as seen in Figure 21.
+
+    <figure markdown>
+    ![Open the get persisent identifier form](images/screenshots/assign-database-pid-step-1.png){ .img-border }
+    <figcaption>Figure 21: Open the get persisent identifier form.</figcaption>
+    </figure>
+
+    First, provide information on the dataset creator(s). Since the [Metadata Service](../system-services-metadata) 
+    automatically resolves external PIDs, the easiest way is to provide the correct mandatory data is by filling the
+    name identifier :material-numeric-1-circle-outline:. The creator type :material-numeric-2-circle-outline:
+    denotes either a natural person or organization. Optionally fill out the given 
+    name :material-numeric-3-circle-outline: and family name :material-numeric-4-circle-outline:, both form the
+    mandatory name :material-numeric-5-circle-outline:. Optionally provide an external affilation
+    identifier :material-numeric-6-circle-outline: which is automatically resolved. Optionally provide an affiliation
+    name :material-numeric-7-circle-outline: in Figure 22. You can change the order of creators with the up/down buttons
+    :material-numeric-8-circle-outline:.
+
+    <figure markdown>
+    ![Identifier creator fields](images/screenshots/assign-database-pid-step-2.png){ .img-border }
+    <figcaption>Figure 22: Identifier creator fields.</figcaption>
+    </figure>
+
+    The identifier needs at least one title in the title field :material-numeric-1-circle-outline: and optionally a
+    title type :material-numeric-2-circle-outline: from the selection and a title 
+    language :material-numeric-3-circle-outline: from the available list of languages. Additional titles can be removed
+    again :material-numeric-4-circle-outline: if they are not needed in Figure 23.
+
+    <figure markdown>
+    ![JDBC connection information](images/screenshots/assign-database-pid-step-3.png){ .img-border }
+    <figcaption>Figure 23: Identifier title fields.</figcaption>
+    </figure>
+
+    The identifier needs at least one description in the description field :material-numeric-1-circle-outline: and 
+    optionally a description type :material-numeric-2-circle-outline: from the selection and a description 
+    language :material-numeric-3-circle-outline:. Fill the dataset publisher information 
+    :material-numeric-4-circle-outline: and publication year :material-numeric-5-circle-outline: and optionally a
+    publication month and publication day in Figure 24.
+
+    <figure markdown>
+    ![Identifier description fields and publishing information](images/screenshots/assign-database-pid-step-4.png){ .img-border }
+    <figcaption>Figure 24: Identifier description fields and publishing information.</figcaption>
+    </figure>
+
+    Optionally reference other PIDs :material-numeric-1-circle-outline:, if you added too much, removing a related
+    identifier can be done by clicking the "REMOVE" button :material-numeric-2-circle-outline:. Add a license from the
+    list :material-numeric-3-circle-outline: fitting to your interests and optionally provide the main language for the
+    identifier :material-numeric-4-circle-outline: (c.f. Figure 25). This helps machines to understand the context of
+    your data.
+
+    <figure markdown>
+    ![Related identifiers, license and language of the identifier](images/screenshots/assign-database-pid-step-5.png){ .img-border }
+    <figcaption>Figure 25: Related identifiers, license and language of the identifier.</figcaption>
+    </figure>
+
+    Optionally add funding information, again the [Metadata Service](../system-services-metadata) 
+    automatically resolves external PIDs, the easiest way is to provide the correct mandatory data is by filling the
+    funder identifier :material-numeric-1-circle-outline: that attempts to get the funder
+    name :material-numeric-2-circle-outline:. If you provide an award number :material-numeric-3-circle-outline: and/or
+    award title :material-numeric-4-circle-outline:, this information will be represented also in human-readable
+    language on the identifier summary page (c.f. Figure 26).
+
+    <figure markdown>
+    ![Identifier funder information](images/screenshots/assign-database-pid-step-6.png){ .img-border }
+    <figcaption>Figure 26: Identifier funder information.</figcaption>
+    </figure>
+
+    Scroll to the top again and click the ":material-content-save-outline: CREATE PID" button to create the PID. The
+    result is displayed in Figure 27.
+
+    <figure markdown>
+    ![Identifier summary page](images/screenshots/assign-database-pid-step-7.png){ .img-border }
+    <figcaption>Figure 27: Identifier summary page.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Create a persistent identifier for a database where you are the owner (this is the case for self-created databases)
+    using the HTTP API:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"type": "database", "titles": [{"title": "Danube water level measurements", "language": "en"},{"title": "Donau Wasserstandsmessungen", "language": "de", "type": "TranslatedTitle"}], "descriptions": [{"description": "This dataset contains hourly measurements of the water level in Vienna from 1983 to 2015", "language": "en", "type": "Abstract"}], "funders": [{ "funder_name": "Austrian Science Fund", "funder_identifier": "https://doi.org/10.13039/100000001", "funder_identifier_type": "Crossref Funder ID", "scheme_uri": "http://doi.org/"}], "licenses": [{"identifier": "CC-BY-4.0", "uri": "https://creativecommons.org/licenses/by/4.0/legalcode"}], "visibility": "everyone", "publisher": "Example University", "creators": [{"firstname": "Martin", "lastname": "Weise", "affiliation": "TU Wien", "creator_name": "Weise, Martin", "name_type": "Personal", "name_identifier": "0000-0003-4216-302X", "name_identifier_scheme": "ORCID", "affiliation_identifier": "https://ror.org/04d836q62", "affiliation_identifier_scheme": "ROR"}], "database_id": 1, "publication_day": 16, "publication_month": 1, "publication_year": 2024, "related_identifiers": [{"value": "10.5334/dsj-2022-004", "type": "DOI", "relation": "Cites"}]}' \
+      http://localhost/api/identifier | jq .id
+    ```
+
+=== "JDBC"
+
+    !!! warning
+
+        Creating a PID directly in the [Metadata Database](../system-databases-metadata) is not recommended! It bypasses
+        validation and creation of external PIDs (e.g. DOI) and may lead to inconstistent data locally compared to
+        external systems (e.g. DataCite Fabrica).
+
+    Create a local PID directly in the [Metadata Database](../system-databases-metadata) by filling the tables in this
+    order (they have foreign key dependencies).
+
+    1. `mdb_identifiers` ... identifier core information
+        * `mdb_identifier_creators` ... identifier creator list
+        * `mdb_identifier_titles` ... identifier creator list
+        * `mdb_identifier_descriptions` ... identifier description list
+        * `mdb_identifier_funders` ... identifier funder list
+        * `mdb_identifier_licenses` ... identifier license list
+        * `mdb_related_identifiers` ... related identifier list
+
+=== "Python"
+
+    Obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    Create a persistent identifier for a database where you are the owner (this is the case for self-created databases)
+    using the HTTP API:
+
+    ```python
+    import requests
+
+    response = requests.post("http://localhost/api/database/1/query/1", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "type": "database",
+        "titles": [
+            {
+                "title": "Danube water level measurements",
+                "language": "en"
+            },
+            {
+                "title": "Donau Wasserstandsmessungen",
+                "language": "de",
+                "type": "TranslatedTitle"
+            }
+        ],
+        "descriptions": [
+            {
+                "description": "This dataset contains hourly measurements of the water level in Vienna from 1983 to 2015",
+                "language": "en",
+                "type": "Abstract"
+            }
+        ],
+        "funders": [
+            {
+                "funder_name": "Austrian Science Fund",
+                "funder_identifier": "https://doi.org/10.13039/100000001",
+                "funder_identifier_type": "Crossref Funder ID",
+                "scheme_uri": "http://doi.org/"
+            }
+        ],
+        "licenses": [
+            {
+                "identifier": "CC-BY-4.0",
+                "uri": "https://creativecommons.org/licenses/by/4.0/legalcode"
+            }
+        ],
+        "visibility": "everyone",
+        "publisher": "Example University",
+        "creators": [
+            {
+                "firstname": "Martin",
+                "lastname": "Weise",
+                "affiliation": "TU Wien",
+                "creator_name": "Weise, Martin",
+                "name_type": "Personal",
+                "name_identifier": "0000-0003-4216-302X",
+                "name_identifier_scheme": "ORCID",
+                "affiliation_identifier": "https://ror.org/04d836q62",
+                "affiliation_identifier_scheme": "ROR"
+            }
+        ],
+        "database_id": 1,
+        "publication_day": 16,
+        "publication_month": 1,
+        "publication_year": 2024,
+        "related_identifiers": [
+            {
+                "value": "10.5334/dsj-2022-004",
+                "type": "DOI",
+                "relation": "Cites"
+            }
+        ]
+    })
+    pid = response.json()["id"]
+    ```
+
+## Private Database &amp; Access
+
+A user wants a public database to be private and only give specific users access.
+
+=== "UI"
+
+    Login and select a database where you are the owner (this is the case for e.g. self-created databases). Click 
+    the "SETTINGS" tab :material-numeric-1-circle-outline: and set the visibility to `Private`
+    :material-numeric-2-circle-outline:, then click the "MODIFY VISIBILITY" button to apply the changes.
+
+    An overview of users who have access to this database is given in :material-numeric-3-circle-outline: and can be
+    changed or revoked at any time by the owner. To give a user account access, click the "GIVE ACCESS" button to open
+    the dialog (c.f. Figure 28).
+
+    <figure markdown>
+    ![Database settings for visibility and access](images/screenshots/private-database-access-step-1.png){ .img-border }
+    <figcaption>Figure 28: Database settings for visibility and access.</figcaption>
+    </figure>
+
+    Give a user from the list access to the database by selecting the qualified username from the 
+    list :material-numeric-1-circle-outline: and the access :material-numeric-2-circle-outline:, e.g. `read` for
+    allowing users to view the private data (c.f. Figure 29).
+
+    <figure markdown>
+    ![Database acccess dialog](images/screenshots/private-database-access-step-2.png){ .img-border }
+    <figcaption>Figure 29: Database acccess dialog.</figcaption>
+    </figure>
+
+=== "Terminal"
+
+    Obtain an access token:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -d 'username=foo&password=bar&grant_type=password&client_id=dbrepo-client&scope=openid&client_secret=MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG' \
+      http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token | jq .access_token
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    To change the visibility of a database where you are the owner (this is the case for self-created databases), send
+    a request to the HTTP API:
+
+    ```bash
+    curl -sSL \
+      -X PUT \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"is_public":true}' \
+      http://localhost/api/database/1/visibility
+    ```
+
+    To give a user (with id `e9bf38a0-a254-4040-87e3-92e0f09e29c8` access to this database (e.g. read access), update
+    their access using the HTTP API:
+
+    ```bash
+    curl -sSL \
+      -X POST \
+      -H "Authorization: Bearer ACCESS_TOKEN" \
+      -d '{"type":"read"}' \
+      http://localhost/api/database/1/access/e9bf38a0-a254-4040-87e3-92e0f09e29c8
+    ```
+
+    In case the user already has access, use the method `PUT`.
+
+=== "JDBC"
+
+    To change the visibility of a database as administrator with direct JDBC access to 
+    the [Metadata Database](../system-databases-metadata), change the visibility directly by executing the SQL-query
+    in the `fda` schema:
+
+    ```sql
+    UPDATE `fda`.`mdb_databases` SET `is_public` = TRUE;
+    ```
+
+    To give a user (with id `e9bf38a0-a254-4040-87e3-92e0f09e29c8` access to this database (e.g. read access), update
+    their access using the JDBC API:
+
+    ```sql
+    INSERT INTO `fda`.`mdb_have_access` (`user_id`, `database_id`, `access_type`)
+        VALUES ('e9bf38a0-a254-4040-87e3-92e0f09e29c8', 1, 'READ');
+    ```
+
+    In case the user already has access, use an `UPDATE` query.
+
+=== "Python"
+
+    Obtain an access token:
+
+    ```python
+    import requests
+    
+    response = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", json={
+        "username": "foo",
+        "password": "bar",
+        "grant_type": "password",
+        "client_id": "dbrepo-client",
+        "scope": "openid",
+        "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
+    })
+    access_token = response.json()["access_token"]
+    print(access_token)
+    ```
+
+    !!! note
+
+        Please note that the `client_secret` is different for your DBRepo instance. This is a default client secret that
+        likely has been replaced. Please contact your DBRepo administrator to get the `client_secret` for your instance.
+        Similar you need to replace `localhost` with your actual DBRepo instance hostname, e.g. `test.dbrepo.tuwien.ac.at`.
+
+    To change the visibility of a database where you are the owner (this is the case for self-created databases), send
+    a request to the HTTP API:
+
+    ```python
+    requests.put("http://localhost/api/database/1/visibility", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "is_public": True
+    })
+    ```
+
+    To give a user (with id `e9bf38a0-a254-4040-87e3-92e0f09e29c8` access to this database (e.g. read access), update
+    their access using the HTTP API:
+
+    ```python
+    requests.post("http://localhost/api/database/1/access/e9bf38a0-a254-4040-87e3-92e0f09e29c8", headers={
+        "Authorization": "Bearer " + access_token
+    }, json={
+        "type": "read"
+    })
+    ```
+
+    In case the user already has access, use the method `put`.
\ No newline at end of file
diff --git a/.docs/usage-storage.md b/.docs/usage-storage.md
index 214698710e8086ae1dd40ada21561cd98b1127ff..d9fc967f28e8814619d5fa3396c4203b0e3997ab 100644
--- a/.docs/usage-storage.md
+++ b/.docs/usage-storage.md
@@ -4,10 +4,21 @@ author: Martin Weise
 
 # Storage Service
 
+Configure the credentials to access the S3 endpoint:
+
+```console
+$ aws configure \
+    --endpoint-url http://localhost:9000
+AWS Access Key ID [None]: seaweedfsadmin
+AWS Secret Access Key [None]: seaweedfsadmin
+Default region name [None]: 
+Default output format [None]:
+```
+
 Upload a CSV-file into the `dbrepo-upload` bucket with the AWS CLI:
 
 ```console
-$ aws --endpoint-url http://<hostname>:9000 \
+$ aws --endpoint-url http://localhost:9000 \
     s3 \
     cp /path/to/file.csv \
     s3://dbrepo-upload/
@@ -17,7 +28,7 @@ upload: /path/to/file.csv to s3://dbrepo-upload/file.csv
 You can list the buckets:
 
 ```console
-$ aws --endpoint-url http://<hostname>:9000 \
+$ aws --endpoint-url http://localhost:9000 \
     s3 \
     ls
 2023-12-03 16:23:15 dbrepo-download
@@ -27,7 +38,7 @@ $ aws --endpoint-url http://<hostname>:9000 \
 And list the files in the bucket `dbrepo-upload` with:
 
 ```console
-$ aws --endpoint-url http://<hostname>:9000 \
+$ aws --endpoint-url http://localhost:9000 \
     s3 \
     ls \
     dbrepo-upload
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6ebd3e844931f0c6f23759d55d62c92e8bfb9bd4..5449795b63878b147639efb194a572a548f9fb2a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -119,7 +119,7 @@ test-analyse-service:
   script:
     - "pip install pipenv"
     - "pipenv install gunicorn && pipenv install --dev --system --deploy"
-    - "cd ./dbrepo-analyse-service/ && coverage run -m pytest test/test_determine_dt.py test/test_determine_pk.py --junitxml=report.xml && coverage html && coverage report > ./coverage.txt"
+    - "cd ./dbrepo-analyse-service/ && coverage run -m pytest test/test_determine_dt.py test/test_determine_pk.py test/test_determine_stats.py --junitxml=report.xml && coverage html && coverage report > ./coverage.txt"
     - "cat ./coverage.txt | grep -o 'TOTAL[^%]*%'"
   artifacts:
     when: always
@@ -156,7 +156,7 @@ scan-analyse-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-analyse-service-report.json docker.io/dbrepo/analyse-service:latest
@@ -176,7 +176,7 @@ scan-authentication-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-authentication-service-report.json docker.io/dbrepo/authentication-service:latest
@@ -196,7 +196,7 @@ scan-broker-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-broker-service-report.json docker.io/dbrepo/broker-service:latest
@@ -216,7 +216,7 @@ scan-gateway-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-gateway-service-report.json docker.io/nginx:1.25.0-alpine-slim
@@ -236,7 +236,7 @@ scan-metadata-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-metadata-service-report.json docker.io/dbrepo/metadata-service:latest
@@ -256,7 +256,7 @@ scan-data-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-data-service-report.json docker.io/dbrepo/data-service:latest
@@ -276,7 +276,7 @@ scan-search-db:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-db-report.json docker.io/dbrepo/search-db:latest
@@ -296,7 +296,7 @@ scan-search-dashboard:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-dashboard-report.json docker.io/opensearchproject/opensearch-dashboards:2.10.0
@@ -316,7 +316,7 @@ scan-search-db-init:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-db-init-report.json docker.io/dbrepo/search-db-init:latest
@@ -336,7 +336,7 @@ scan-data-db:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-data-db-report.json docker.io/bitnami/mariadb:11.2.2-debian-11-r0
@@ -356,7 +356,7 @@ scan-metadata-db:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-metadata-db-report.json docker.io/dbrepo/metadata-db:latest
@@ -376,7 +376,7 @@ scan-ui:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-ui-report.json docker.io/dbrepo/ui:latest
@@ -396,7 +396,7 @@ scan-storage-service:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-storage-service-report.json docker.io/chrislusf/seaweedfs:3.59
@@ -416,7 +416,7 @@ scan-storage-service-init:
   stage: scan
   only:
     refs:
-      - dev
+      - master
   allow_failure: true
   script:
     - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-storage-service-init-report.json docker.io/dbrepo/storage-service-init:latest
@@ -441,7 +441,7 @@ release-latest:
     - test-frontend
   only:
     refs:
-      - dev
+      - master
   before_script:
     - echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY_URL
     - echo "$CI_REGISTRY2_PASSWORD" | docker login --username "$CI_REGISTRY2_USER" --password-stdin $CI_REGISTRY2_URL
@@ -467,7 +467,7 @@ release-1.3:
   script:
     - "ifconfig eth0 mtu 1450 up"
     - "apk add make"
-    - "TAG=1.3.9 make release"
+    - "TAG=1.3.0 make release"
 
 release-1.4:
   stage: release
@@ -493,12 +493,12 @@ build-api-latest:
   image: docker.io/alpine:3.18
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
     - apk add bash git
-    - git fetch && git checkout dev
+    - git fetch && git checkout master
     - bash .docs/.swagger/swagger-site.sh
     - mkdir -p ./swagger/latest
     - cp -r ./site/* ./swagger/latest/
@@ -516,22 +516,22 @@ build-api-1.3:
   image: docker.io/alpine:3.18
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
     - apk add bash git maven
     - git fetch && git checkout release-v1.3
     - bash .docs/.swagger/generate.sh
-    - mkdir -p ./swagger/1.3.9
-    - cp -r ./site/* ./swagger/1.3.9/
+    - mkdir -p ./swagger/1.3.0
+    - cp -r ./site/* ./swagger/1.3.0/
   cache:
     paths:
-      - ./swagger/1.3.9
+      - ./swagger/1.3.0
   artifacts:
     when: always
     paths:
-      - ./swagger/1.3.9
+      - ./swagger/1.3.0
     expire_in: 1 days
 
 build-api-1.4:
@@ -539,7 +539,7 @@ build-api-1.4:
   image: docker.io/alpine:3.18
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
@@ -562,7 +562,7 @@ docs-registry:
   image: docker.io/python:3.9-slim
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
@@ -586,12 +586,12 @@ docs-latest:
     - build-api-1.4
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
     - apt-get update && apt-get install -y git make sed
-    - git fetch && git checkout dev
+    - git fetch && git checkout master
     - pip install -r ./requirements.txt
     - mkdir -p ./final
     - find ./.docs -type f -exec sed -i -e "s/\$TAG/latest/g" {} \;
@@ -616,16 +616,17 @@ docs-1.3:
     - build-api-1.3
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
-    - apt-get update && apt-get install -y git make
+    - apt-get update && apt-get install -y git make wget
     - git fetch && git checkout release-v1.3
     - pip install -r ./.docs/requirements.txt
+    - wget https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/.docs/overrides/main.html -O .docs/overrides/main.html -q
     - mkdir -p ./final
-    - mkdocs build && cp -r ./site ./final/1.3.9
-    - cp -r ./swagger/1.3.9 ./final/1.3.9/swagger
+    - mkdocs build && cp -r ./site ./final/1.3.0
+    - cp -r ./swagger/1.3.0 ./final/1.3.0/swagger
   cache:
     paths:
       - ./final
@@ -644,13 +645,14 @@ docs-1.4:
     - build-api-1.4
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
-    - apt-get update && apt-get install -y git make sed
+    - apt-get update && apt-get install -y git make sed wget
     - git fetch && git checkout release-v1.4
     - pip install -r ./.docs/requirements.txt
+    - wget https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/.docs/overrides/main.html -O .docs/overrides/main.html -q
     - mkdir -p ./final
     - find ./.docs -type f -exec sed -i -e "s/\$TAG/${VERSION}/g" {} \;
     - mkdocs build && cp -r ./site ./final/${VERSION}
@@ -673,7 +675,7 @@ release-docs:
     - docs-1.4
   only:
     refs:
-      - dev
+      - master
       - release-v1.3
       - release-v1.4
   script:
diff --git a/.gitlab/branching-strategy.png b/.gitlab/branching-strategy.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0972fc50b2e0c432a068014474441667245fec0
Binary files /dev/null and b/.gitlab/branching-strategy.png differ
diff --git a/.java-stubs/.swagger-codegen/VERSION b/.java-stubs/.swagger-codegen/VERSION
deleted file mode 100644
index 10bbf276ee45aaec75c7b2ada3ff71d798f89fd9..0000000000000000000000000000000000000000
--- a/.java-stubs/.swagger-codegen/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-3.0.34
\ No newline at end of file
diff --git a/.java-stubs/README.md b/.java-stubs/README.md
deleted file mode 100644
index 0b0e00011dd52dcd8742acb7dfb95ed704aa0f8f..0000000000000000000000000000000000000000
--- a/.java-stubs/README.md
+++ /dev/null
@@ -1,251 +0,0 @@
-# swagger-java-client
-
-Database Repository Container Service API
-- API version: 1.1.0-alpha
-  - Build date: 2023-02-12T11:48:18.502846+01:00[Europe/Vienna]
-
-Service that manages the containers
-
-
-*Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen)*
-
-
-## Requirements
-
-Building the API client library requires:
-1. Java 1.7+
-2. Maven/Gradle
-
-## Installation
-
-To install the API client library to your local Maven repository, simply execute:
-
-```shell
-mvn clean install
-```
-
-To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
-
-```shell
-mvn clean deploy
-```
-
-Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
-
-### Maven users
-
-Add this dependency to your project's POM:
-
-```xml
-<dependency>
-  <groupId>io.swagger</groupId>
-  <artifactId>swagger-java-client</artifactId>
-  <version>1.0.0</version>
-  <scope>compile</scope>
-</dependency>
-```
-
-### Gradle users
-
-Add this dependency to your project's build file:
-
-```groovy
-compile "io.swagger:swagger-java-client:1.0.0"
-```
-
-### Others
-
-At first generate the JAR by executing:
-
-```shell
-mvn clean package
-```
-
-Then manually install the following JARs:
-
-* `target/swagger-java-client-1.0.0.jar`
-* `target/lib/*.jar`
-
-## Getting Started
-
-Please follow the [installation](#installation) instruction and execute the following Java code:
-
-```java
-import io.swagger.client.*;
-import io.swagger.client.auth.*;
-import io.swagger.client.model.*;
-import io.swagger.client.api.ContainerEndpointApi;
-
-import java.io.File;
-import java.util.*;
-
-public class ContainerEndpointApiExample {
-
-    public static void main(String[] args) {
-        ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-        ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-        ContainerCreateRequestDto body = new ContainerCreateRequestDto(); // ContainerCreateRequestDto | 
-        try {
-            ContainerBriefDto result = apiInstance.create1(body);
-            System.out.println(result);
-        } catch (ApiException e) {
-            System.err.println("Exception when calling ContainerEndpointApi#create1");
-            e.printStackTrace();
-        }
-    }
-}
-import io.swagger.client.*;
-import io.swagger.client.auth.*;
-import io.swagger.client.model.*;
-import io.swagger.client.api.ContainerEndpointApi;
-
-import java.io.File;
-import java.util.*;
-
-public class ContainerEndpointApiExample {
-
-    public static void main(String[] args) {
-        ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-        ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-        Long id = 789L; // Long | 
-        try {
-            Object result = apiInstance.delete1(id);
-            System.out.println(result);
-        } catch (ApiException e) {
-            System.err.println("Exception when calling ContainerEndpointApi#delete1");
-            e.printStackTrace();
-        }
-    }
-}
-import io.swagger.client.*;
-import io.swagger.client.auth.*;
-import io.swagger.client.model.*;
-import io.swagger.client.api.ContainerEndpointApi;
-
-import java.io.File;
-import java.util.*;
-
-public class ContainerEndpointApiExample {
-
-    public static void main(String[] args) {
-        
-        ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-        try {
-            List<ContainerBriefDto> result = apiInstance.findAll1();
-            System.out.println(result);
-        } catch (ApiException e) {
-            System.err.println("Exception when calling ContainerEndpointApi#findAll1");
-            e.printStackTrace();
-        }
-    }
-}
-import io.swagger.client.*;
-import io.swagger.client.auth.*;
-import io.swagger.client.model.*;
-import io.swagger.client.api.ContainerEndpointApi;
-
-import java.io.File;
-import java.util.*;
-
-public class ContainerEndpointApiExample {
-
-    public static void main(String[] args) {
-        
-        ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-        Long id = 789L; // Long | 
-        try {
-            ContainerDto result = apiInstance.findById1(id);
-            System.out.println(result);
-        } catch (ApiException e) {
-            System.err.println("Exception when calling ContainerEndpointApi#findById1");
-            e.printStackTrace();
-        }
-    }
-}
-import io.swagger.client.*;
-import io.swagger.client.auth.*;
-import io.swagger.client.model.*;
-import io.swagger.client.api.ContainerEndpointApi;
-
-import java.io.File;
-import java.util.*;
-
-public class ContainerEndpointApiExample {
-
-    public static void main(String[] args) {
-        ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-        ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-        ContainerChangeDto body = new ContainerChangeDto(); // ContainerChangeDto | 
-        Long id = 789L; // Long | 
-        try {
-            ContainerBriefDto result = apiInstance.modify(body, id);
-            System.out.println(result);
-        } catch (ApiException e) {
-            System.err.println("Exception when calling ContainerEndpointApi#modify");
-            e.printStackTrace();
-        }
-    }
-}
-```
-
-## Documentation for API Endpoints
-
-All URIs are relative to *http://localhost:9091*
-
-Class | Method | HTTP request | Description
------------- | ------------- | ------------- | -------------
-*ContainerEndpointApi* | [**create1**](docs/ContainerEndpointApi.md#create1) | **POST** /api/container | Create container
-*ContainerEndpointApi* | [**delete1**](docs/ContainerEndpointApi.md#delete1) | **DELETE** /api/container/{id} | Delete some container
-*ContainerEndpointApi* | [**findAll1**](docs/ContainerEndpointApi.md#findAll1) | **GET** /api/container | Find all containers
-*ContainerEndpointApi* | [**findById1**](docs/ContainerEndpointApi.md#findById1) | **GET** /api/container/{id} | Find some container
-*ContainerEndpointApi* | [**modify**](docs/ContainerEndpointApi.md#modify) | **PUT** /api/container/{id} | Modify some container
-*ImageEndpointApi* | [**create**](docs/ImageEndpointApi.md#create) | **POST** /api/image | Create image
-*ImageEndpointApi* | [**delete**](docs/ImageEndpointApi.md#delete) | **DELETE** /api/image/{id} | Delete some image
-*ImageEndpointApi* | [**findAll**](docs/ImageEndpointApi.md#findAll) | **GET** /api/image | Find all images
-*ImageEndpointApi* | [**findById**](docs/ImageEndpointApi.md#findById) | **GET** /api/image/{id} | Find some image
-*ImageEndpointApi* | [**update**](docs/ImageEndpointApi.md#update) | **PUT** /api/image/{id} | Update some image
-
-## Documentation for Models
-
- - [ApiErrorDto](docs/ApiErrorDto.md)
- - [ContainerBriefDto](docs/ContainerBriefDto.md)
- - [ContainerChangeDto](docs/ContainerChangeDto.md)
- - [ContainerCreateRequestDto](docs/ContainerCreateRequestDto.md)
- - [ContainerDto](docs/ContainerDto.md)
- - [CreatorDto](docs/CreatorDto.md)
- - [DatabaseAccessDto](docs/DatabaseAccessDto.md)
- - [DatabaseDto](docs/DatabaseDto.md)
- - [GrantedAuthorityDto](docs/GrantedAuthorityDto.md)
- - [IdentifierDto](docs/IdentifierDto.md)
- - [ImageBriefDto](docs/ImageBriefDto.md)
- - [ImageChangeDto](docs/ImageChangeDto.md)
- - [ImageCreateDto](docs/ImageCreateDto.md)
- - [ImageDateDto](docs/ImageDateDto.md)
- - [ImageDto](docs/ImageDto.md)
- - [ImageEnvItemDto](docs/ImageEnvItemDto.md)
- - [LicenseDto](docs/LicenseDto.md)
- - [RelatedIdentifierDto](docs/RelatedIdentifierDto.md)
- - [TableBriefDto](docs/TableBriefDto.md)
- - [UserBriefDto](docs/UserBriefDto.md)
- - [UserDto](docs/UserDto.md)
-
-## Documentation for Authorization
-
-Authentication schemes defined for the API:
-### bearerAuth
-
-
-
-## Recommendation
-
-It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
-
-## Author
-
-andreas.rauber@tuwien.ac.at
diff --git a/.java-stubs/docs/ApiErrorDto.md b/.java-stubs/docs/ApiErrorDto.md
deleted file mode 100644
index 36cd96dbc1e024ed83d849ca174198be8a44438e..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ApiErrorDto.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# ApiErrorDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**status** | [**StatusEnum**](#StatusEnum) |  | 
-**message** | **String** |  | 
-**code** | **String** |  | 
-
-<a name="StatusEnum"></a>
-## Enum: StatusEnum
-Name | Value
----- | -----
-_100_CONTINUE | &quot;100 CONTINUE&quot;
-_101_SWITCHING_PROTOCOLS | &quot;101 SWITCHING_PROTOCOLS&quot;
-_102_PROCESSING | &quot;102 PROCESSING&quot;
-_103_CHECKPOINT | &quot;103 CHECKPOINT&quot;
-_200_OK | &quot;200 OK&quot;
-_201_CREATED | &quot;201 CREATED&quot;
-_202_ACCEPTED | &quot;202 ACCEPTED&quot;
-_203_NON_AUTHORITATIVE_INFORMATION | &quot;203 NON_AUTHORITATIVE_INFORMATION&quot;
-_204_NO_CONTENT | &quot;204 NO_CONTENT&quot;
-_205_RESET_CONTENT | &quot;205 RESET_CONTENT&quot;
-_206_PARTIAL_CONTENT | &quot;206 PARTIAL_CONTENT&quot;
-_207_MULTI_STATUS | &quot;207 MULTI_STATUS&quot;
-_208_ALREADY_REPORTED | &quot;208 ALREADY_REPORTED&quot;
-_226_IM_USED | &quot;226 IM_USED&quot;
-_300_MULTIPLE_CHOICES | &quot;300 MULTIPLE_CHOICES&quot;
-_301_MOVED_PERMANENTLY | &quot;301 MOVED_PERMANENTLY&quot;
-_302_FOUND | &quot;302 FOUND&quot;
-_302_MOVED_TEMPORARILY | &quot;302 MOVED_TEMPORARILY&quot;
-_303_SEE_OTHER | &quot;303 SEE_OTHER&quot;
-_304_NOT_MODIFIED | &quot;304 NOT_MODIFIED&quot;
-_305_USE_PROXY | &quot;305 USE_PROXY&quot;
-_307_TEMPORARY_REDIRECT | &quot;307 TEMPORARY_REDIRECT&quot;
-_308_PERMANENT_REDIRECT | &quot;308 PERMANENT_REDIRECT&quot;
-_400_BAD_REQUEST | &quot;400 BAD_REQUEST&quot;
-_401_UNAUTHORIZED | &quot;401 UNAUTHORIZED&quot;
-_402_PAYMENT_REQUIRED | &quot;402 PAYMENT_REQUIRED&quot;
-_403_FORBIDDEN | &quot;403 FORBIDDEN&quot;
-_404_NOT_FOUND | &quot;404 NOT_FOUND&quot;
-_405_METHOD_NOT_ALLOWED | &quot;405 METHOD_NOT_ALLOWED&quot;
-_406_NOT_ACCEPTABLE | &quot;406 NOT_ACCEPTABLE&quot;
-_407_PROXY_AUTHENTICATION_REQUIRED | &quot;407 PROXY_AUTHENTICATION_REQUIRED&quot;
-_408_REQUEST_TIMEOUT | &quot;408 REQUEST_TIMEOUT&quot;
-_409_CONFLICT | &quot;409 CONFLICT&quot;
-_410_GONE | &quot;410 GONE&quot;
-_411_LENGTH_REQUIRED | &quot;411 LENGTH_REQUIRED&quot;
-_412_PRECONDITION_FAILED | &quot;412 PRECONDITION_FAILED&quot;
-_413_PAYLOAD_TOO_LARGE | &quot;413 PAYLOAD_TOO_LARGE&quot;
-_413_REQUEST_ENTITY_TOO_LARGE | &quot;413 REQUEST_ENTITY_TOO_LARGE&quot;
-_414_URI_TOO_LONG | &quot;414 URI_TOO_LONG&quot;
-_414_REQUEST_URI_TOO_LONG | &quot;414 REQUEST_URI_TOO_LONG&quot;
-_415_UNSUPPORTED_MEDIA_TYPE | &quot;415 UNSUPPORTED_MEDIA_TYPE&quot;
-_416_REQUESTED_RANGE_NOT_SATISFIABLE | &quot;416 REQUESTED_RANGE_NOT_SATISFIABLE&quot;
-_417_EXPECTATION_FAILED | &quot;417 EXPECTATION_FAILED&quot;
-_418_I_AM_A_TEAPOT | &quot;418 I_AM_A_TEAPOT&quot;
-_419_INSUFFICIENT_SPACE_ON_RESOURCE | &quot;419 INSUFFICIENT_SPACE_ON_RESOURCE&quot;
-_420_METHOD_FAILURE | &quot;420 METHOD_FAILURE&quot;
-_421_DESTINATION_LOCKED | &quot;421 DESTINATION_LOCKED&quot;
-_422_UNPROCESSABLE_ENTITY | &quot;422 UNPROCESSABLE_ENTITY&quot;
-_423_LOCKED | &quot;423 LOCKED&quot;
-_424_FAILED_DEPENDENCY | &quot;424 FAILED_DEPENDENCY&quot;
-_425_TOO_EARLY | &quot;425 TOO_EARLY&quot;
-_426_UPGRADE_REQUIRED | &quot;426 UPGRADE_REQUIRED&quot;
-_428_PRECONDITION_REQUIRED | &quot;428 PRECONDITION_REQUIRED&quot;
-_429_TOO_MANY_REQUESTS | &quot;429 TOO_MANY_REQUESTS&quot;
-_431_REQUEST_HEADER_FIELDS_TOO_LARGE | &quot;431 REQUEST_HEADER_FIELDS_TOO_LARGE&quot;
-_451_UNAVAILABLE_FOR_LEGAL_REASONS | &quot;451 UNAVAILABLE_FOR_LEGAL_REASONS&quot;
-_500_INTERNAL_SERVER_ERROR | &quot;500 INTERNAL_SERVER_ERROR&quot;
-_501_NOT_IMPLEMENTED | &quot;501 NOT_IMPLEMENTED&quot;
-_502_BAD_GATEWAY | &quot;502 BAD_GATEWAY&quot;
-_503_SERVICE_UNAVAILABLE | &quot;503 SERVICE_UNAVAILABLE&quot;
-_504_GATEWAY_TIMEOUT | &quot;504 GATEWAY_TIMEOUT&quot;
-_505_HTTP_VERSION_NOT_SUPPORTED | &quot;505 HTTP_VERSION_NOT_SUPPORTED&quot;
-_506_VARIANT_ALSO_NEGOTIATES | &quot;506 VARIANT_ALSO_NEGOTIATES&quot;
-_507_INSUFFICIENT_STORAGE | &quot;507 INSUFFICIENT_STORAGE&quot;
-_508_LOOP_DETECTED | &quot;508 LOOP_DETECTED&quot;
-_509_BANDWIDTH_LIMIT_EXCEEDED | &quot;509 BANDWIDTH_LIMIT_EXCEEDED&quot;
-_510_NOT_EXTENDED | &quot;510 NOT_EXTENDED&quot;
-_511_NETWORK_AUTHENTICATION_REQUIRED | &quot;511 NETWORK_AUTHENTICATION_REQUIRED&quot;
diff --git a/.java-stubs/docs/ContainerBriefDto.md b/.java-stubs/docs/ContainerBriefDto.md
deleted file mode 100644
index 0885b79e26d5b5a5c9253c15c8ecc84311242f4e..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ContainerBriefDto.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# ContainerBriefDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**hash** | **String** |  | 
-**name** | **String** |  | 
-**creator** | [**UserBriefDto**](UserBriefDto.md) |  |  [optional]
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-**internalName** | **String** |  | 
diff --git a/.java-stubs/docs/ContainerChangeDto.md b/.java-stubs/docs/ContainerChangeDto.md
deleted file mode 100644
index d7ae58d3f0ada6749fea8d07039d4c7508a1f590..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ContainerChangeDto.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# ContainerChangeDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**action** | [**ActionEnum**](#ActionEnum) |  | 
-
-<a name="ActionEnum"></a>
-## Enum: ActionEnum
-Name | Value
----- | -----
-START | &quot;start&quot;
-STOP | &quot;stop&quot;
diff --git a/.java-stubs/docs/ContainerCreateRequestDto.md b/.java-stubs/docs/ContainerCreateRequestDto.md
deleted file mode 100644
index ed49414a1ed65193c7224ca2dd4b6958fe535d91..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ContainerCreateRequestDto.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# ContainerCreateRequestDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**name** | **String** |  | 
-**repository** | **String** |  | 
-**tag** | **String** |  | 
diff --git a/.java-stubs/docs/ContainerDto.md b/.java-stubs/docs/ContainerDto.md
deleted file mode 100644
index 9018045b21053183774813a2e42dd21a4e1028b6..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ContainerDto.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# ContainerDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**hash** | **String** |  | 
-**name** | **String** |  | 
-**state** | [**StateEnum**](#StateEnum) |  |  [optional]
-**database** | [**DatabaseDto**](DatabaseDto.md) |  |  [optional]
-**image** | [**ImageBriefDto**](ImageBriefDto.md) |  |  [optional]
-**port** | **Integer** |  |  [optional]
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  | 
-**internalName** | **String** |  | 
-**ipAddress** | **String** |  |  [optional]
-
-<a name="StateEnum"></a>
-## Enum: StateEnum
-Name | Value
----- | -----
-CREATED | &quot;created&quot;
-RESTARTING | &quot;restarting&quot;
-RUNNING | &quot;running&quot;
-PAUSED | &quot;paused&quot;
-EXITED | &quot;exited&quot;
-DEAD | &quot;dead&quot;
diff --git a/.java-stubs/docs/ContainerEndpointApi.md b/.java-stubs/docs/ContainerEndpointApi.md
deleted file mode 100644
index f618c78f22d5c08508301cd5f43f3555c7129332..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ContainerEndpointApi.md
+++ /dev/null
@@ -1,240 +0,0 @@
-# ContainerEndpointApi
-
-All URIs are relative to *http://localhost:9091*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**create1**](ContainerEndpointApi.md#create1) | **POST** /api/container | Create container
-[**delete1**](ContainerEndpointApi.md#delete1) | **DELETE** /api/container/{id} | Delete some container
-[**findAll1**](ContainerEndpointApi.md#findAll1) | **GET** /api/container | Find all containers
-[**findById1**](ContainerEndpointApi.md#findById1) | **GET** /api/container/{id} | Find some container
-[**modify**](ContainerEndpointApi.md#modify) | **PUT** /api/container/{id} | Modify some container
-
-<a name="create1"></a>
-# **create1**
-> ContainerBriefDto create1(body)
-
-Create container
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ContainerEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-ContainerCreateRequestDto body = new ContainerCreateRequestDto(); // ContainerCreateRequestDto | 
-try {
-    ContainerBriefDto result = apiInstance.create1(body);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ContainerEndpointApi#create1");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **body** | [**ContainerCreateRequestDto**](ContainerCreateRequestDto.md)|  |
-
-### Return type
-
-[**ContainerBriefDto**](ContainerBriefDto.md)
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: */*
-
-<a name="delete1"></a>
-# **delete1**
-> Object delete1(id)
-
-Delete some container
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ContainerEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-Long id = 789L; // Long | 
-try {
-    Object result = apiInstance.delete1(id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ContainerEndpointApi#delete1");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **id** | **Long**|  |
-
-### Return type
-
-**Object**
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="findAll1"></a>
-# **findAll1**
-> List&lt;ContainerBriefDto&gt; findAll1()
-
-Find all containers
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiException;
-//import io.swagger.client.api.ContainerEndpointApi;
-
-
-ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-try {
-    List<ContainerBriefDto> result = apiInstance.findAll1();
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ContainerEndpointApi#findAll1");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-This endpoint does not need any parameter.
-
-### Return type
-
-[**List&lt;ContainerBriefDto&gt;**](ContainerBriefDto.md)
-
-### Authorization
-
-No authorization required
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="findById1"></a>
-# **findById1**
-> ContainerDto findById1(id)
-
-Find some container
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiException;
-//import io.swagger.client.api.ContainerEndpointApi;
-
-
-ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-Long id = 789L; // Long | 
-try {
-    ContainerDto result = apiInstance.findById1(id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ContainerEndpointApi#findById1");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **id** | **Long**|  |
-
-### Return type
-
-[**ContainerDto**](ContainerDto.md)
-
-### Authorization
-
-No authorization required
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="modify"></a>
-# **modify**
-> ContainerBriefDto modify(body, id)
-
-Modify some container
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ContainerEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ContainerEndpointApi apiInstance = new ContainerEndpointApi();
-ContainerChangeDto body = new ContainerChangeDto(); // ContainerChangeDto | 
-Long id = 789L; // Long | 
-try {
-    ContainerBriefDto result = apiInstance.modify(body, id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ContainerEndpointApi#modify");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **body** | [**ContainerChangeDto**](ContainerChangeDto.md)|  |
- **id** | **Long**|  |
-
-### Return type
-
-[**ContainerBriefDto**](ContainerBriefDto.md)
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: */*
-
diff --git a/.java-stubs/docs/CreatorDto.md b/.java-stubs/docs/CreatorDto.md
deleted file mode 100644
index 16f35d183bd806584ae13288a3bab015eaafa8d1..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/CreatorDto.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# CreatorDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**firstname** | **String** |  | 
-**lastname** | **String** |  | 
-**affiliation** | **String** |  |  [optional]
-**orcid** | **String** |  |  [optional]
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-**lastModified** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
diff --git a/.java-stubs/docs/DatabaseAccessDto.md b/.java-stubs/docs/DatabaseAccessDto.md
deleted file mode 100644
index 23b4d38550d18982b0aed40d0ea2ef3f1668967d..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/DatabaseAccessDto.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# DatabaseAccessDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**user** | [**UserDto**](UserDto.md) |  | 
-**type** | [**TypeEnum**](#TypeEnum) |  | 
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-
-<a name="TypeEnum"></a>
-## Enum: TypeEnum
-Name | Value
----- | -----
-READ | &quot;read&quot;
-WRITE_OWN | &quot;write_own&quot;
-WRITE_ALL | &quot;write_all&quot;
diff --git a/.java-stubs/docs/DatabaseDto.md b/.java-stubs/docs/DatabaseDto.md
deleted file mode 100644
index 3563e2692d0b40dc95483e545a9ca7ac98af2ad7..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/DatabaseDto.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# DatabaseDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**name** | **String** |  | 
-**creator** | [**UserBriefDto**](UserBriefDto.md) |  | 
-**identifier** | [**IdentifierDto**](IdentifierDto.md) |  |  [optional]
-**description** | **String** |  |  [optional]
-**tables** | [**List&lt;TableBriefDto&gt;**](TableBriefDto.md) |  |  [optional]
-**image** | [**ImageDto**](ImageDto.md) |  |  [optional]
-**container** | [**ContainerDto**](ContainerDto.md) |  |  [optional]
-**accesses** | [**List&lt;DatabaseAccessDto&gt;**](DatabaseAccessDto.md) |  |  [optional]
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-**exchangeName** | **String** |  | 
-**internalName** | **String** |  | 
-**isPublic** | **Boolean** |  |  [optional]
diff --git a/.java-stubs/docs/GrantedAuthorityDto.md b/.java-stubs/docs/GrantedAuthorityDto.md
deleted file mode 100644
index 416b6b3ff3c27ae4fae207ca280096d177764341..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/GrantedAuthorityDto.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# GrantedAuthorityDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**authority** | **String** |  |  [optional]
diff --git a/.java-stubs/docs/IdentifierDto.md b/.java-stubs/docs/IdentifierDto.md
deleted file mode 100644
index 5535a8024d2469836effd4d91bf89a9b7712e850..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/IdentifierDto.md
+++ /dev/null
@@ -1,234 +0,0 @@
-# IdentifierDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  |  [optional]
-**type** | [**TypeEnum**](#TypeEnum) |  | 
-**title** | **String** |  | 
-**description** | **String** |  |  [optional]
-**query** | **String** |  | 
-**execution** | [**OffsetDateTime**](OffsetDateTime.md) |  | 
-**visibility** | [**VisibilityEnum**](#VisibilityEnum) |  | 
-**doi** | **String** |  |  [optional]
-**publisher** | **String** |  |  [optional]
-**language** | [**LanguageEnum**](#LanguageEnum) |  |  [optional]
-**license** | [**LicenseDto**](LicenseDto.md) |  |  [optional]
-**creators** | [**List&lt;CreatorDto&gt;**](CreatorDto.md) |  | 
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-**containerId** | **Long** |  | 
-**databaseId** | **Long** |  | 
-**queryId** | **Long** |  |  [optional]
-**queryNormalized** | **String** |  | 
-**related** | [**List&lt;RelatedIdentifierDto&gt;**](RelatedIdentifierDto.md) |  |  [optional]
-**queryHash** | **String** | query hash in sha512 | 
-**resultHash** | **String** |  | 
-**resultNumber** | **Long** |  | 
-**publicationDay** | **Integer** |  |  [optional]
-**publicationMonth** | **Integer** |  |  [optional]
-**publicationYear** | **Integer** |  | 
-**lastModified** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-
-<a name="TypeEnum"></a>
-## Enum: TypeEnum
-Name | Value
----- | -----
-DATABASE | &quot;database&quot;
-SUBSET | &quot;subset&quot;
-
-<a name="VisibilityEnum"></a>
-## Enum: VisibilityEnum
-Name | Value
----- | -----
-EVERYONE | &quot;everyone&quot;
-TRUSTED | &quot;trusted&quot;
-SELF | &quot;self&quot;
-
-<a name="LanguageEnum"></a>
-## Enum: LanguageEnum
-Name | Value
----- | -----
-AB | &quot;ab&quot;
-AA | &quot;aa&quot;
-AF | &quot;af&quot;
-AK | &quot;ak&quot;
-SQ | &quot;sq&quot;
-AM | &quot;am&quot;
-AR | &quot;ar&quot;
-AN | &quot;an&quot;
-HY | &quot;hy&quot;
-AS | &quot;as&quot;
-AV | &quot;av&quot;
-AE | &quot;ae&quot;
-AY | &quot;ay&quot;
-AZ | &quot;az&quot;
-BM | &quot;bm&quot;
-BA | &quot;ba&quot;
-EU | &quot;eu&quot;
-BE | &quot;be&quot;
-BN | &quot;bn&quot;
-BH | &quot;bh&quot;
-BI | &quot;bi&quot;
-BS | &quot;bs&quot;
-BR | &quot;br&quot;
-BG | &quot;bg&quot;
-MY | &quot;my&quot;
-CA | &quot;ca&quot;
-KM | &quot;km&quot;
-CH | &quot;ch&quot;
-CE | &quot;ce&quot;
-NY | &quot;ny&quot;
-ZH | &quot;zh&quot;
-CU | &quot;cu&quot;
-CV | &quot;cv&quot;
-KW | &quot;kw&quot;
-CO | &quot;co&quot;
-CR | &quot;cr&quot;
-HR | &quot;hr&quot;
-CS | &quot;cs&quot;
-DA | &quot;da&quot;
-DV | &quot;dv&quot;
-NL | &quot;nl&quot;
-DZ | &quot;dz&quot;
-EN | &quot;en&quot;
-EO | &quot;eo&quot;
-ET | &quot;et&quot;
-EE | &quot;ee&quot;
-FO | &quot;fo&quot;
-FJ | &quot;fj&quot;
-FI | &quot;fi&quot;
-FR | &quot;fr&quot;
-FF | &quot;ff&quot;
-GD | &quot;gd&quot;
-GL | &quot;gl&quot;
-LG | &quot;lg&quot;
-KA | &quot;ka&quot;
-DE | &quot;de&quot;
-KI | &quot;ki&quot;
-EL | &quot;el&quot;
-KL | &quot;kl&quot;
-GN | &quot;gn&quot;
-GU | &quot;gu&quot;
-HT | &quot;ht&quot;
-HA | &quot;ha&quot;
-HE | &quot;he&quot;
-HZ | &quot;hz&quot;
-HI | &quot;hi&quot;
-HO | &quot;ho&quot;
-HU | &quot;hu&quot;
-IS | &quot;is&quot;
-IO | &quot;io&quot;
-IG | &quot;ig&quot;
-ID | &quot;id&quot;
-IA | &quot;ia&quot;
-IE | &quot;ie&quot;
-IU | &quot;iu&quot;
-IK | &quot;ik&quot;
-GA | &quot;ga&quot;
-IT | &quot;it&quot;
-JA | &quot;ja&quot;
-JV | &quot;jv&quot;
-KN | &quot;kn&quot;
-KR | &quot;kr&quot;
-KS | &quot;ks&quot;
-KK | &quot;kk&quot;
-RW | &quot;rw&quot;
-KV | &quot;kv&quot;
-KG | &quot;kg&quot;
-KO | &quot;ko&quot;
-KJ | &quot;kj&quot;
-KU | &quot;ku&quot;
-KY | &quot;ky&quot;
-LO | &quot;lo&quot;
-LA | &quot;la&quot;
-LV | &quot;lv&quot;
-LB | &quot;lb&quot;
-LI | &quot;li&quot;
-LN | &quot;ln&quot;
-LT | &quot;lt&quot;
-LU | &quot;lu&quot;
-MK | &quot;mk&quot;
-MG | &quot;mg&quot;
-MS | &quot;ms&quot;
-ML | &quot;ml&quot;
-MT | &quot;mt&quot;
-GV | &quot;gv&quot;
-MI | &quot;mi&quot;
-MR | &quot;mr&quot;
-MH | &quot;mh&quot;
-RO | &quot;ro&quot;
-MN | &quot;mn&quot;
-NA | &quot;na&quot;
-NV | &quot;nv&quot;
-ND | &quot;nd&quot;
-NG | &quot;ng&quot;
-NE | &quot;ne&quot;
-SE | &quot;se&quot;
-NO | &quot;no&quot;
-NB | &quot;nb&quot;
-NN | &quot;nn&quot;
-II | &quot;ii&quot;
-OC | &quot;oc&quot;
-OJ | &quot;oj&quot;
-OR | &quot;or&quot;
-OM | &quot;om&quot;
-OS | &quot;os&quot;
-PI | &quot;pi&quot;
-PA | &quot;pa&quot;
-PS | &quot;ps&quot;
-FA | &quot;fa&quot;
-PL | &quot;pl&quot;
-PT | &quot;pt&quot;
-QU | &quot;qu&quot;
-RM | &quot;rm&quot;
-RN | &quot;rn&quot;
-RU | &quot;ru&quot;
-SM | &quot;sm&quot;
-SG | &quot;sg&quot;
-SA | &quot;sa&quot;
-SC | &quot;sc&quot;
-SR | &quot;sr&quot;
-SN | &quot;sn&quot;
-SD | &quot;sd&quot;
-SI | &quot;si&quot;
-SK | &quot;sk&quot;
-SL | &quot;sl&quot;
-SO | &quot;so&quot;
-ST | &quot;st&quot;
-NR | &quot;nr&quot;
-ES | &quot;es&quot;
-SU | &quot;su&quot;
-SW | &quot;sw&quot;
-SS | &quot;ss&quot;
-SV | &quot;sv&quot;
-TL | &quot;tl&quot;
-TY | &quot;ty&quot;
-TG | &quot;tg&quot;
-TA | &quot;ta&quot;
-TT | &quot;tt&quot;
-TE | &quot;te&quot;
-TH | &quot;th&quot;
-BO | &quot;bo&quot;
-TI | &quot;ti&quot;
-TO | &quot;to&quot;
-TS | &quot;ts&quot;
-TN | &quot;tn&quot;
-TR | &quot;tr&quot;
-TK | &quot;tk&quot;
-TW | &quot;tw&quot;
-UG | &quot;ug&quot;
-UK | &quot;uk&quot;
-UR | &quot;ur&quot;
-UZ | &quot;uz&quot;
-VE | &quot;ve&quot;
-VI | &quot;vi&quot;
-VO | &quot;vo&quot;
-WA | &quot;wa&quot;
-CY | &quot;cy&quot;
-FY | &quot;fy&quot;
-WO | &quot;wo&quot;
-XH | &quot;xh&quot;
-YI | &quot;yi&quot;
-YO | &quot;yo&quot;
-ZA | &quot;za&quot;
-ZU | &quot;zu&quot;
diff --git a/.java-stubs/docs/ImageBriefDto.md b/.java-stubs/docs/ImageBriefDto.md
deleted file mode 100644
index 8f6f6e0bec0393bbb95345580ea9173a5a86f37e..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageBriefDto.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# ImageBriefDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**repository** | **String** |  | 
-**tag** | **String** |  | 
diff --git a/.java-stubs/docs/ImageChangeDto.md b/.java-stubs/docs/ImageChangeDto.md
deleted file mode 100644
index 9f24074881271791bd59f73bf6c328eebe030fad..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageChangeDto.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# ImageChangeDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**defaultPort** | **Integer** |  |  [optional]
-**environment** | [**List&lt;ImageEnvItemDto&gt;**](ImageEnvItemDto.md) |  |  [optional]
-**dialect** | **String** |  | 
-**driverClass** | **String** |  | 
-**jdbcMethod** | **String** |  | 
diff --git a/.java-stubs/docs/ImageCreateDto.md b/.java-stubs/docs/ImageCreateDto.md
deleted file mode 100644
index a2dc85f03b68f4e0a3a68bbda9e1c8a70f196353..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageCreateDto.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# ImageCreateDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**repository** | **String** |  | 
-**tag** | **String** |  | 
-**dialect** | **String** |  | 
-**environment** | [**List&lt;ImageEnvItemDto&gt;**](ImageEnvItemDto.md) |  |  [optional]
-**driverClass** | **String** |  | 
-**jdbcMethod** | **String** |  | 
-**defaultPort** | **Integer** |  | 
diff --git a/.java-stubs/docs/ImageDateDto.md b/.java-stubs/docs/ImageDateDto.md
deleted file mode 100644
index eceb42f289aeae3225ec037459c09da6e604cd7a..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageDateDto.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# ImageDateDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**example** | **String** |  | 
-**databaseFormat** | **String** |  | 
-**unixFormat** | **String** |  | 
-**hasTime** | **Boolean** |  | 
-**createdAt** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
diff --git a/.java-stubs/docs/ImageDto.md b/.java-stubs/docs/ImageDto.md
deleted file mode 100644
index 1020da91906554a5bd6908a22e569291e3c1653c..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageDto.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# ImageDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**repository** | **String** |  | 
-**tag** | **String** |  | 
-**dialect** | **String** |  | 
-**hash** | **String** |  |  [optional]
-**compiled** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-**size** | **Integer** |  |  [optional]
-**environment** | [**List&lt;ImageEnvItemDto&gt;**](ImageEnvItemDto.md) |  | 
-**driverClass** | **String** |  | 
-**dateFormats** | [**List&lt;ImageDateDto&gt;**](ImageDateDto.md) |  |  [optional]
-**jdbcMethod** | **String** |  | 
-**defaultPort** | **Integer** |  | 
diff --git a/.java-stubs/docs/ImageEndpointApi.md b/.java-stubs/docs/ImageEndpointApi.md
deleted file mode 100644
index c13e61ae50ab242801d11721b1e5869a4b2235de..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageEndpointApi.md
+++ /dev/null
@@ -1,240 +0,0 @@
-# ImageEndpointApi
-
-All URIs are relative to *http://localhost:9091*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**create**](ImageEndpointApi.md#create) | **POST** /api/image | Create image
-[**delete**](ImageEndpointApi.md#delete) | **DELETE** /api/image/{id} | Delete some image
-[**findAll**](ImageEndpointApi.md#findAll) | **GET** /api/image | Find all images
-[**findById**](ImageEndpointApi.md#findById) | **GET** /api/image/{id} | Find some image
-[**update**](ImageEndpointApi.md#update) | **PUT** /api/image/{id} | Update some image
-
-<a name="create"></a>
-# **create**
-> ImageDto create(body)
-
-Create image
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ImageEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ImageEndpointApi apiInstance = new ImageEndpointApi();
-ImageCreateDto body = new ImageCreateDto(); // ImageCreateDto | 
-try {
-    ImageDto result = apiInstance.create(body);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ImageEndpointApi#create");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **body** | [**ImageCreateDto**](ImageCreateDto.md)|  |
-
-### Return type
-
-[**ImageDto**](ImageDto.md)
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: */*
-
-<a name="delete"></a>
-# **delete**
-> Object delete(id)
-
-Delete some image
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ImageEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ImageEndpointApi apiInstance = new ImageEndpointApi();
-Long id = 789L; // Long | 
-try {
-    Object result = apiInstance.delete(id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ImageEndpointApi#delete");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **id** | **Long**|  |
-
-### Return type
-
-**Object**
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="findAll"></a>
-# **findAll**
-> List&lt;ImageBriefDto&gt; findAll()
-
-Find all images
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiException;
-//import io.swagger.client.api.ImageEndpointApi;
-
-
-ImageEndpointApi apiInstance = new ImageEndpointApi();
-try {
-    List<ImageBriefDto> result = apiInstance.findAll();
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ImageEndpointApi#findAll");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-This endpoint does not need any parameter.
-
-### Return type
-
-[**List&lt;ImageBriefDto&gt;**](ImageBriefDto.md)
-
-### Authorization
-
-No authorization required
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="findById"></a>
-# **findById**
-> ImageDto findById(id)
-
-Find some image
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiException;
-//import io.swagger.client.api.ImageEndpointApi;
-
-
-ImageEndpointApi apiInstance = new ImageEndpointApi();
-Long id = 789L; // Long | 
-try {
-    ImageDto result = apiInstance.findById(id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ImageEndpointApi#findById");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **id** | **Long**|  |
-
-### Return type
-
-[**ImageDto**](ImageDto.md)
-
-### Authorization
-
-No authorization required
-
-### HTTP request headers
-
- - **Content-Type**: Not defined
- - **Accept**: */*
-
-<a name="update"></a>
-# **update**
-> ImageDto update(body, id)
-
-Update some image
-
-### Example
-```java
-// Import classes:
-//import io.swagger.client.ApiClient;
-//import io.swagger.client.ApiException;
-//import io.swagger.client.Configuration;
-//import io.swagger.client.auth.*;
-//import io.swagger.client.api.ImageEndpointApi;
-
-ApiClient defaultClient = Configuration.getDefaultApiClient();
-
-
-ImageEndpointApi apiInstance = new ImageEndpointApi();
-ImageChangeDto body = new ImageChangeDto(); // ImageChangeDto | 
-Long id = 789L; // Long | 
-try {
-    ImageDto result = apiInstance.update(body, id);
-    System.out.println(result);
-} catch (ApiException e) {
-    System.err.println("Exception when calling ImageEndpointApi#update");
-    e.printStackTrace();
-}
-```
-
-### Parameters
-
-Name | Type | Description  | Notes
-------------- | ------------- | ------------- | -------------
- **body** | [**ImageChangeDto**](ImageChangeDto.md)|  |
- **id** | **Long**|  |
-
-### Return type
-
-[**ImageDto**](ImageDto.md)
-
-### Authorization
-
-[bearerAuth](../README.md#bearerAuth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: */*
-
diff --git a/.java-stubs/docs/ImageEnvItemDto.md b/.java-stubs/docs/ImageEnvItemDto.md
deleted file mode 100644
index 28d66a237661149b9ada35c3186f03770b0bebd3..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/ImageEnvItemDto.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# ImageEnvItemDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**iid** | **Long** |  | 
-**key** | **String** |  | 
-**value** | **String** |  | 
-**type** | [**TypeEnum**](#TypeEnum) |  | 
-
-<a name="TypeEnum"></a>
-## Enum: TypeEnum
-Name | Value
----- | -----
-USERNAME | &quot;username&quot;
-PASSWORD | &quot;password&quot;
-PRIVILEGED_USERNAME | &quot;privileged_username&quot;
-PRIVILEGED_PASSWORD | &quot;privileged_password&quot;
diff --git a/.java-stubs/docs/LicenseDto.md b/.java-stubs/docs/LicenseDto.md
deleted file mode 100644
index 90b5cb83a233d16570f78e3d8a5ca7e8af7c5e6c..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/LicenseDto.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# LicenseDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**identifier** | **String** |  | 
-**uri** | **String** |  | 
diff --git a/.java-stubs/docs/RelatedIdentifierDto.md b/.java-stubs/docs/RelatedIdentifierDto.md
deleted file mode 100644
index 452569a46aed788d58fa98701219dec0cca12099..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/RelatedIdentifierDto.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# RelatedIdentifierDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**value** | **String** |  | 
-**type** | [**TypeEnum**](#TypeEnum) |  |  [optional]
-**relation** | [**RelationEnum**](#RelationEnum) |  |  [optional]
-**created** | [**OffsetDateTime**](OffsetDateTime.md) |  | 
-**lastModified** | [**OffsetDateTime**](OffsetDateTime.md) |  |  [optional]
-
-<a name="TypeEnum"></a>
-## Enum: TypeEnum
-Name | Value
----- | -----
-DOI | &quot;DOI&quot;
-URL | &quot;URL&quot;
-URN | &quot;URN&quot;
-ARK | &quot;ARK&quot;
-ARXIV | &quot;arXiv&quot;
-BIBCODE | &quot;bibcode&quot;
-EAN13 | &quot;EAN13&quot;
-EISSN | &quot;EISSN&quot;
-HANDLE | &quot;Handle&quot;
-IGSN | &quot;IGSN&quot;
-ISBN | &quot;ISBN&quot;
-ISTC | &quot;ISTC&quot;
-LISSN | &quot;LISSN&quot;
-LSID | &quot;LSID&quot;
-PMID | &quot;PMID&quot;
-PURL | &quot;PURL&quot;
-UPC | &quot;UPC&quot;
-W3ID | &quot;w3id&quot;
-
-<a name="RelationEnum"></a>
-## Enum: RelationEnum
-Name | Value
----- | -----
-ISCITEDBY | &quot;IsCitedBy&quot;
-CITES | &quot;Cites&quot;
-ISSUPPLEMENTTO | &quot;IsSupplementTo&quot;
-ISSUPPLEMENTEDBY | &quot;IsSupplementedBy&quot;
-ISCONTINUEDBY | &quot;IsContinuedBy&quot;
-CONTINUES | &quot;Continues&quot;
-ISDESCRIBEDBY | &quot;IsDescribedBy&quot;
-DESCRIBES | &quot;Describes&quot;
-HASMETADATA | &quot;HasMetadata&quot;
-ISMETADATAFOR | &quot;IsMetadataFor&quot;
-HASVERSION | &quot;HasVersion&quot;
-ISVERSIONOF | &quot;IsVersionOf&quot;
-ISNEWVERSIONOF | &quot;IsNewVersionOf&quot;
-ISPREVIOUSVERSIONOF | &quot;IsPreviousVersionOf&quot;
-ISPARTOF | &quot;IsPartOf&quot;
-HASPART | &quot;HasPart&quot;
-ISPUBLISHEDIN | &quot;IsPublishedIn&quot;
-ISREFERENCEDBY | &quot;IsReferencedBy&quot;
-REFERENCES | &quot;References&quot;
-ISDOCUMENTEDBY | &quot;IsDocumentedBy&quot;
-DOCUMENTS | &quot;Documents&quot;
-ISCOMPILEDBY | &quot;IsCompiledBy&quot;
-COMPILES | &quot;Compiles&quot;
-ISVARIANTFORMOF | &quot;IsVariantFormOf&quot;
-ISORIGINALFORMOF | &quot;IsOriginalFormOf&quot;
-ISIDENTICALTO | &quot;IsIdenticalTo&quot;
-ISREVIEWEDBY | &quot;IsReviewedBy&quot;
-REVIEWS | &quot;Reviews&quot;
-ISDERIVEDFROM | &quot;IsDerivedFrom&quot;
-ISSOURCEOF | &quot;IsSourceOf&quot;
-ISREQUIREDBY | &quot;IsRequiredBy&quot;
-REQUIRES | &quot;Requires&quot;
-ISOBSOLETEDBY | &quot;IsObsoletedBy&quot;
-OBSOLETES | &quot;Obsoletes&quot;
diff --git a/.java-stubs/docs/TableBriefDto.md b/.java-stubs/docs/TableBriefDto.md
deleted file mode 100644
index 6eed5908e39719df7aaf8e07d3a5cdffc25cda23..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/TableBriefDto.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# TableBriefDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**name** | **String** |  | 
-**description** | **String** |  | 
-**creator** | [**UserBriefDto**](UserBriefDto.md) |  | 
-**internalName** | **String** |  | 
diff --git a/.java-stubs/docs/UserBriefDto.md b/.java-stubs/docs/UserBriefDto.md
deleted file mode 100644
index f616cb450536101906d90269682475da1974e4a4..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/UserBriefDto.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# UserBriefDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**username** | **String** | Only contains lowercase characters | 
-**titlesBefore** | **String** |  |  [optional]
-**titlesAfter** | **String** |  |  [optional]
-**firstname** | **String** |  |  [optional]
-**lastname** | **String** |  |  [optional]
-**affiliation** | **String** |  |  [optional]
-**orcid** | **String** |  |  [optional]
-**roles** | **List&lt;String&gt;** | Roles of the user | 
-**themeDark** | **Boolean** |  |  [optional]
-**emailVerified** | **Boolean** |  |  [optional]
diff --git a/.java-stubs/docs/UserDto.md b/.java-stubs/docs/UserDto.md
deleted file mode 100644
index be198dbc46d9529e29c1a030d90124a763edd4ce..0000000000000000000000000000000000000000
--- a/.java-stubs/docs/UserDto.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# UserDto
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **Long** |  | 
-**authorities** | [**List&lt;GrantedAuthorityDto&gt;**](GrantedAuthorityDto.md) |  |  [optional]
-**username** | **String** | Only contains lowercase characters | 
-**firstname** | **String** |  |  [optional]
-**lastname** | **String** |  |  [optional]
-**affiliation** | **String** |  |  [optional]
-**orcid** | **String** |  |  [optional]
-**roles** | **List&lt;String&gt;** | Roles of the user | 
-**containers** | [**List&lt;ContainerDto&gt;**](ContainerDto.md) |  |  [optional]
-**databases** | [**List&lt;ContainerDto&gt;**](ContainerDto.md) |  |  [optional]
-**identifiers** | [**List&lt;ContainerDto&gt;**](ContainerDto.md) |  |  [optional]
-**email** | **String** |  | 
-**titlesBefore** | **String** |  |  [optional]
-**titlesAfter** | **String** |  |  [optional]
-**themeDark** | **Boolean** |  | 
-**emailVerified** | **Boolean** |  | 
diff --git a/.java-stubs/gradle/wrapper/gradle-wrapper.jar b/.java-stubs/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 2c6137b87896c8f70315ae454e00a969ef5f6019..0000000000000000000000000000000000000000
Binary files a/.java-stubs/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/.java-stubs/gradle/wrapper/gradle-wrapper.properties b/.java-stubs/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index b7a3647395514b585a55c96dbf3fae30035c95dc..0000000000000000000000000000000000000000
--- a/.java-stubs/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Tue May 17 23:08:05 CST 2016
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip
diff --git a/.java-stubs/pom.xml b/.java-stubs/pom.xml
deleted file mode 100644
index d565ab7c1ab6acb9af45ab738baaf9a98fe7e894..0000000000000000000000000000000000000000
--- a/.java-stubs/pom.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>io.swagger</groupId>
-  <artifactId>swagger-java-client</artifactId>
-  <packaging>jar</packaging>
-  <name>swagger-java-client</name>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>8</source>
-                    <target>8</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-    <version>1.0.0</version>
-  <url>https://github.com/swagger-api/swagger-codegen</url>
-  <description>Swagger Java</description>
-  <scm>
-    <connection>scm:git:git@github.com:swagger-api/swagger-codegen.git</connection>
-    <developerConnection>scm:git:git@github.com:swagger-api/swagger-codegen.git</developerConnection>
-    <url>https://github.com/swagger-api/swagger-codegen</url>
-  </scm>
-  <prerequisites>
-    <maven>2.2.0</maven>
-  </prerequisites>
-
-  <licenses>
-    <license>
-      <name>Unlicense</name>
-      <url>https://www.apache.org/licenses/LICENSE-2.0</url>
-      <distribution>repo</distribution>
-    </license>
-  </licenses>
-
-  <developers>
-    <developer>
-      <name>Swagger</name>
-      <email>apiteam@swagger.io</email>
-      <organization>Swagger</organization>
-      <organizationUrl>http://swagger.io</organizationUrl>
-    </developer>
-  </developers>
-
-  <profiles>
-    <profile>
-      <id>sign-artifacts</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-gpg-plugin</artifactId>
-            <version>1.5</version>
-            <executions>
-              <execution>
-                <id>sign-artifacts</id>
-                <phase>verify</phase>
-                <goals>
-                  <goal>sign</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
-  <dependencies>
-    <dependency>
-      <groupId>io.swagger.core.v3</groupId>
-      <artifactId>swagger-annotations</artifactId>
-      <version>${swagger-core-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.squareup.okhttp</groupId>
-      <artifactId>okhttp</artifactId>
-      <version>${okhttp-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.squareup.okhttp</groupId>
-      <artifactId>logging-interceptor</artifactId>
-      <version>${okhttp-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>${gson-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>io.gsonfire</groupId>
-      <artifactId>gson-fire</artifactId>
-      <version>${gson-fire-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.threeten</groupId>
-      <artifactId>threetenbp</artifactId>
-      <version>${threetenbp-version}</version>
-    </dependency>
-    <!-- test dependencies -->
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${junit-version}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <properties>
-    <java.version>1.7</java.version>
-    <maven.compiler.source>${java.version}</maven.compiler.source>
-    <maven.compiler.target>${java.version}</maven.compiler.target>
-    <swagger-core-version>2.0.0</swagger-core-version>
-    <okhttp-version>2.7.5</okhttp-version>
-    <gson-version>2.8.1</gson-version>
-    <gson-fire-version>1.8.3</gson-fire-version>
-    <threetenbp-version>1.3.5</threetenbp-version>
-    <maven-plugin-version>1.0.0</maven-plugin-version>
-    <junit-version>4.13.1</junit-version>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-</project>
diff --git a/.java-stubs/settings.gradle b/.java-stubs/settings.gradle
deleted file mode 100644
index 55640f75122ecce8bac6d4e3e75dce20896a07fd..0000000000000000000000000000000000000000
--- a/.java-stubs/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-rootProject.name = "swagger-java-client"
\ No newline at end of file
diff --git a/.java-stubs/src/main/java/CreateDatabaseApp.java b/.java-stubs/src/main/java/CreateDatabaseApp.java
deleted file mode 100644
index b2ec162977335c738b18cf8383315ce11e4f0363..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/CreateDatabaseApp.java
+++ /dev/null
@@ -1,43 +0,0 @@
-import io.swagger.client.ApiException;
-import io.swagger.client.api.ContainerEndpointApi;
-import io.swagger.client.api.DatabaseEndpointApi;
-import io.swagger.client.model.*;
-
-public class CreateDatabaseApp {
-
-    public static void main(String[] args) throws InterruptedException {
-        final ContainerEndpointApi containerEndpointApi = new ContainerEndpointApi();
-        final DatabaseEndpointApi databaseEndpointApi = new DatabaseEndpointApi();
-        /* create container */
-        final ContainerCreateRequestDto containerCreateRequest = new ContainerCreateRequestDto();
-        containerCreateRequest.setName("Pilot Factory Data");
-        containerCreateRequest.setRepository("mariadb");
-        containerCreateRequest.setTag("10.5");
-        final ContainerBriefDto container;
-        try {
-            container = containerEndpointApi.create1(containerCreateRequest);
-        } catch (ApiException e) {
-            throw new RuntimeException(e);
-        }
-        /* start container */
-        final ContainerChangeDto containerChangeRequest = new ContainerChangeDto();
-        containerChangeRequest.action(ContainerChangeDto.ActionEnum.START);
-        try {
-            containerEndpointApi.modify(containerChangeRequest, container.getId());
-        } catch (ApiException e) {
-            throw new RuntimeException(e);
-        }
-        Thread.sleep(5 * 1000) /* wait 5 seconds */;
-        /* create database */
-        final DatabaseCreateDto databaseCreateRequest = new DatabaseCreateDto();
-        databaseCreateRequest.setName("Pilot Factory Data");
-        databaseCreateRequest.setIsPublic(true);
-        final DatabaseBriefDto database;
-        try {
-            database = databaseEndpointApi.create(databaseCreateRequest, container.getId());
-        } catch (ApiException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/.java-stubs/src/main/java/InsertDataApp.java b/.java-stubs/src/main/java/InsertDataApp.java
deleted file mode 100644
index 8e4fdaaa0bdbf7bd828cd799cb32790a657934e9..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/InsertDataApp.java
+++ /dev/null
@@ -1,71 +0,0 @@
-import io.swagger.client.ApiException;
-import io.swagger.client.api.TableDataEndpointApi;
-import io.swagger.client.api.TableEndpointApi;
-import io.swagger.client.model.*;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-
-public class InsertDataApp {
-
-    public static void main(String[] args) {
-        final TableEndpointApi tableEndpointApi = new TableEndpointApi();
-        /* create table */
-        final TableCreateDto tableCreateRequest = new TableCreateDto();
-        tableCreateRequest.setName("Power");
-        tableCreateRequest.setDescription("Power consumption in the Pilot Factory");
-        final List<ColumnCreateDto> columns = new LinkedList<>();
-        columns.add(column("UUID", ColumnCreateDto.TypeEnum.STRING, null, true, true, false));
-        columns.add(column("Point", ColumnCreateDto.TypeEnum.STRING, null, true, true, false));
-        columns.add(column("Value", ColumnCreateDto.TypeEnum.DECIMAL, null, true, true, false));
-        columns.add(column("Unit", ColumnCreateDto.TypeEnum.STRING, null, true, true, false));
-        columns.add(column("Timestamp", ColumnCreateDto.TypeEnum.TIMESTAMP, 1L, true, true, false));
-        tableCreateRequest.setColumns(columns);
-        final TableBriefDto table;
-        try {
-            table = tableEndpointApi.create(tableCreateRequest, 1L, 1L);
-        } catch (ApiException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static void insertTuple(Long containerId, Long databaseId, Long tableId) throws ApiException {
-        final TableDataEndpointApi tableDataEndpointApi = new TableDataEndpointApi();
-        /* insert data */
-        final TableCsvDto tuple = new TableCsvDto();
-        tuple.data(new HashMap<String, Object>(){{
-            put("uuid", "56873eb0-aacb-11ed-afa1-0242ac120002");
-            put("point", "A");
-            put("value", 54.3212);
-            put("unit", "W");
-            put("timestamp", Instant.now());
-        }});
-        tableDataEndpointApi.insert(tuple, containerId, databaseId, tableId);
-    }
-
-    private static void insertBulk(Long containerId, Long databaseId, Long tableId) throws ApiException {
-        final TableDataEndpointApi tableDataEndpointApi = new TableDataEndpointApi();
-        /* insert data */
-        final ImportDto csv = new ImportDto();
-        csv.setLocation("/path/to/data.csv");
-        csv.setQuote("\"");
-        csv.setNullElement("NA");
-        csv.setSeparator(",");
-        tableDataEndpointApi.importCsv(csv, containerId, databaseId, tableId);
-    }
-
-    private static ColumnCreateDto column(String name, ColumnCreateDto.TypeEnum type, Long dateFormatId,
-                                          Boolean primaryKey, Boolean unique, Boolean nulled) {
-        final ColumnCreateDto columnCreateRequest = new ColumnCreateDto();
-        columnCreateRequest.setName(name);
-        columnCreateRequest.setType(type);
-        columnCreateRequest.setNullAllowed(nulled);
-        columnCreateRequest.setPrimaryKey(primaryKey);
-        columnCreateRequest.setUnique(unique);
-        columnCreateRequest.setDfid(dateFormatId);
-        return columnCreateRequest;
-    }
-
-}
diff --git a/.java-stubs/src/main/java/QueryDataApp.java b/.java-stubs/src/main/java/QueryDataApp.java
deleted file mode 100644
index f5c1db60cc1f606838195a7e1e716adf50c16ae7..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/QueryDataApp.java
+++ /dev/null
@@ -1,18 +0,0 @@
-import io.swagger.client.ApiException;
-import io.swagger.client.api.QueryEndpointApi;
-import io.swagger.client.model.*;
-
-public class QueryDataApp {
-
-    public static void main(String[] args) throws ApiException {
-        final QueryEndpointApi queryEndpointApi = new QueryEndpointApi();
-        /* execute query */
-        final ExecuteStatementDto executeStatementRequest = new ExecuteStatementDto();
-        executeStatementRequest.setStatement("SELECT `uuid`, `point`, `value`, `unit`, `timestamp` FROM `power` WHERE `point` = \"A\"");
-        final QueryResultDto response = queryEndpointApi.execute(executeStatementRequest, 1L, 1L, 0L, 10L, null, null);
-        response.getId();
-        response.getResult();
-        response.getResultNumber();
-    }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ApiCallback.java b/.java-stubs/src/main/java/io/swagger/client/ApiCallback.java
deleted file mode 100644
index bbee95baf9d497a59327918f5e8b9e7cfe411b24..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ApiCallback.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import java.io.IOException;
-
-import java.util.Map;
-import java.util.List;
-
-/**
- * Callback for asynchronous API call.
- *
- * @param <T> The return type
- */
-public interface ApiCallback<T> {
-    /**
-     * This is called when the API call fails.
-     *
-     * @param e The exception causing the failure
-     * @param statusCode Status code of the response if available, otherwise it would be 0
-     * @param responseHeaders Headers of the response if available, otherwise it would be null
-     */
-    void onFailure(ApiException e, int statusCode, Map<String, List<String>> responseHeaders);
-
-    /**
-     * This is called when the API call succeeded.
-     *
-     * @param result The result deserialized from response
-     * @param statusCode Status code of the response
-     * @param responseHeaders Headers of the response
-     */
-    void onSuccess(T result, int statusCode, Map<String, List<String>> responseHeaders);
-
-    /**
-     * This is called when the API upload processing.
-     *
-     * @param bytesWritten bytes Written
-     * @param contentLength content length of request body
-     * @param done write end
-     */
-    void onUploadProgress(long bytesWritten, long contentLength, boolean done);
-
-    /**
-     * This is called when the API downlond processing.
-     *
-     * @param bytesRead bytes Read
-     * @param contentLength content lenngth of the response
-     * @param done Read end
-     */
-    void onDownloadProgress(long bytesRead, long contentLength, boolean done);
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ApiClient.java b/.java-stubs/src/main/java/io/swagger/client/ApiClient.java
deleted file mode 100644
index 84cb28877b2af6d761cce2ce6bbf8a4f72b32b7d..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ApiClient.java
+++ /dev/null
@@ -1,1206 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import com.squareup.okhttp.*;
-import com.squareup.okhttp.internal.http.HttpMethod;
-import com.squareup.okhttp.logging.HttpLoggingInterceptor;
-import com.squareup.okhttp.logging.HttpLoggingInterceptor.Level;
-import okio.BufferedSink;
-import okio.Okio;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.OffsetDateTime;
-import org.threeten.bp.format.DateTimeFormatter;
-
-import javax.net.ssl.*;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.lang.reflect.Type;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import io.swagger.client.auth.Authentication;
-import io.swagger.client.auth.HttpBasicAuth;
-import io.swagger.client.auth.ApiKeyAuth;
-import io.swagger.client.auth.OAuth;
-
-public class ApiClient {
-
-    private String basePath = "http://localhost:9091";
-    private boolean debugging = false;
-    private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
-    private String tempFolderPath = null;
-
-    private Map<String, Authentication> authentications;
-
-    private DateFormat dateFormat;
-    private DateFormat datetimeFormat;
-    private boolean lenientDatetimeFormat;
-    private int dateLength;
-
-    private InputStream sslCaCert;
-    private boolean verifyingSsl;
-    private KeyManager[] keyManagers;
-
-    private OkHttpClient httpClient;
-    private JSON json;
-
-    private HttpLoggingInterceptor loggingInterceptor;
-
-    /*
-     * Constructor for ApiClient
-     */
-    public ApiClient() {
-        httpClient = new OkHttpClient();
-
-
-        verifyingSsl = true;
-
-        json = new JSON();
-
-        // Set default User-Agent.
-        setUserAgent("Swagger-Codegen/1.0.0/java");
-
-        // Setup authentications (key: authentication name, value: authentication).
-        authentications = new HashMap<String, Authentication>();
-        authentications.put("bearerAuth", new OAuth());
-        // Prevent the authentications from being modified.
-        authentications = Collections.unmodifiableMap(authentications);
-    }
-
-    /**
-     * Get base path
-     *
-     * @return Baes path
-     */
-    public String getBasePath() {
-        return basePath;
-    }
-
-    /**
-     * Set base path
-     *
-     * @param basePath Base path of the URL (e.g http://localhost:9091
-     * @return An instance of OkHttpClient
-     */
-    public ApiClient setBasePath(String basePath) {
-        this.basePath = basePath;
-        return this;
-    }
-
-    /**
-     * Get HTTP client
-     *
-     * @return An instance of OkHttpClient
-     */
-    public OkHttpClient getHttpClient() {
-        return httpClient;
-    }
-
-    /**
-     * Set HTTP client
-     *
-     * @param httpClient An instance of OkHttpClient
-     * @return Api Client
-     */
-    public ApiClient setHttpClient(OkHttpClient httpClient) {
-        this.httpClient = httpClient;
-        return this;
-    }
-
-    /**
-     * Get JSON
-     *
-     * @return JSON object
-     */
-    public JSON getJSON() {
-        return json;
-    }
-
-    /**
-     * Set JSON
-     *
-     * @param json JSON object
-     * @return Api client
-     */
-    public ApiClient setJSON(JSON json) {
-        this.json = json;
-        return this;
-    }
-
-    /**
-     * True if isVerifyingSsl flag is on
-     *
-     * @return True if isVerifySsl flag is on
-     */
-    public boolean isVerifyingSsl() {
-        return verifyingSsl;
-    }
-
-    /**
-     * Configure whether to verify certificate and hostname when making https requests.
-     * Default to true.
-     * NOTE: Do NOT set to false in production code, otherwise you would face multiple types of cryptographic attacks.
-     *
-     * @param verifyingSsl True to verify TLS/SSL connection
-     * @return ApiClient
-     */
-    public ApiClient setVerifyingSsl(boolean verifyingSsl) {
-        this.verifyingSsl = verifyingSsl;
-        applySslSettings();
-        return this;
-    }
-
-    /**
-     * Get SSL CA cert.
-     *
-     * @return Input stream to the SSL CA cert
-     */
-    public InputStream getSslCaCert() {
-        return sslCaCert;
-    }
-
-    /**
-     * Configure the CA certificate to be trusted when making https requests.
-     * Use null to reset to default.
-     *
-     * @param sslCaCert input stream for SSL CA cert
-     * @return ApiClient
-     */
-    public ApiClient setSslCaCert(InputStream sslCaCert) {
-        this.sslCaCert = sslCaCert;
-        applySslSettings();
-        return this;
-    }
-
-    public KeyManager[] getKeyManagers() {
-        return keyManagers;
-    }
-
-    /**
-     * Configure client keys to use for authorization in an SSL session.
-     * Use null to reset to default.
-     *
-     * @param managers The KeyManagers to use
-     * @return ApiClient
-     */
-    public ApiClient setKeyManagers(KeyManager[] managers) {
-        this.keyManagers = managers;
-        applySslSettings();
-        return this;
-    }
-
-    public DateFormat getDateFormat() {
-        return dateFormat;
-    }
-
-    public ApiClient setDateFormat(DateFormat dateFormat) {
-        this.json.setDateFormat(dateFormat);
-        return this;
-    }
-
-    public ApiClient setSqlDateFormat(DateFormat dateFormat) {
-        this.json.setSqlDateFormat(dateFormat);
-        return this;
-    }
-
-    public ApiClient setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
-        this.json.setOffsetDateTimeFormat(dateFormat);
-        return this;
-    }
-
-    public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) {
-        this.json.setLocalDateFormat(dateFormat);
-        return this;
-    }
-
-    public ApiClient setLenientOnJson(boolean lenientOnJson) {
-        this.json.setLenientOnJson(lenientOnJson);
-        return this;
-    }
-
-    /**
-     * Get authentications (key: authentication name, value: authentication).
-     *
-     * @return Map of authentication objects
-     */
-    public Map<String, Authentication> getAuthentications() {
-        return authentications;
-    }
-
-    /**
-     * Get authentication for the given name.
-     *
-     * @param authName The authentication name
-     * @return The authentication, null if not found
-     */
-    public Authentication getAuthentication(String authName) {
-        return authentications.get(authName);
-    }
-
-    /**
-     * Helper method to set username for the first HTTP basic authentication.
-     *
-     * @param username Username
-     */
-    public void setUsername(String username) {
-        for (Authentication auth : authentications.values()) {
-            if (auth instanceof HttpBasicAuth) {
-                ((HttpBasicAuth) auth).setUsername(username);
-                return;
-            }
-        }
-        throw new RuntimeException("No HTTP basic authentication configured!");
-    }
-
-    /**
-     * Helper method to set password for the first HTTP basic authentication.
-     *
-     * @param password Password
-     */
-    public void setPassword(String password) {
-        for (Authentication auth : authentications.values()) {
-            if (auth instanceof HttpBasicAuth) {
-                ((HttpBasicAuth) auth).setPassword(password);
-                return;
-            }
-        }
-        throw new RuntimeException("No HTTP basic authentication configured!");
-    }
-
-    /**
-     * Helper method to set API key value for the first API key authentication.
-     *
-     * @param apiKey API key
-     */
-    public void setApiKey(String apiKey) {
-        for (Authentication auth : authentications.values()) {
-            if (auth instanceof ApiKeyAuth) {
-                ((ApiKeyAuth) auth).setApiKey(apiKey);
-                return;
-            }
-        }
-        throw new RuntimeException("No API key authentication configured!");
-    }
-
-    /**
-     * Helper method to set API key prefix for the first API key authentication.
-     *
-     * @param apiKeyPrefix API key prefix
-     */
-    public void setApiKeyPrefix(String apiKeyPrefix) {
-        for (Authentication auth : authentications.values()) {
-            if (auth instanceof ApiKeyAuth) {
-                ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
-                return;
-            }
-        }
-        throw new RuntimeException("No API key authentication configured!");
-    }
-
-    /**
-     * Helper method to set access token for the first OAuth2 authentication.
-     *
-     * @param accessToken Access token
-     */
-    public void setAccessToken(String accessToken) {
-        for (Authentication auth : authentications.values()) {
-            if (auth instanceof OAuth) {
-                ((OAuth) auth).setAccessToken(accessToken);
-                return;
-            }
-        }
-        throw new RuntimeException("No OAuth2 authentication configured!");
-    }
-
-    /**
-     * Set the User-Agent header's value (by adding to the default header map).
-     *
-     * @param userAgent HTTP request's user agent
-     * @return ApiClient
-     */
-    public ApiClient setUserAgent(String userAgent) {
-        addDefaultHeader("User-Agent", userAgent);
-        return this;
-    }
-
-    /**
-     * Add a default header.
-     *
-     * @param key The header's key
-     * @param value The header's value
-     * @return ApiClient
-     */
-    public ApiClient addDefaultHeader(String key, String value) {
-        defaultHeaderMap.put(key, value);
-        return this;
-    }
-
-    /**
-     * Check that whether debugging is enabled for this API client.
-     *
-     * @return True if debugging is enabled, false otherwise.
-     */
-    public boolean isDebugging() {
-        return debugging;
-    }
-
-    /**
-     * Enable/disable debugging for this API client.
-     *
-     * @param debugging To enable (true) or disable (false) debugging
-     * @return ApiClient
-     */
-    public ApiClient setDebugging(boolean debugging) {
-        if (debugging != this.debugging) {
-            if (debugging) {
-                loggingInterceptor = new HttpLoggingInterceptor();
-                loggingInterceptor.setLevel(Level.BODY);
-                httpClient.interceptors().add(loggingInterceptor);
-            } else {
-                httpClient.interceptors().remove(loggingInterceptor);
-                loggingInterceptor = null;
-            }
-        }
-        this.debugging = debugging;
-        return this;
-    }
-
-    /**
-     * The path of temporary folder used to store downloaded files from endpoints
-     * with file response. The default value is <code>null</code>, i.e. using
-     * the system's default tempopary folder.
-     *
-     * @see <a href="https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile">createTempFile</a>
-     * @return Temporary folder path
-     */
-    public String getTempFolderPath() {
-        return tempFolderPath;
-    }
-
-    /**
-     * Set the temporary folder path (for downloading files)
-     *
-     * @param tempFolderPath Temporary folder path
-     * @return ApiClient
-     */
-    public ApiClient setTempFolderPath(String tempFolderPath) {
-        this.tempFolderPath = tempFolderPath;
-        return this;
-    }
-
-    /**
-     * Get connection timeout (in milliseconds).
-     *
-     * @return Timeout in milliseconds
-     */
-    public int getConnectTimeout() {
-        return httpClient.getConnectTimeout();
-    }
-
-    /**
-     * Sets the connect timeout (in milliseconds).
-     * A value of 0 means no timeout, otherwise values must be between 1 and
-     *
-     * @param connectionTimeout connection timeout in milliseconds
-     * @return Api client
-     */
-    public ApiClient setConnectTimeout(int connectionTimeout) {
-        httpClient.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS);
-        return this;
-    }
-
-    /**
-     * Get read timeout (in milliseconds).
-     *
-     * @return Timeout in milliseconds
-     */
-    public int getReadTimeout() {
-        return httpClient.getReadTimeout();
-    }
-
-    /**
-     * Sets the read timeout (in milliseconds).
-     * A value of 0 means no timeout, otherwise values must be between 1 and
-     * {@link Integer#MAX_VALUE}.
-     *
-     * @param readTimeout read timeout in milliseconds
-     * @return Api client
-     */
-    public ApiClient setReadTimeout(int readTimeout) {
-        httpClient.setReadTimeout(readTimeout, TimeUnit.MILLISECONDS);
-        return this;
-    }
-
-    /**
-     * Get write timeout (in milliseconds).
-     *
-     * @return Timeout in milliseconds
-     */
-    public int getWriteTimeout() {
-        return httpClient.getWriteTimeout();
-    }
-
-    /**
-     * Sets the write timeout (in milliseconds).
-     * A value of 0 means no timeout, otherwise values must be between 1 and
-     * {@link Integer#MAX_VALUE}.
-     *
-     * @param writeTimeout connection timeout in milliseconds
-     * @return Api client
-     */
-    public ApiClient setWriteTimeout(int writeTimeout) {
-        httpClient.setWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS);
-        return this;
-    }
-
-    /**
-     * Format the given parameter object into string.
-     *
-     * @param param Parameter
-     * @return String representation of the parameter
-     */
-    public String parameterToString(Object param) {
-        if (param == null) {
-            return "";
-        } else if (param instanceof Date || param instanceof OffsetDateTime || param instanceof LocalDate) {
-            //Serialize to json string and remove the " enclosing characters
-            String jsonStr = json.serialize(param);
-            return jsonStr.substring(1, jsonStr.length() - 1);
-        } else if (param instanceof Collection) {
-            StringBuilder b = new StringBuilder();
-            for (Object o : (Collection)param) {
-                if (b.length() > 0) {
-                    b.append(",");
-                }
-                b.append(String.valueOf(o));
-            }
-            return b.toString();
-        } else {
-            return String.valueOf(param);
-        }
-    }
-
-    /**
-     * Formats the specified query parameter to a list containing a single {@code Pair} object.
-     *
-     * Note that {@code value} must not be a collection.
-     *
-     * @param name The name of the parameter.
-     * @param value The value of the parameter.
-     * @return A list containing a single {@code Pair} object.
-     */
-    public List<Pair> parameterToPair(String name, Object value) {
-        List<Pair> params = new ArrayList<Pair>();
-
-        // preconditions
-        if (name == null || name.isEmpty() || value == null || value instanceof Collection) return params;
-
-        params.add(new Pair(name, parameterToString(value)));
-        return params;
-    }
-
-    /**
-     * Formats the specified collection query parameters to a list of {@code Pair} objects.
-     *
-     * Note that the values of each of the returned Pair objects are percent-encoded.
-     *
-     * @param collectionFormat The collection format of the parameter.
-     * @param name The name of the parameter.
-     * @param value The value of the parameter.
-     * @return A list of {@code Pair} objects.
-     */
-    public List<Pair> parameterToPairs(String collectionFormat, String name, Collection value) {
-        List<Pair> params = new ArrayList<Pair>();
-
-        // preconditions
-        if (name == null || name.isEmpty() || value == null || value.isEmpty()) {
-            return params;
-        }
-
-        // create the params based on the collection format
-        if ("multi".equals(collectionFormat)) {
-            for (Object item : value) {
-                params.add(new Pair(name, escapeString(parameterToString(item))));
-            }
-            return params;
-        }
-
-        // collectionFormat is assumed to be "csv" by default
-        String delimiter = ",";
-
-        // escape all delimiters except commas, which are URI reserved
-        // characters
-        if ("ssv".equals(collectionFormat)) {
-            delimiter = escapeString(" ");
-        } else if ("tsv".equals(collectionFormat)) {
-            delimiter = escapeString("\t");
-        } else if ("pipes".equals(collectionFormat)) {
-            delimiter = escapeString("|");
-        }
-
-        StringBuilder sb = new StringBuilder() ;
-        for (Object item : value) {
-            sb.append(delimiter);
-            sb.append(escapeString(parameterToString(item)));
-        }
-
-        params.add(new Pair(name, sb.substring(delimiter.length())));
-
-        return params;
-    }
-
-    /**
-     * Sanitize filename by removing path.
-     * e.g. ../../sun.gif becomes sun.gif
-     *
-     * @param filename The filename to be sanitized
-     * @return The sanitized filename
-     */
-    public String sanitizeFilename(String filename) {
-        return filename.replaceAll(".*[/\\\\]", "");
-    }
-
-    /**
-     * Check if the given MIME is a JSON MIME.
-     * JSON MIME examples:
-     *   application/json
-     *   application/json; charset=UTF8
-     *   APPLICATION/JSON
-     *   application/vnd.company+json
-     * "* / *" is also default to JSON
-     * @param mime MIME (Multipurpose Internet Mail Extensions)
-     * @return True if the given MIME is JSON, false otherwise.
-     */
-    public boolean isJsonMime(String mime) {
-      String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
-      return mime != null && (mime.matches(jsonMime) || mime.equals("*/*"));
-    }
-
-    /**
-     * Select the Accept header's value from the given accepts array:
-     *   if JSON exists in the given array, use it;
-     *   otherwise use all of them (joining into a string)
-     *
-     * @param accepts The accepts array to select from
-     * @return The Accept header to use. If the given array is empty,
-     *   null will be returned (not to set the Accept header explicitly).
-     */
-    public String selectHeaderAccept(String[] accepts) {
-        if (accepts.length == 0) {
-            return null;
-        }
-        for (String accept : accepts) {
-            if (isJsonMime(accept)) {
-                return accept;
-            }
-        }
-        return StringUtil.join(accepts, ",");
-    }
-
-    /**
-     * Select the Content-Type header's value from the given array:
-     *   if JSON exists in the given array, use it;
-     *   otherwise use the first one of the array.
-     *
-     * @param contentTypes The Content-Type array to select from
-     * @return The Content-Type header to use. If the given array is empty,
-     *   or matches "any", JSON will be used.
-     */
-    public String selectHeaderContentType(String[] contentTypes) {
-        if (contentTypes.length == 0 || contentTypes[0].equals("*/*")) {
-             return "application/json";
-        }
-        for (String contentType : contentTypes) {
-            if (isJsonMime(contentType)) {
-                return contentType;
-            }
-        }
-        return contentTypes[0];
-    }
-
-    /**
-     * Escape the given string to be used as URL query value.
-     *
-     * @param str String to be escaped
-     * @return Escaped string
-     */
-    public String escapeString(String str) {
-        try {
-            return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
-        } catch (UnsupportedEncodingException e) {
-            return str;
-        }
-    }
-
-    /**
-     * Deserialize response body to Java object, according to the return type and
-     * the Content-Type response header.
-     *
-     * @param <T> Type
-     * @param response HTTP response
-     * @param returnType The type of the Java object
-     * @return The deserialized Java object
-     * @throws ApiException If fail to deserialize response body, i.e. cannot read response body
-     *   or the Content-Type of the response is not supported.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T deserialize(Response response, Type returnType) throws ApiException {
-        if (response == null || returnType == null) {
-            return null;
-        }
-
-        if ("byte[]".equals(returnType.toString())) {
-            // Handle binary response (byte array).
-            try {
-                return (T) response.body().bytes();
-            } catch (IOException e) {
-                throw new ApiException(e);
-            }
-        } else if (returnType.equals(File.class)) {
-            // Handle file downloading.
-            return (T) downloadFileFromResponse(response);
-        }
-
-        String respBody;
-        try {
-            if (response.body() != null)
-                respBody = response.body().string();
-            else
-                respBody = null;
-        } catch (IOException e) {
-            throw new ApiException(e);
-        }
-
-        if (respBody == null || "".equals(respBody)) {
-            return null;
-        }
-
-        String contentType = response.headers().get("Content-Type");
-        if (contentType == null) {
-            // ensuring a default content type
-            contentType = "application/json";
-        }
-        if (isJsonMime(contentType)) {
-            return json.deserialize(respBody, returnType);
-        } else if (returnType.equals(String.class)) {
-            // Expecting string, return the raw response body.
-            return (T) respBody;
-        } else {
-            throw new ApiException(
-                    "Content type \"" + contentType + "\" is not supported for type: " + returnType,
-                    response.code(),
-                    response.headers().toMultimap(),
-                    respBody);
-        }
-    }
-
-    /**
-     * Serialize the given Java object into request body according to the object's
-     * class and the request Content-Type.
-     *
-     * @param obj The Java object
-     * @param contentType The request Content-Type
-     * @return The serialized request body
-     * @throws ApiException If fail to serialize the given object
-     */
-    public RequestBody serialize(Object obj, String contentType) throws ApiException {
-        if (obj instanceof byte[]) {
-            // Binary (byte array) body parameter support.
-            return RequestBody.create(MediaType.parse(contentType), (byte[]) obj);
-        } else if (obj instanceof File) {
-            // File body parameter support.
-            return RequestBody.create(MediaType.parse(contentType), (File) obj);
-        } else if (isJsonMime(contentType)) {
-            String content;
-            if (obj != null) {
-                content = json.serialize(obj);
-            } else {
-                content = null;
-            }
-            return RequestBody.create(MediaType.parse(contentType), content);
-        } else {
-            throw new ApiException("Content type \"" + contentType + "\" is not supported");
-        }
-    }
-
-    /**
-     * Download file from the given response.
-     *
-     * @param response An instance of the Response object
-     * @throws ApiException If fail to read file content from response and write to disk
-     * @return Downloaded file
-     */
-    public File downloadFileFromResponse(Response response) throws ApiException {
-        try {
-            File file = prepareDownloadFile(response);
-            BufferedSink sink = Okio.buffer(Okio.sink(file));
-            sink.writeAll(response.body().source());
-            sink.close();
-            return file;
-        } catch (IOException e) {
-            throw new ApiException(e);
-        }
-    }
-
-    /**
-     * Prepare file for download
-     *
-     * @param response An instance of the Response object
-     * @throws IOException If fail to prepare file for download
-     * @return Prepared file for the download
-     */
-    public File prepareDownloadFile(Response response) throws IOException {
-        String filename = null;
-        String contentDisposition = response.header("Content-Disposition");
-        if (contentDisposition != null && !"".equals(contentDisposition)) {
-            // Get filename from the Content-Disposition header.
-            Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
-            Matcher matcher = pattern.matcher(contentDisposition);
-            if (matcher.find()) {
-                filename = sanitizeFilename(matcher.group(1));
-            }
-        }
-
-        String prefix = null;
-        String suffix = null;
-        if (filename == null) {
-            prefix = "download-";
-            suffix = "";
-        } else {
-            int pos = filename.lastIndexOf(".");
-            if (pos == -1) {
-                prefix = filename + "-";
-            } else {
-                prefix = filename.substring(0, pos) + "-";
-                suffix = filename.substring(pos);
-            }
-            // File.createTempFile requires the prefix to be at least three characters long
-            if (prefix.length() < 3)
-                prefix = "download-";
-        }
-
-        if (tempFolderPath == null)
-            return Files.createTempFile(prefix, suffix).toFile();
-        else
-            return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile();
-    }
-
-    /**
-     * {@link #execute(Call, Type)}
-     *
-     * @param <T> Type
-     * @param call An instance of the Call object
-     * @throws ApiException If fail to execute the call
-     * @return ApiResponse&lt;T&gt;
-     */
-    public <T> ApiResponse<T> execute(Call call) throws ApiException {
-        return execute(call, null);
-    }
-
-    /**
-     * Execute HTTP call and deserialize the HTTP response body into the given return type.
-     *
-     * @param returnType The return type used to deserialize HTTP response body
-     * @param <T> The return type corresponding to (same with) returnType
-     * @param call Call
-     * @return ApiResponse object containing response status, headers and
-     *   data, which is a Java object deserialized from response body and would be null
-     *   when returnType is null.
-     * @throws ApiException If fail to execute the call
-     */
-    public <T> ApiResponse<T> execute(Call call, Type returnType) throws ApiException {
-        try {
-            Response response = call.execute();
-            T data = handleResponse(response, returnType);
-            return new ApiResponse<T>(response.code(), response.headers().toMultimap(), data);
-        } catch (IOException e) {
-            throw new ApiException(e);
-        }
-    }
-
-    /**
-     * {@link #executeAsync(Call, Type, ApiCallback)}
-     *
-     * @param <T> Type
-     * @param call An instance of the Call object
-     * @param callback ApiCallback&lt;T&gt;
-     */
-    public <T> void executeAsync(Call call, ApiCallback<T> callback) {
-        executeAsync(call, null, callback);
-    }
-
-    /**
-     * Execute HTTP call asynchronously.
-     *
-     * @see #execute(Call, Type)
-     * @param <T> Type
-     * @param call The callback to be executed when the API call finishes
-     * @param returnType Return type
-     * @param callback ApiCallback
-     */
-    @SuppressWarnings("unchecked")
-    public <T> void executeAsync(Call call, final Type returnType, final ApiCallback<T> callback) {
-        call.enqueue(new Callback() {
-            @Override
-            public void onFailure(Request request, IOException e) {
-                callback.onFailure(new ApiException(e), 0, null);
-            }
-
-            @Override
-            public void onResponse(Response response) throws IOException {
-                T result;
-                try {
-                    result = (T) handleResponse(response, returnType);
-                } catch (ApiException e) {
-                    callback.onFailure(e, response.code(), response.headers().toMultimap());
-                    return;
-                }
-                callback.onSuccess(result, response.code(), response.headers().toMultimap());
-            }
-        });
-    }
-
-    /**
-     * Handle the given response, return the deserialized object when the response is successful.
-     *
-     * @param <T> Type
-     * @param response Response
-     * @param returnType Return type
-     * @throws ApiException If the response has a unsuccessful status code or
-     *   fail to deserialize the response body
-     * @return Type
-     */
-    public <T> T handleResponse(Response response, Type returnType) throws ApiException {
-        if (response.isSuccessful()) {
-            if (returnType == null || response.code() == 204) {
-                // returning null if the returnType is not defined,
-                // or the status code is 204 (No Content)
-                if (response.body() != null) {
-                    try {
-                        response.body().close();
-                    } catch (IOException e) {
-                        throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
-                    }
-                }
-                return null;
-            } else {
-                return deserialize(response, returnType);
-            }
-        } else {
-            String respBody = null;
-            if (response.body() != null) {
-                try {
-                    respBody = response.body().string();
-                } catch (IOException e) {
-                    throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
-                }
-            }
-            throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody);
-        }
-    }
-
-    /**
-     * Build HTTP call with the given options.
-     *
-     * @param path The sub-path of the HTTP URL
-     * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
-     * @param queryParams The query parameters
-     * @param collectionQueryParams The collection query parameters
-     * @param body The request body object
-     * @param headerParams The header parameters
-     * @param formParams The form parameters
-     * @param authNames The authentications to apply
-     * @param progressRequestListener Progress request listener
-     * @return The HTTP call
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public Call buildCall(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Request request = buildRequest(path, method, queryParams, collectionQueryParams, body, headerParams, formParams, authNames, progressRequestListener);
-
-        return httpClient.newCall(request);
-    }
-
-    /**
-     * Build an HTTP request with the given options.
-     *
-     * @param path The sub-path of the HTTP URL
-     * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
-     * @param queryParams The query parameters
-     * @param collectionQueryParams The collection query parameters
-     * @param body The request body object
-     * @param headerParams The header parameters
-     * @param formParams The form parameters
-     * @param authNames The authentications to apply
-     * @param progressRequestListener Progress request listener
-     * @return The HTTP request
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public Request buildRequest(String path, String method, List<Pair> queryParams, List<Pair> collectionQueryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String[] authNames, ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        updateParamsForAuth(authNames, queryParams, headerParams);
-
-        final String url = buildUrl(path, queryParams, collectionQueryParams);
-        final Request.Builder reqBuilder = new Request.Builder().url(url);
-        processHeaderParams(headerParams, reqBuilder);
-
-        String contentType = (String) headerParams.get("Content-Type");
-        // ensuring a default content type
-        if (contentType == null) {
-            contentType = "application/json";
-        }
-
-        RequestBody reqBody;
-        if (!HttpMethod.permitsRequestBody(method)) {
-            reqBody = null;
-        } else if ("application/x-www-form-urlencoded".equals(contentType)) {
-            reqBody = buildRequestBodyFormEncoding(formParams);
-        } else if ("multipart/form-data".equals(contentType)) {
-            reqBody = buildRequestBodyMultipart(formParams);
-        } else if (body == null) {
-            if ("DELETE".equals(method)) {
-                // allow calling DELETE without sending a request body
-                reqBody = null;
-            } else {
-                // use an empty request body (for POST, PUT and PATCH)
-                reqBody = RequestBody.create(MediaType.parse(contentType), "");
-            }
-        } else {
-            reqBody = serialize(body, contentType);
-        }
-
-        Request request = null;
-
-        if(progressRequestListener != null && reqBody != null) {
-            ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, progressRequestListener);
-            request = reqBuilder.method(method, progressRequestBody).build();
-        } else {
-            request = reqBuilder.method(method, reqBody).build();
-        }
-
-        return request;
-    }
-
-    /**
-     * Build full URL by concatenating base path, the given sub path and query parameters.
-     *
-     * @param path The sub path
-     * @param queryParams The query parameters
-     * @param collectionQueryParams The collection query parameters
-     * @return The full URL
-     */
-    public String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams) {
-        final StringBuilder url = new StringBuilder();
-        url.append(basePath).append(path);
-
-        if (queryParams != null && !queryParams.isEmpty()) {
-            // support (constant) query string in `path`, e.g. "/posts?draft=1"
-            String prefix = path.contains("?") ? "&" : "?";
-            for (Pair param : queryParams) {
-                if (param.getValue() != null) {
-                    if (prefix != null) {
-                        url.append(prefix);
-                        prefix = null;
-                    } else {
-                        url.append("&");
-                    }
-                    String value = parameterToString(param.getValue());
-                    url.append(escapeString(param.getName())).append("=").append(escapeString(value));
-                }
-            }
-        }
-
-        if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) {
-            String prefix = url.toString().contains("?") ? "&" : "?";
-            for (Pair param : collectionQueryParams) {
-                if (param.getValue() != null) {
-                    if (prefix != null) {
-                        url.append(prefix);
-                        prefix = null;
-                    } else {
-                        url.append("&");
-                    }
-                    String value = parameterToString(param.getValue());
-                    // collection query parameter value already escaped as part of parameterToPairs
-                    url.append(escapeString(param.getName())).append("=").append(value);
-                }
-            }
-        }
-
-        return url.toString();
-    }
-
-    /**
-     * Set header parameters to the request builder, including default headers.
-     *
-     * @param headerParams Header parameters in the ofrm of Map
-     * @param reqBuilder Reqeust.Builder
-     */
-    public void processHeaderParams(Map<String, String> headerParams, Request.Builder reqBuilder) {
-        for (Entry<String, String> param : headerParams.entrySet()) {
-            reqBuilder.header(param.getKey(), parameterToString(param.getValue()));
-        }
-        for (Entry<String, String> header : defaultHeaderMap.entrySet()) {
-            if (!headerParams.containsKey(header.getKey())) {
-                reqBuilder.header(header.getKey(), parameterToString(header.getValue()));
-            }
-        }
-    }
-
-    /**
-     * Update query and header parameters based on authentication settings.
-     *
-     * @param authNames The authentications to apply
-     * @param queryParams  List of query parameters
-     * @param headerParams  Map of header parameters
-     */
-    public void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
-        for (String authName : authNames) {
-            Authentication auth = authentications.get(authName);
-            if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
-            auth.applyToParams(queryParams, headerParams);
-        }
-    }
-
-    /**
-     * Build a form-encoding request body with the given form parameters.
-     *
-     * @param formParams Form parameters in the form of Map
-     * @return RequestBody
-     */
-    public RequestBody buildRequestBodyFormEncoding(Map<String, Object> formParams) {
-        FormEncodingBuilder formBuilder  = new FormEncodingBuilder();
-        for (Entry<String, Object> param : formParams.entrySet()) {
-            formBuilder.add(param.getKey(), parameterToString(param.getValue()));
-        }
-        return formBuilder.build();
-    }
-
-    /**
-     * Build a multipart (file uploading) request body with the given form parameters,
-     * which could contain text fields and file fields.
-     *
-     * @param formParams Form parameters in the form of Map
-     * @return RequestBody
-     */
-    public RequestBody buildRequestBodyMultipart(Map<String, Object> formParams) {
-        MultipartBuilder mpBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
-        for (Entry<String, Object> param : formParams.entrySet()) {
-            if (param.getValue() instanceof File) {
-                File file = (File) param.getValue();
-                Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\"");
-                MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
-                mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file));
-            } else {
-                Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"");
-                mpBuilder.addPart(partHeaders, RequestBody.create(null, parameterToString(param.getValue())));
-            }
-        }
-        return mpBuilder.build();
-    }
-
-    /**
-     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
-     *
-     * @param file The given file
-     * @return The guessed Content-Type
-     */
-    public String guessContentTypeFromFile(File file) {
-        String contentType = URLConnection.guessContentTypeFromName(file.getName());
-        if (contentType == null) {
-            return "application/octet-stream";
-        } else {
-            return contentType;
-        }
-    }
-
-    /**
-     * Apply SSL related settings to httpClient according to the current values of
-     * verifyingSsl and sslCaCert.
-     */
-    private void applySslSettings() {
-        try {
-            TrustManager[] trustManagers = null;
-            HostnameVerifier hostnameVerifier = null;
-            if (!verifyingSsl) {
-                TrustManager trustAll = new X509TrustManager() {
-                    @Override
-                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
-                    @Override
-                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
-                    @Override
-                    public X509Certificate[] getAcceptedIssuers() { return null; }
-                };
-                SSLContext sslContext = SSLContext.getInstance("TLS");
-                trustManagers = new TrustManager[]{ trustAll };
-                hostnameVerifier = new HostnameVerifier() {
-                    @Override
-                    public boolean verify(String hostname, SSLSession session) { return true; }
-                };
-            } else if (sslCaCert != null) {
-                char[] password = null; // Any password will work.
-                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
-                Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(sslCaCert);
-                if (certificates.isEmpty()) {
-                    throw new IllegalArgumentException("expected non-empty set of trusted certificates");
-                }
-                KeyStore caKeyStore = newEmptyKeyStore(password);
-                int index = 0;
-                for (Certificate certificate : certificates) {
-                    String certificateAlias = "ca" + Integer.toString(index++);
-                    caKeyStore.setCertificateEntry(certificateAlias, certificate);
-                }
-                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                trustManagerFactory.init(caKeyStore);
-                trustManagers = trustManagerFactory.getTrustManagers();
-            }
-
-            if (keyManagers != null || trustManagers != null) {
-                SSLContext sslContext = SSLContext.getInstance("TLS");
-                sslContext.init(keyManagers, trustManagers, new SecureRandom());
-                httpClient.setSslSocketFactory(sslContext.getSocketFactory());
-            } else {
-                httpClient.setSslSocketFactory(null);
-            }
-            httpClient.setHostnameVerifier(hostnameVerifier);
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
-        try {
-            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-            keyStore.load(null, password);
-            return keyStore;
-        } catch (IOException e) {
-            throw new AssertionError(e);
-        }
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ApiException.java b/.java-stubs/src/main/java/io/swagger/client/ApiException.java
deleted file mode 100644
index 07739ce26f60cecdc29be1686aefa3855adf01fe..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ApiException.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import java.util.Map;
-import java.util.List;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class ApiException extends Exception {
-    private int code = 0;
-    private Map<String, List<String>> responseHeaders = null;
-    private String responseBody = null;
-
-    public ApiException() {}
-
-    public ApiException(Throwable throwable) {
-        super(throwable);
-    }
-
-    public ApiException(String message) {
-        super(message);
-    }
-
-    public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody) {
-        super(message, throwable);
-        this.code = code;
-        this.responseHeaders = responseHeaders;
-        this.responseBody = responseBody;
-    }
-
-    public ApiException(String message, int code, Map<String, List<String>> responseHeaders, String responseBody) {
-        this(message, (Throwable) null, code, responseHeaders, responseBody);
-    }
-
-    public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
-        this(message, throwable, code, responseHeaders, null);
-    }
-
-    public ApiException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
-        this((String) null, (Throwable) null, code, responseHeaders, responseBody);
-    }
-
-    public ApiException(int code, String message) {
-        super(message);
-        this.code = code;
-    }
-
-    public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
-        this(code, message);
-        this.responseHeaders = responseHeaders;
-        this.responseBody = responseBody;
-    }
-
-    /**
-     * Get the HTTP status code.
-     *
-     * @return HTTP status code
-     */
-    public int getCode() {
-        return code;
-    }
-
-    /**
-     * Get the HTTP response headers.
-     *
-     * @return A map of list of string
-     */
-    public Map<String, List<String>> getResponseHeaders() {
-        return responseHeaders;
-    }
-
-    /**
-     * Get the HTTP response body.
-     *
-     * @return Response body in the form of string
-     */
-    public String getResponseBody() {
-        return responseBody;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ApiResponse.java b/.java-stubs/src/main/java/io/swagger/client/ApiResponse.java
deleted file mode 100644
index c21ab49f1c7eb1dd7f0d851b2e8a1b3acb2d4b23..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ApiResponse.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * API response returned by API call.
- *
- * @param <T> The type of data that is deserialized from response body
- */
-public class ApiResponse<T> {
-    final private int statusCode;
-    final private Map<String, List<String>> headers;
-    final private T data;
-
-    /**
-     * @param statusCode The status code of HTTP response
-     * @param headers The headers of HTTP response
-     */
-    public ApiResponse(int statusCode, Map<String, List<String>> headers) {
-        this(statusCode, headers, null);
-    }
-
-    /**
-     * @param statusCode The status code of HTTP response
-     * @param headers The headers of HTTP response
-     * @param data The object deserialized from response bod
-     */
-    public ApiResponse(int statusCode, Map<String, List<String>> headers, T data) {
-        this.statusCode = statusCode;
-        this.headers = headers;
-        this.data = data;
-    }
-
-    public int getStatusCode() {
-        return statusCode;
-    }
-
-    public Map<String, List<String>> getHeaders() {
-        return headers;
-    }
-
-    public T getData() {
-        return data;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/Configuration.java b/.java-stubs/src/main/java/io/swagger/client/Configuration.java
deleted file mode 100644
index cd15f19cf1a6365b9a80f0f30e0859665e695d86..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/Configuration.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class Configuration {
-    private static ApiClient defaultApiClient = new ApiClient();
-
-    /**
-     * Get the default API client, which would be used when creating API
-     * instances without providing an API client.
-     *
-     * @return Default API client
-     */
-    public static ApiClient getDefaultApiClient() {
-        return defaultApiClient;
-    }
-
-    /**
-     * Set the default API client, which would be used when creating API
-     * instances without providing an API client.
-     *
-     * @param apiClient API client
-     */
-    public static void setDefaultApiClient(ApiClient apiClient) {
-        defaultApiClient = apiClient;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/GzipRequestInterceptor.java b/.java-stubs/src/main/java/io/swagger/client/GzipRequestInterceptor.java
deleted file mode 100644
index 8a91a68ede6b3190a9ccd77b986acb063b09d5fe..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/GzipRequestInterceptor.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import com.squareup.okhttp.*;
-import okio.Buffer;
-import okio.BufferedSink;
-import okio.GzipSink;
-import okio.Okio;
-
-import java.io.IOException;
-
-/**
- * Encodes request bodies using gzip.
- *
- * Taken from https://github.com/square/okhttp/issues/350
- */
-class GzipRequestInterceptor implements Interceptor {
-    @Override public Response intercept(Chain chain) throws IOException {
-        Request originalRequest = chain.request();
-        if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
-            return chain.proceed(originalRequest);
-        }
-
-        Request compressedRequest = originalRequest.newBuilder()
-                                                   .header("Content-Encoding", "gzip")
-                                                   .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body())))
-                                                   .build();
-        return chain.proceed(compressedRequest);
-    }
-
-    private RequestBody forceContentLength(final RequestBody requestBody) throws IOException {
-        final Buffer buffer = new Buffer();
-        requestBody.writeTo(buffer);
-        return new RequestBody() {
-            @Override
-            public MediaType contentType() {
-                return requestBody.contentType();
-            }
-
-            @Override
-            public long contentLength() {
-                return buffer.size();
-            }
-
-            @Override
-            public void writeTo(BufferedSink sink) throws IOException {
-                sink.write(buffer.snapshot());
-            }
-        };
-    }
-
-    private RequestBody gzip(final RequestBody body) {
-        return new RequestBody() {
-            @Override public MediaType contentType() {
-                return body.contentType();
-            }
-
-            @Override public long contentLength() {
-                return -1; // We don't know the compressed length in advance!
-            }
-
-            @Override public void writeTo(BufferedSink sink) throws IOException {
-                BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
-                body.writeTo(gzipSink);
-                gzipSink.close();
-            }
-        };
-    }
-}
\ No newline at end of file
diff --git a/.java-stubs/src/main/java/io/swagger/client/JSON.java b/.java-stubs/src/main/java/io/swagger/client/JSON.java
deleted file mode 100644
index 71ca4bdafa6a1119b8e1ef3a6ebcbd0773ce7187..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/JSON.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import io.gsonfire.GsonFireBuilder;
-import io.gsonfire.PostProcessor;
-import io.gsonfire.TypeSelector;
-import com.google.gson.JsonParseException;
-import com.google.gson.TypeAdapter;
-import com.google.gson.internal.bind.util.ISO8601Utils;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import org.threeten.bp.LocalDate;
-import org.threeten.bp.OffsetDateTime;
-import org.threeten.bp.format.DateTimeFormatter;
-
-import io.swagger.client.model.*;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.lang.reflect.Type;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Map;
-import java.util.HashMap;
-
-public class JSON {
-    private Gson gson;
-    private boolean isLenientOnJson = false;
-    private DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
-    private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
-    private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
-    private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
-
-    public static GsonBuilder createGson() {
-        GsonFireBuilder fireBuilder = new GsonFireBuilder()
-        ;
-        return fireBuilder.createGsonBuilder();
-    }
-
-    private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) {
-        JsonElement element = readElement.getAsJsonObject().get(discriminatorField);
-        if(null == element) {
-            throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">");
-        }
-        return element.getAsString();
-    }
-
-    private static <T> Class<? extends T> getClassByDiscriminator(Map<String, Class<? extends T>> classByDiscriminatorValue, String discriminatorValue) {
-        Class<? extends T> clazz = classByDiscriminatorValue.get(discriminatorValue.toUpperCase());
-        if(null == clazz) {
-            throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">");
-        }
-        return clazz;
-    }
-
-    public JSON() {
-        gson = createGson()
-            .registerTypeAdapter(Date.class, dateTypeAdapter)
-            .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
-            .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
-            .registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
-            .create();
-    }
-
-    /**
-     * Get Gson.
-     *
-     * @return Gson
-     */
-    public Gson getGson() {
-        return gson;
-    }
-
-    /**
-     * Set Gson.
-     *
-     * @param gson Gson
-     * @return JSON
-     */
-    public JSON setGson(Gson gson) {
-        this.gson = gson;
-        return this;
-    }
-
-    public JSON setLenientOnJson(boolean lenientOnJson) {
-        isLenientOnJson = lenientOnJson;
-        return this;
-    }
-
-    /**
-     * Serialize the given Java object into JSON string.
-     *
-     * @param obj Object
-     * @return String representation of the JSON
-     */
-    public String serialize(Object obj) {
-        return gson.toJson(obj);
-    }
-
-    /**
-     * Deserialize the given JSON string to Java object.
-     *
-     * @param <T>        Type
-     * @param body       The JSON string
-     * @param returnType The type to deserialize into
-     * @return The deserialized Java object
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T deserialize(String body, Type returnType) {
-        try {
-            if (isLenientOnJson) {
-                JsonReader jsonReader = new JsonReader(new StringReader(body));
-                // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
-                jsonReader.setLenient(true);
-                return gson.fromJson(jsonReader, returnType);
-            } else {
-                return gson.fromJson(body, returnType);
-            }
-        } catch (JsonParseException e) {
-            // Fallback processing when failed to parse JSON form response body:
-            // return the response body string directly for the String return type;
-            if (returnType.equals(String.class))
-                return (T) body;
-            else throw (e);
-        }
-    }
-
-    /**
-     * Gson TypeAdapter for JSR310 OffsetDateTime type
-     */
-    public static class OffsetDateTimeTypeAdapter extends TypeAdapter<OffsetDateTime> {
-
-        private DateTimeFormatter formatter;
-
-        public OffsetDateTimeTypeAdapter() {
-            this(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
-        }
-
-        public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) {
-            this.formatter = formatter;
-        }
-
-        public void setFormat(DateTimeFormatter dateFormat) {
-            this.formatter = dateFormat;
-        }
-
-        @Override
-        public void write(JsonWriter out, OffsetDateTime date) throws IOException {
-            if (date == null) {
-                out.nullValue();
-            } else {
-                out.value(formatter.format(date));
-            }
-        }
-
-        @Override
-        public OffsetDateTime read(JsonReader in) throws IOException {
-            switch (in.peek()) {
-                case NULL:
-                    in.nextNull();
-                    return null;
-                default:
-                    String date = in.nextString();
-                    if (date.endsWith("+0000")) {
-                        date = date.substring(0, date.length()-5) + "Z";
-                    }
-                    return OffsetDateTime.parse(date, formatter);
-            }
-        }
-    }
-
-    /**
-     * Gson TypeAdapter for JSR310 LocalDate type
-     */
-    public class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {
-
-        private DateTimeFormatter formatter;
-
-        public LocalDateTypeAdapter() {
-            this(DateTimeFormatter.ISO_LOCAL_DATE);
-        }
-
-        public LocalDateTypeAdapter(DateTimeFormatter formatter) {
-            this.formatter = formatter;
-        }
-
-        public void setFormat(DateTimeFormatter dateFormat) {
-            this.formatter = dateFormat;
-        }
-
-        @Override
-        public void write(JsonWriter out, LocalDate date) throws IOException {
-            if (date == null) {
-                out.nullValue();
-            } else {
-                out.value(formatter.format(date));
-            }
-        }
-
-        @Override
-        public LocalDate read(JsonReader in) throws IOException {
-            switch (in.peek()) {
-                case NULL:
-                    in.nextNull();
-                    return null;
-                default:
-                    String date = in.nextString();
-                    return LocalDate.parse(date, formatter);
-            }
-        }
-    }
-
-    public JSON setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
-        offsetDateTimeTypeAdapter.setFormat(dateFormat);
-        return this;
-    }
-
-    public JSON setLocalDateFormat(DateTimeFormatter dateFormat) {
-        localDateTypeAdapter.setFormat(dateFormat);
-        return this;
-    }
-
-    /**
-     * Gson TypeAdapter for java.sql.Date type
-     * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used
-     * (more efficient than SimpleDateFormat).
-     */
-    public static class SqlDateTypeAdapter extends TypeAdapter<java.sql.Date> {
-
-        private DateFormat dateFormat;
-
-        public SqlDateTypeAdapter() {
-        }
-
-        public SqlDateTypeAdapter(DateFormat dateFormat) {
-            this.dateFormat = dateFormat;
-        }
-
-        public void setFormat(DateFormat dateFormat) {
-            this.dateFormat = dateFormat;
-        }
-
-        @Override
-        public void write(JsonWriter out, java.sql.Date date) throws IOException {
-            if (date == null) {
-                out.nullValue();
-            } else {
-                String value;
-                if (dateFormat != null) {
-                    value = dateFormat.format(date);
-                } else {
-                    value = date.toString();
-                }
-                out.value(value);
-            }
-        }
-
-        @Override
-        public java.sql.Date read(JsonReader in) throws IOException {
-            switch (in.peek()) {
-                case NULL:
-                    in.nextNull();
-                    return null;
-                default:
-                    String date = in.nextString();
-                    try {
-                        if (dateFormat != null) {
-                            return new java.sql.Date(dateFormat.parse(date).getTime());
-                        }
-                        return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime());
-                    } catch (ParseException e) {
-                        throw new JsonParseException(e);
-                    }
-            }
-        }
-    }
-
-    /**
-     * Gson TypeAdapter for java.util.Date type
-     * If the dateFormat is null, ISO8601Utils will be used.
-     */
-    public static class DateTypeAdapter extends TypeAdapter<Date> {
-
-        private DateFormat dateFormat;
-
-        public DateTypeAdapter() {
-        }
-
-        public DateTypeAdapter(DateFormat dateFormat) {
-            this.dateFormat = dateFormat;
-        }
-
-        public void setFormat(DateFormat dateFormat) {
-            this.dateFormat = dateFormat;
-        }
-
-        @Override
-        public void write(JsonWriter out, Date date) throws IOException {
-            if (date == null) {
-                out.nullValue();
-            } else {
-                String value;
-                if (dateFormat != null) {
-                    value = dateFormat.format(date);
-                } else {
-                    value = ISO8601Utils.format(date, true);
-                }
-                out.value(value);
-            }
-        }
-
-        @Override
-        public Date read(JsonReader in) throws IOException {
-            try {
-                switch (in.peek()) {
-                    case NULL:
-                        in.nextNull();
-                        return null;
-                    default:
-                        String date = in.nextString();
-                        try {
-                            if (dateFormat != null) {
-                                return dateFormat.parse(date);
-                            }
-                            return ISO8601Utils.parse(date, new ParsePosition(0));
-                        } catch (ParseException e) {
-                            throw new JsonParseException(e);
-                        }
-                }
-            } catch (IllegalArgumentException e) {
-                throw new JsonParseException(e);
-            }
-        }
-    }
-
-    public JSON setDateFormat(DateFormat dateFormat) {
-        dateTypeAdapter.setFormat(dateFormat);
-        return this;
-    }
-
-    public JSON setSqlDateFormat(DateFormat dateFormat) {
-        sqlDateTypeAdapter.setFormat(dateFormat);
-        return this;
-    }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/Pair.java b/.java-stubs/src/main/java/io/swagger/client/Pair.java
deleted file mode 100644
index add9addaa269c9262d5c06ff71cef0a428443aa4..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/Pair.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class Pair {
-    private String name = "";
-    private String value = "";
-
-    public Pair (String name, String value) {
-        setName(name);
-        setValue(value);
-    }
-
-    private void setName(String name) {
-        if (!isValidString(name)) return;
-
-        this.name = name;
-    }
-
-    private void setValue(String value) {
-        if (!isValidString(value)) return;
-
-        this.value = value;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public String getValue() {
-        return this.value;
-    }
-
-    private boolean isValidString(String arg) {
-        if (arg == null) return false;
-        if (arg.trim().isEmpty()) return false;
-
-        return true;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ProgressRequestBody.java b/.java-stubs/src/main/java/io/swagger/client/ProgressRequestBody.java
deleted file mode 100644
index 0e68cbda8892f133e9faa65978075b790ec8adda..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ProgressRequestBody.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import com.squareup.okhttp.MediaType;
-import com.squareup.okhttp.RequestBody;
-
-import java.io.IOException;
-
-import okio.Buffer;
-import okio.BufferedSink;
-import okio.ForwardingSink;
-import okio.Okio;
-import okio.Sink;
-
-public class ProgressRequestBody extends RequestBody {
-
-    public interface ProgressRequestListener {
-        void onRequestProgress(long bytesWritten, long contentLength, boolean done);
-    }
-
-    private final RequestBody requestBody;
-
-    private final ProgressRequestListener progressListener;
-
-    public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) {
-        this.requestBody = requestBody;
-        this.progressListener = progressListener;
-    }
-
-    @Override
-    public MediaType contentType() {
-        return requestBody.contentType();
-    }
-
-    @Override
-    public long contentLength() throws IOException {
-        return requestBody.contentLength();
-    }
-
-    @Override
-    public void writeTo(BufferedSink sink) throws IOException {
-        BufferedSink bufferedSink = Okio.buffer(sink(sink));
-        requestBody.writeTo(bufferedSink);
-        bufferedSink.flush();
-    }
-
-    private Sink sink(Sink sink) {
-        return new ForwardingSink(sink) {
-
-            long bytesWritten = 0L;
-            long contentLength = 0L;
-
-            @Override
-            public void write(Buffer source, long byteCount) throws IOException {
-                super.write(source, byteCount);
-                if (contentLength == 0) {
-                    contentLength = contentLength();
-                }
-
-                bytesWritten += byteCount;
-                progressListener.onRequestProgress(bytesWritten, contentLength, bytesWritten == contentLength);
-            }
-        };
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/ProgressResponseBody.java b/.java-stubs/src/main/java/io/swagger/client/ProgressResponseBody.java
deleted file mode 100644
index 1e517d1d6db14a9dd6a250e679a2de8d395eb45f..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/ProgressResponseBody.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-import com.squareup.okhttp.MediaType;
-import com.squareup.okhttp.ResponseBody;
-
-import java.io.IOException;
-
-import okio.Buffer;
-import okio.BufferedSource;
-import okio.ForwardingSource;
-import okio.Okio;
-import okio.Source;
-
-public class ProgressResponseBody extends ResponseBody {
-
-    public interface ProgressListener {
-        void update(long bytesRead, long contentLength, boolean done);
-    }
-
-    private final ResponseBody responseBody;
-    private final ProgressListener progressListener;
-    private BufferedSource bufferedSource;
-
-    public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
-        this.responseBody = responseBody;
-        this.progressListener = progressListener;
-    }
-
-    @Override
-    public MediaType contentType() {
-        return responseBody.contentType();
-    }
-
-    @Override
-    public long contentLength() throws IOException {
-        return responseBody.contentLength();
-    }
-
-    @Override
-    public BufferedSource source() throws IOException {
-        if (bufferedSource == null) {
-            bufferedSource = Okio.buffer(source(responseBody.source()));
-        }
-        return bufferedSource;
-    }
-
-    private Source source(Source source) {
-        return new ForwardingSource(source) {
-            long totalBytesRead = 0L;
-
-            @Override
-            public long read(Buffer sink, long byteCount) throws IOException {
-                long bytesRead = super.read(sink, byteCount);
-                // read() returns the number of bytes read, or -1 if this source is exhausted.
-                totalBytesRead += bytesRead != -1 ? bytesRead : 0;
-                progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
-                return bytesRead;
-            }
-        };
-    }
-}
-
-
diff --git a/.java-stubs/src/main/java/io/swagger/client/StringUtil.java b/.java-stubs/src/main/java/io/swagger/client/StringUtil.java
deleted file mode 100644
index 03e061debebd40996ba42ccfa85ad9059bb7b631..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/StringUtil.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class StringUtil {
-  /**
-   * Check if the given array contains the given value (with case-insensitive comparison).
-   *
-   * @param array The array
-   * @param value The value to search
-   * @return true if the array contains the value
-   */
-  public static boolean containsIgnoreCase(String[] array, String value) {
-    for (String str : array) {
-      if (value == null && str == null) return true;
-      if (value != null && value.equalsIgnoreCase(str)) return true;
-    }
-    return false;
-  }
-
-  /**
-   * Join an array of strings with the given separator.
-   * <p>
-   * Note: This might be replaced by utility method from commons-lang or guava someday
-   * if one of those libraries is added as dependency.
-   * </p>
-   *
-   * @param array     The array of strings
-   * @param separator The separator
-   * @return the resulting string
-   */
-  public static String join(String[] array, String separator) {
-    int len = array.length;
-    if (len == 0) return "";
-
-    StringBuilder out = new StringBuilder();
-    out.append(array[0]);
-    for (int i = 1; i < len; i++) {
-      out.append(separator).append(array[i]);
-    }
-    return out.toString();
-  }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/AccessEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/AccessEndpointApi.java
deleted file mode 100644
index 758c64030dbfc5812a9b6de0e5438ec2e4e23dee..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/AccessEndpointApi.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import com.google.gson.reflect.TypeToken;
-import io.swagger.client.*;
-import io.swagger.client.model.DatabaseAccessDto;
-import io.swagger.client.model.DatabaseGiveAccessDto;
-import io.swagger.client.model.DatabaseModifyAccessDto;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AccessEndpointApi {
-    private ApiClient apiClient;
-
-    public AccessEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public AccessEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create1
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call create1Call(DatabaseGiveAccessDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/access"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call create1ValidateBeforeCall(DatabaseGiveAccessDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create1(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling create1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling create1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = create1Call(body, id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Give access to some database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object create1(DatabaseGiveAccessDto body, Long id, Long databaseId) throws ApiException {
-        ApiResponse<Object> resp = create1WithHttpInfo(body, id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Give access to some database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> create1WithHttpInfo(DatabaseGiveAccessDto body, Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = create1ValidateBeforeCall(body, id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Give access to some database (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call create1Async(DatabaseGiveAccessDto body, Long id, Long databaseId, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = create1ValidateBeforeCall(body, id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for find
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/access"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findValidateBeforeCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling find(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling find(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findCall(id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Check access to some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return DatabaseAccessDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public DatabaseAccessDto find(Long id, Long databaseId) throws ApiException {
-        ApiResponse<DatabaseAccessDto> resp = findWithHttpInfo(id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Check access to some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;DatabaseAccessDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<DatabaseAccessDto> findWithHttpInfo(Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = findValidateBeforeCall(id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<DatabaseAccessDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Check access to some database (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAsync(Long id, Long databaseId, final ApiCallback<DatabaseAccessDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findValidateBeforeCall(id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<DatabaseAccessDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for update
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call updateCall(DatabaseModifyAccessDto body, Long id, Long databaseId, String username, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/access/{username}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call updateValidateBeforeCall(DatabaseModifyAccessDto body, Long id, Long databaseId, String username, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling update(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling update(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling update(Async)");
-        }
-        // verify the required parameter 'username' is set
-        if (username == null) {
-            throw new ApiException("Missing the required parameter 'username' when calling update(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = updateCall(body, id, databaseId, username, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Modify access to some database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object update(DatabaseModifyAccessDto body, Long id, Long databaseId, String username) throws ApiException {
-        ApiResponse<Object> resp = updateWithHttpInfo(body, id, databaseId, username);
-        return resp.getData();
-    }
-
-    /**
-     * Modify access to some database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> updateWithHttpInfo(DatabaseModifyAccessDto body, Long id, Long databaseId, String username) throws ApiException {
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, username, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Modify access to some database (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call updateAsync(DatabaseModifyAccessDto body, Long id, Long databaseId, String username, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, username, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for update1
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call update1Call(Long id, Long databaseId, String username, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/access/{username}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call update1ValidateBeforeCall(Long id, Long databaseId, String username, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling update1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling update1(Async)");
-        }
-        // verify the required parameter 'username' is set
-        if (username == null) {
-            throw new ApiException("Missing the required parameter 'username' when calling update1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = update1Call(id, databaseId, username, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Revoke access to some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object update1(Long id, Long databaseId, String username) throws ApiException {
-        ApiResponse<Object> resp = update1WithHttpInfo(id, databaseId, username);
-        return resp.getData();
-    }
-
-    /**
-     * Revoke access to some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> update1WithHttpInfo(Long id, Long databaseId, String username) throws ApiException {
-        com.squareup.okhttp.Call call = update1ValidateBeforeCall(id, databaseId, username, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Revoke access to some database (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param username  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call update1Async(Long id, Long databaseId, String username, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = update1ValidateBeforeCall(id, databaseId, username, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/ContainerEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/ContainerEndpointApi.java
deleted file mode 100644
index 73100bca0a730e8d3f3a279d57cc8952f8634d5c..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/ContainerEndpointApi.java
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.ContainerBriefDto;
-import io.swagger.client.model.ContainerChangeDto;
-import io.swagger.client.model.ContainerCreateRequestDto;
-import io.swagger.client.model.ContainerDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ContainerEndpointApi {
-    private ApiClient apiClient;
-
-    public ContainerEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public ContainerEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create1
-     * @param body  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call create1Call(ContainerCreateRequestDto body, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container";
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call create1ValidateBeforeCall(ContainerCreateRequestDto body, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = create1Call(body, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Create container
-     * 
-     * @param body  (required)
-     * @return ContainerBriefDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ContainerBriefDto create1(ContainerCreateRequestDto body) throws ApiException {
-        ApiResponse<ContainerBriefDto> resp = create1WithHttpInfo(body);
-        return resp.getData();
-    }
-
-    /**
-     * Create container
-     * 
-     * @param body  (required)
-     * @return ApiResponse&lt;ContainerBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ContainerBriefDto> create1WithHttpInfo(ContainerCreateRequestDto body) throws ApiException {
-        com.squareup.okhttp.Call call = create1ValidateBeforeCall(body, null, null);
-        Type localVarReturnType = new TypeToken<ContainerBriefDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Create container (asynchronously)
-     * 
-     * @param body  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call create1Async(ContainerCreateRequestDto body, final ApiCallback<ContainerBriefDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = create1ValidateBeforeCall(body, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ContainerBriefDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for delete1
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call delete1Call(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call delete1ValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = delete1Call(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete some container
-     * 
-     * @param id  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object delete1(Long id) throws ApiException {
-        ApiResponse<Object> resp = delete1WithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * Delete some container
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> delete1WithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = delete1ValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Delete some container (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call delete1Async(Long id, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = delete1ValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findAll1
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findAll1Call(final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container";
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findAll1ValidateBeforeCall(final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        
-        com.squareup.okhttp.Call call = findAll1Call(progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find all containers
-     * 
-     * @return List&lt;ContainerBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<ContainerBriefDto> findAll1() throws ApiException {
-        ApiResponse<List<ContainerBriefDto>> resp = findAll1WithHttpInfo();
-        return resp.getData();
-    }
-
-    /**
-     * Find all containers
-     * 
-     * @return ApiResponse&lt;List&lt;ContainerBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<ContainerBriefDto>> findAll1WithHttpInfo() throws ApiException {
-        com.squareup.okhttp.Call call = findAll1ValidateBeforeCall(null, null);
-        Type localVarReturnType = new TypeToken<List<ContainerBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find all containers (asynchronously)
-     * 
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAll1Async(final ApiCallback<List<ContainerBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findAll1ValidateBeforeCall(progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<ContainerBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findById1
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findById1Call(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findById1ValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findById1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findById1Call(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find some container
-     * 
-     * @param id  (required)
-     * @return ContainerDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ContainerDto findById1(Long id) throws ApiException {
-        ApiResponse<ContainerDto> resp = findById1WithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * Find some container
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;ContainerDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ContainerDto> findById1WithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = findById1ValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<ContainerDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find some container (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findById1Async(Long id, final ApiCallback<ContainerDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findById1ValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ContainerDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for modify
-     * @param body  (required)
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call modifyCall(ContainerChangeDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call modifyValidateBeforeCall(ContainerChangeDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling modify(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling modify(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = modifyCall(body, id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Modify some container
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return ContainerBriefDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ContainerBriefDto modify(ContainerChangeDto body, Long id) throws ApiException {
-        ApiResponse<ContainerBriefDto> resp = modifyWithHttpInfo(body, id);
-        return resp.getData();
-    }
-
-    /**
-     * Modify some container
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return ApiResponse&lt;ContainerBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ContainerBriefDto> modifyWithHttpInfo(ContainerChangeDto body, Long id) throws ApiException {
-        com.squareup.okhttp.Call call = modifyValidateBeforeCall(body, id, null, null);
-        Type localVarReturnType = new TypeToken<ContainerBriefDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Modify some container (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call modifyAsync(ContainerChangeDto body, Long id, final ApiCallback<ContainerBriefDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = modifyValidateBeforeCall(body, id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ContainerBriefDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/DatabaseEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/DatabaseEndpointApi.java
deleted file mode 100644
index 3340f4523597bdd7b588c17f5225eba35b91cc46..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/DatabaseEndpointApi.java
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import com.google.gson.reflect.TypeToken;
-import io.swagger.client.*;
-import io.swagger.client.model.DatabaseBriefDto;
-import io.swagger.client.model.DatabaseCreateDto;
-import io.swagger.client.model.DatabaseDto;
-import io.swagger.client.model.DatabaseTransferDto;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class DatabaseEndpointApi {
-    private ApiClient apiClient;
-
-    public DatabaseEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public DatabaseEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create
-     * @param body  (required)
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call createCall(DatabaseCreateDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call createValidateBeforeCall(DatabaseCreateDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling create(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = createCall(body, id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Create database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return DatabaseBriefDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public DatabaseBriefDto create(DatabaseCreateDto body, Long id) throws ApiException {
-        ApiResponse<DatabaseBriefDto> resp = createWithHttpInfo(body, id);
-        return resp.getData();
-    }
-
-    /**
-     * Create database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return ApiResponse&lt;DatabaseBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<DatabaseBriefDto> createWithHttpInfo(DatabaseCreateDto body, Long id) throws ApiException {
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, null, null);
-        Type localVarReturnType = new TypeToken<DatabaseBriefDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Create database (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call createAsync(DatabaseCreateDto body, Long id, final ApiCallback<DatabaseBriefDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<DatabaseBriefDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for delete
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call deleteCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call deleteValidateBeforeCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling delete(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = deleteCall(id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object delete(Long id, Long databaseId) throws ApiException {
-        ApiResponse<Object> resp = deleteWithHttpInfo(id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Delete some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> deleteWithHttpInfo(Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Delete some database (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call deleteAsync(Long id, Long databaseId, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findById
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findByIdCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findByIdValidateBeforeCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findById(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling findById(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findByIdCall(id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return DatabaseDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public DatabaseDto findById(Long id, Long databaseId) throws ApiException {
-        ApiResponse<DatabaseDto> resp = findByIdWithHttpInfo(id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Find some database
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;DatabaseDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<DatabaseDto> findByIdWithHttpInfo(Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<DatabaseDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find some database (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findByIdAsync(Long id, Long databaseId, final ApiCallback<DatabaseDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<DatabaseDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for list
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call listCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call listValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling list(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = listCall(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * List databases
-     * 
-     * @param id  (required)
-     * @return List&lt;DatabaseBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<DatabaseBriefDto> list(Long id) throws ApiException {
-        ApiResponse<List<DatabaseBriefDto>> resp = listWithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * List databases
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;List&lt;DatabaseBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<DatabaseBriefDto>> listWithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = listValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<List<DatabaseBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * List databases (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call listAsync(Long id, final ApiCallback<List<DatabaseBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = listValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<DatabaseBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for transfer
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call transferCall(DatabaseTransferDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/transfer"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call transferValidateBeforeCall(DatabaseTransferDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling transfer(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling transfer(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling transfer(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = transferCall(body, id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Update database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return DatabaseDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public DatabaseDto transfer(DatabaseTransferDto body, Long id, Long databaseId) throws ApiException {
-        ApiResponse<DatabaseDto> resp = transferWithHttpInfo(body, id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Update database
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;DatabaseDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<DatabaseDto> transferWithHttpInfo(DatabaseTransferDto body, Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = transferValidateBeforeCall(body, id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<DatabaseDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Update database (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call transferAsync(DatabaseTransferDto body, Long id, Long databaseId, final ApiCallback<DatabaseDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = transferValidateBeforeCall(body, id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<DatabaseDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/ExportEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/ExportEndpointApi.java
deleted file mode 100644
index ad683313a9f7421e87c804a5e3af9d0b3ef3a308..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/ExportEndpointApi.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import java.io.File;
-import org.threeten.bp.OffsetDateTime;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ExportEndpointApi {
-    private ApiClient apiClient;
-
-    public ExportEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public ExportEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for export
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call exportCall(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/export"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (timestamp != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("timestamp", timestamp));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call exportValidateBeforeCall(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling export(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling export(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling export(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = exportCall(id, databaseId, tableId, timestamp, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Export table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @return File
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public File export(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp) throws ApiException {
-        ApiResponse<File> resp = exportWithHttpInfo(id, databaseId, tableId, timestamp);
-        return resp.getData();
-    }
-
-    /**
-     * Export table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @return ApiResponse&lt;File&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<File> exportWithHttpInfo(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp) throws ApiException {
-        com.squareup.okhttp.Call call = exportValidateBeforeCall(id, databaseId, tableId, timestamp, null, null);
-        Type localVarReturnType = new TypeToken<File>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Export table (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call exportAsync(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, final ApiCallback<File> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = exportValidateBeforeCall(id, databaseId, tableId, timestamp, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<File>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/ImageEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/ImageEndpointApi.java
deleted file mode 100644
index a80bd47bec9c1c0ad91e617fecd895d4a7cc3837..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/ImageEndpointApi.java
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.ImageBriefDto;
-import io.swagger.client.model.ImageChangeDto;
-import io.swagger.client.model.ImageCreateDto;
-import io.swagger.client.model.ImageDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ImageEndpointApi {
-    private ApiClient apiClient;
-
-    public ImageEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public ImageEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create
-     * @param body  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call createCall(ImageCreateDto body, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/image";
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call createValidateBeforeCall(ImageCreateDto body, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = createCall(body, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Create image
-     * 
-     * @param body  (required)
-     * @return ImageDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ImageDto create(ImageCreateDto body) throws ApiException {
-        ApiResponse<ImageDto> resp = createWithHttpInfo(body);
-        return resp.getData();
-    }
-
-    /**
-     * Create image
-     * 
-     * @param body  (required)
-     * @return ApiResponse&lt;ImageDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ImageDto> createWithHttpInfo(ImageCreateDto body) throws ApiException {
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, null, null);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Create image (asynchronously)
-     * 
-     * @param body  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call createAsync(ImageCreateDto body, final ApiCallback<ImageDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for delete
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call deleteCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/image/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call deleteValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = deleteCall(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete some image
-     * 
-     * @param id  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object delete(Long id) throws ApiException {
-        ApiResponse<Object> resp = deleteWithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * Delete some image
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> deleteWithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Delete some image (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call deleteAsync(Long id, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findAll
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findAllCall(final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/image";
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findAllValidateBeforeCall(final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        
-        com.squareup.okhttp.Call call = findAllCall(progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find all images
-     * 
-     * @return List&lt;ImageBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<ImageBriefDto> findAll() throws ApiException {
-        ApiResponse<List<ImageBriefDto>> resp = findAllWithHttpInfo();
-        return resp.getData();
-    }
-
-    /**
-     * Find all images
-     * 
-     * @return ApiResponse&lt;List&lt;ImageBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<ImageBriefDto>> findAllWithHttpInfo() throws ApiException {
-        com.squareup.okhttp.Call call = findAllValidateBeforeCall(null, null);
-        Type localVarReturnType = new TypeToken<List<ImageBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find all images (asynchronously)
-     * 
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAllAsync(final ApiCallback<List<ImageBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findAllValidateBeforeCall(progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<ImageBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findById
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findByIdCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/image/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findByIdValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findById(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findByIdCall(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find some image
-     * 
-     * @param id  (required)
-     * @return ImageDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ImageDto findById(Long id) throws ApiException {
-        ApiResponse<ImageDto> resp = findByIdWithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * Find some image
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;ImageDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ImageDto> findByIdWithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find some image (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findByIdAsync(Long id, final ApiCallback<ImageDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for update
-     * @param body  (required)
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call updateCall(ImageChangeDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/image/{id}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(com.squareup.okhttp.Interceptor.Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call updateValidateBeforeCall(ImageChangeDto body, Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling update(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling update(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = updateCall(body, id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Update some image
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return ImageDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ImageDto update(ImageChangeDto body, Long id) throws ApiException {
-        ApiResponse<ImageDto> resp = updateWithHttpInfo(body, id);
-        return resp.getData();
-    }
-
-    /**
-     * Update some image
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @return ApiResponse&lt;ImageDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ImageDto> updateWithHttpInfo(ImageChangeDto body, Long id) throws ApiException {
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, null, null);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Update some image (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call updateAsync(ImageChangeDto body, Long id, final ApiCallback<ImageDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ImageDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/LicenseEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/LicenseEndpointApi.java
deleted file mode 100644
index e500a03122a56a6a19c79d042d113020f7b4540a..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/LicenseEndpointApi.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import com.google.gson.reflect.TypeToken;
-import io.swagger.client.*;
-import io.swagger.client.model.LicenseDto;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class LicenseEndpointApi {
-    private ApiClient apiClient;
-
-    public LicenseEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public LicenseEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for list1
-     * @param id  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call list1Call(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/license"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] {  };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call list1ValidateBeforeCall(Long id, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling list1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = list1Call(id, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Get all licenses
-     * 
-     * @param id  (required)
-     * @return List&lt;LicenseDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<LicenseDto> list1(Long id) throws ApiException {
-        ApiResponse<List<LicenseDto>> resp = list1WithHttpInfo(id);
-        return resp.getData();
-    }
-
-    /**
-     * Get all licenses
-     * 
-     * @param id  (required)
-     * @return ApiResponse&lt;List&lt;LicenseDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<LicenseDto>> list1WithHttpInfo(Long id) throws ApiException {
-        com.squareup.okhttp.Call call = list1ValidateBeforeCall(id, null, null);
-        Type localVarReturnType = new TypeToken<List<LicenseDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Get all licenses (asynchronously)
-     * 
-     * @param id  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call list1Async(Long id, final ApiCallback<List<LicenseDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = list1ValidateBeforeCall(id, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<LicenseDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/QueryEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/QueryEndpointApi.java
deleted file mode 100644
index 51f09e889978f5e82c1e17d4c52f3e8548adb344..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/QueryEndpointApi.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.ExecuteStatementDto;
-import io.swagger.client.model.QueryResultDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class QueryEndpointApi {
-    private ApiClient apiClient;
-
-    public QueryEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public QueryEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for execute
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call executeCall(ExecuteStatementDto body, Long id, Long databaseId, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (page != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("page", page));
-        if (size != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("size", size));
-        if (sortDirection != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortDirection", sortDirection));
-        if (sortColumn != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortColumn", sortColumn));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call executeValidateBeforeCall(ExecuteStatementDto body, Long id, Long databaseId, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling execute(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling execute(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling execute(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = executeCall(body, id, databaseId, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Execute query
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return QueryResultDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryResultDto execute(ExecuteStatementDto body, Long id, Long databaseId, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        ApiResponse<QueryResultDto> resp = executeWithHttpInfo(body, id, databaseId, page, size, sortDirection, sortColumn);
-        return resp.getData();
-    }
-
-    /**
-     * Execute query
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return ApiResponse&lt;QueryResultDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryResultDto> executeWithHttpInfo(ExecuteStatementDto body, Long id, Long databaseId, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        com.squareup.okhttp.Call call = executeValidateBeforeCall(body, id, databaseId, page, size, sortDirection, sortColumn, null, null);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Execute query (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call executeAsync(ExecuteStatementDto body, Long id, Long databaseId, Long page, Long size, String sortDirection, String sortColumn, final ApiCallback<QueryResultDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = executeValidateBeforeCall(body, id, databaseId, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for export1
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param accept  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call export1Call(Long id, Long databaseId, Long queryId, String accept, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query/{queryId}/export"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "queryId" + "\\}", apiClient.escapeString(queryId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-        if (accept != null)
-        localVarHeaderParams.put("Accept", apiClient.parameterToString(accept));
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call export1ValidateBeforeCall(Long id, Long databaseId, Long queryId, String accept, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling export1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling export1(Async)");
-        }
-        // verify the required parameter 'queryId' is set
-        if (queryId == null) {
-            throw new ApiException("Missing the required parameter 'queryId' when calling export1(Async)");
-        }
-        // verify the required parameter 'accept' is set
-        if (accept == null) {
-            throw new ApiException("Missing the required parameter 'accept' when calling export1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = export1Call(id, databaseId, queryId, accept, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Exports some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param accept  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object export1(Long id, Long databaseId, Long queryId, String accept) throws ApiException {
-        ApiResponse<Object> resp = export1WithHttpInfo(id, databaseId, queryId, accept);
-        return resp.getData();
-    }
-
-    /**
-     * Exports some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param accept  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> export1WithHttpInfo(Long id, Long databaseId, Long queryId, String accept) throws ApiException {
-        com.squareup.okhttp.Call call = export1ValidateBeforeCall(id, databaseId, queryId, accept, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Exports some query (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param accept  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call export1Async(Long id, Long databaseId, Long queryId, String accept, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = export1ValidateBeforeCall(id, databaseId, queryId, accept, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for reExecute
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call reExecuteCall(Long id, Long databaseId, Long queryId, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query/{queryId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "queryId" + "\\}", apiClient.escapeString(queryId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (page != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("page", page));
-        if (size != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("size", size));
-        if (sortDirection != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortDirection", sortDirection));
-        if (sortColumn != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortColumn", sortColumn));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call reExecuteValidateBeforeCall(Long id, Long databaseId, Long queryId, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling reExecute(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling reExecute(Async)");
-        }
-        // verify the required parameter 'queryId' is set
-        if (queryId == null) {
-            throw new ApiException("Missing the required parameter 'queryId' when calling reExecute(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = reExecuteCall(id, databaseId, queryId, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Re-execute some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return QueryResultDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryResultDto reExecute(Long id, Long databaseId, Long queryId, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        ApiResponse<QueryResultDto> resp = reExecuteWithHttpInfo(id, databaseId, queryId, page, size, sortDirection, sortColumn);
-        return resp.getData();
-    }
-
-    /**
-     * Re-execute some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return ApiResponse&lt;QueryResultDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryResultDto> reExecuteWithHttpInfo(Long id, Long databaseId, Long queryId, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        com.squareup.okhttp.Call call = reExecuteValidateBeforeCall(id, databaseId, queryId, page, size, sortDirection, sortColumn, null, null);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Re-execute some query (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call reExecuteAsync(Long id, Long databaseId, Long queryId, Long page, Long size, String sortDirection, String sortColumn, final ApiCallback<QueryResultDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = reExecuteValidateBeforeCall(id, databaseId, queryId, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/StoreEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/StoreEndpointApi.java
deleted file mode 100644
index f2c58d09eb7cc2b07f779dd9c69363bab0a83562..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/StoreEndpointApi.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.QueryBriefDto;
-import io.swagger.client.model.QueryDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class StoreEndpointApi {
-    private ApiClient apiClient;
-
-    public StoreEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public StoreEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for find1
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call find1Call(Long id, Long databaseId, Long queryId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query/{queryId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "queryId" + "\\}", apiClient.escapeString(queryId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call find1ValidateBeforeCall(Long id, Long databaseId, Long queryId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling find1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling find1(Async)");
-        }
-        // verify the required parameter 'queryId' is set
-        if (queryId == null) {
-            throw new ApiException("Missing the required parameter 'queryId' when calling find1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = find1Call(id, databaseId, queryId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @return QueryDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryDto find1(Long id, Long databaseId, Long queryId) throws ApiException {
-        ApiResponse<QueryDto> resp = find1WithHttpInfo(id, databaseId, queryId);
-        return resp.getData();
-    }
-
-    /**
-     * Find some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @return ApiResponse&lt;QueryDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryDto> find1WithHttpInfo(Long id, Long databaseId, Long queryId) throws ApiException {
-        com.squareup.okhttp.Call call = find1ValidateBeforeCall(id, databaseId, queryId, null, null);
-        Type localVarReturnType = new TypeToken<QueryDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find some query (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call find1Async(Long id, Long databaseId, Long queryId, final ApiCallback<QueryDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = find1ValidateBeforeCall(id, databaseId, queryId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findAll1
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param persisted  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findAll1Call(Long id, Long databaseId, Boolean persisted, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (persisted != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("persisted", persisted));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findAll1ValidateBeforeCall(Long id, Long databaseId, Boolean persisted, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findAll1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling findAll1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findAll1Call(id, databaseId, persisted, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find queries
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param persisted  (optional)
-     * @return List&lt;QueryBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<QueryBriefDto> findAll1(Long id, Long databaseId, Boolean persisted) throws ApiException {
-        ApiResponse<List<QueryBriefDto>> resp = findAll1WithHttpInfo(id, databaseId, persisted);
-        return resp.getData();
-    }
-
-    /**
-     * Find queries
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param persisted  (optional)
-     * @return ApiResponse&lt;List&lt;QueryBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<QueryBriefDto>> findAll1WithHttpInfo(Long id, Long databaseId, Boolean persisted) throws ApiException {
-        com.squareup.okhttp.Call call = findAll1ValidateBeforeCall(id, databaseId, persisted, null, null);
-        Type localVarReturnType = new TypeToken<List<QueryBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find queries (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param persisted  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAll1Async(Long id, Long databaseId, Boolean persisted, final ApiCallback<List<QueryBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findAll1ValidateBeforeCall(id, databaseId, persisted, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<QueryBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for persist
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call persistCall(Long id, Long databaseId, Long queryId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/query/{queryId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "queryId" + "\\}", apiClient.escapeString(queryId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call persistValidateBeforeCall(Long id, Long databaseId, Long queryId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling persist(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling persist(Async)");
-        }
-        // verify the required parameter 'queryId' is set
-        if (queryId == null) {
-            throw new ApiException("Missing the required parameter 'queryId' when calling persist(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = persistCall(id, databaseId, queryId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Persist some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @return QueryDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryDto persist(Long id, Long databaseId, Long queryId) throws ApiException {
-        ApiResponse<QueryDto> resp = persistWithHttpInfo(id, databaseId, queryId);
-        return resp.getData();
-    }
-
-    /**
-     * Persist some query
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @return ApiResponse&lt;QueryDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryDto> persistWithHttpInfo(Long id, Long databaseId, Long queryId) throws ApiException {
-        com.squareup.okhttp.Call call = persistValidateBeforeCall(id, databaseId, queryId, null, null);
-        Type localVarReturnType = new TypeToken<QueryDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Persist some query (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param queryId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call persistAsync(Long id, Long databaseId, Long queryId, final ApiCallback<QueryDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = persistValidateBeforeCall(id, databaseId, queryId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/TableColumnEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/TableColumnEndpointApi.java
deleted file mode 100644
index d894bb32e256afbe4691bd98d1bd6a29eaf3beac..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/TableColumnEndpointApi.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.ColumnDto;
-import io.swagger.client.model.ColumnSemanticsUpdateDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class TableColumnEndpointApi {
-    private ApiClient apiClient;
-
-    public TableColumnEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public TableColumnEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for update
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param columnId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call updateCall(ColumnSemanticsUpdateDto body, Long id, Long databaseId, Long tableId, Long columnId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/column/{columnId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()))
-            .replaceAll("\\{" + "columnId" + "\\}", apiClient.escapeString(columnId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call updateValidateBeforeCall(ColumnSemanticsUpdateDto body, Long id, Long databaseId, Long tableId, Long columnId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling update(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling update(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling update(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling update(Async)");
-        }
-        // verify the required parameter 'columnId' is set
-        if (columnId == null) {
-            throw new ApiException("Missing the required parameter 'columnId' when calling update(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = updateCall(body, id, databaseId, tableId, columnId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Update a table column semantic mapping
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param columnId  (required)
-     * @return ColumnDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ColumnDto update(ColumnSemanticsUpdateDto body, Long id, Long databaseId, Long tableId, Long columnId) throws ApiException {
-        ApiResponse<ColumnDto> resp = updateWithHttpInfo(body, id, databaseId, tableId, columnId);
-        return resp.getData();
-    }
-
-    /**
-     * Update a table column semantic mapping
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param columnId  (required)
-     * @return ApiResponse&lt;ColumnDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ColumnDto> updateWithHttpInfo(ColumnSemanticsUpdateDto body, Long id, Long databaseId, Long tableId, Long columnId) throws ApiException {
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, tableId, columnId, null, null);
-        Type localVarReturnType = new TypeToken<ColumnDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Update a table column semantic mapping (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param columnId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call updateAsync(ColumnSemanticsUpdateDto body, Long id, Long databaseId, Long tableId, Long columnId, final ApiCallback<ColumnDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, tableId, columnId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ColumnDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/TableDataEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/TableDataEndpointApi.java
deleted file mode 100644
index ae981d3c3ce5b942d9ab6e2d881b48db45f6dc41..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/TableDataEndpointApi.java
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.ImportDto;
-import org.threeten.bp.OffsetDateTime;
-import io.swagger.client.model.QueryResultDto;
-import io.swagger.client.model.TableCsvDeleteDto;
-import io.swagger.client.model.TableCsvDto;
-import io.swagger.client.model.TableCsvUpdateDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class TableDataEndpointApi {
-    private ApiClient apiClient;
-
-    public TableDataEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public TableDataEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for delete1
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call delete1Call(TableCsvDeleteDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call delete1ValidateBeforeCall(TableCsvDeleteDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling delete1(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling delete1(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling delete1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = delete1Call(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public void delete1(TableCsvDeleteDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        delete1WithHttpInfo(body, id, databaseId, tableId);
-    }
-
-    /**
-     * Delete data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;Void&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Void> delete1WithHttpInfo(TableCsvDeleteDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = delete1ValidateBeforeCall(body, id, databaseId, tableId, null, null);
-        return apiClient.execute(call);
-    }
-
-    /**
-     * Delete data (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call delete1Async(TableCsvDeleteDto body, Long id, Long databaseId, Long tableId, final ApiCallback<Void> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = delete1ValidateBeforeCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        apiClient.executeAsync(call, callback);
-        return call;
-    }
-    /**
-     * Build call for getAll2
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call getAll2Call(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (timestamp != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("timestamp", timestamp));
-        if (page != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("page", page));
-        if (size != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("size", size));
-        if (sortDirection != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortDirection", sortDirection));
-        if (sortColumn != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortColumn", sortColumn));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "HEAD", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call getAll2ValidateBeforeCall(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling getAll2(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling getAll2(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling getAll2(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = getAll2Call(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return QueryResultDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryResultDto getAll2(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        ApiResponse<QueryResultDto> resp = getAll2WithHttpInfo(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn);
-        return resp.getData();
-    }
-
-    /**
-     * Find data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return ApiResponse&lt;QueryResultDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryResultDto> getAll2WithHttpInfo(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        com.squareup.okhttp.Call call = getAll2ValidateBeforeCall(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, null, null);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find data (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call getAll2Async(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ApiCallback<QueryResultDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = getAll2ValidateBeforeCall(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for getAll3
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call getAll3Call(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (timestamp != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("timestamp", timestamp));
-        if (page != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("page", page));
-        if (size != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("size", size));
-        if (sortDirection != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortDirection", sortDirection));
-        if (sortColumn != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("sortColumn", sortColumn));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call getAll3ValidateBeforeCall(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling getAll3(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling getAll3(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling getAll3(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = getAll3Call(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return QueryResultDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryResultDto getAll3(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        ApiResponse<QueryResultDto> resp = getAll3WithHttpInfo(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn);
-        return resp.getData();
-    }
-
-    /**
-     * Find data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @return ApiResponse&lt;QueryResultDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryResultDto> getAll3WithHttpInfo(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn) throws ApiException {
-        com.squareup.okhttp.Call call = getAll3ValidateBeforeCall(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, null, null);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find data (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param timestamp  (optional)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param sortDirection  (optional)
-     * @param sortColumn  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call getAll3Async(Long id, Long databaseId, Long tableId, OffsetDateTime timestamp, Long page, Long size, String sortDirection, String sortColumn, final ApiCallback<QueryResultDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = getAll3ValidateBeforeCall(id, databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for importCsv
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call importCsvCall(ImportDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data/import"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call importCsvValidateBeforeCall(ImportDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling importCsv(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling importCsv(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling importCsv(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling importCsv(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = importCsvCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Insert data from csv
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public void importCsv(ImportDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        importCsvWithHttpInfo(body, id, databaseId, tableId);
-    }
-
-    /**
-     * Insert data from csv
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;Void&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Void> importCsvWithHttpInfo(ImportDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = importCsvValidateBeforeCall(body, id, databaseId, tableId, null, null);
-        return apiClient.execute(call);
-    }
-
-    /**
-     * Insert data from csv (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call importCsvAsync(ImportDto body, Long id, Long databaseId, Long tableId, final ApiCallback<Void> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = importCsvValidateBeforeCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        apiClient.executeAsync(call, callback);
-        return call;
-    }
-    /**
-     * Build call for insert
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call insertCall(TableCsvDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call insertValidateBeforeCall(TableCsvDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling insert(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling insert(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling insert(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling insert(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = insertCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Insert data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public void insert(TableCsvDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        insertWithHttpInfo(body, id, databaseId, tableId);
-    }
-
-    /**
-     * Insert data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;Void&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Void> insertWithHttpInfo(TableCsvDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = insertValidateBeforeCall(body, id, databaseId, tableId, null, null);
-        return apiClient.execute(call);
-    }
-
-    /**
-     * Insert data (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call insertAsync(TableCsvDto body, Long id, Long databaseId, Long tableId, final ApiCallback<Void> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = insertValidateBeforeCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        apiClient.executeAsync(call, callback);
-        return call;
-    }
-    /**
-     * Build call for update
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call updateCall(TableCsvUpdateDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call updateValidateBeforeCall(TableCsvUpdateDto body, Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling update(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling update(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling update(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling update(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = updateCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Update data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public void update(TableCsvUpdateDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        updateWithHttpInfo(body, id, databaseId, tableId);
-    }
-
-    /**
-     * Update data
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;Void&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Void> updateWithHttpInfo(TableCsvUpdateDto body, Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, tableId, null, null);
-        return apiClient.execute(call);
-    }
-
-    /**
-     * Update data (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call updateAsync(TableCsvUpdateDto body, Long id, Long databaseId, Long tableId, final ApiCallback<Void> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = updateValidateBeforeCall(body, id, databaseId, tableId, progressListener, progressRequestListener);
-        apiClient.executeAsync(call, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/TableEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/TableEndpointApi.java
deleted file mode 100644
index 150c2fd765e990ad331facb804253e7fcb9f9812..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/TableEndpointApi.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.TableBriefDto;
-import io.swagger.client.model.TableCreateDto;
-import io.swagger.client.model.TableDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class TableEndpointApi {
-    private ApiClient apiClient;
-
-    public TableEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public TableEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call createCall(TableCreateDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call createValidateBeforeCall(TableCreateDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling create(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling create(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = createCall(body, id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Create a table
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return TableBriefDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public TableBriefDto create(TableCreateDto body, Long id, Long databaseId) throws ApiException {
-        ApiResponse<TableBriefDto> resp = createWithHttpInfo(body, id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Create a table
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;TableBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<TableBriefDto> createWithHttpInfo(TableCreateDto body, Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<TableBriefDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Create a table (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call createAsync(TableCreateDto body, Long id, Long databaseId, final ApiCallback<TableBriefDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<TableBriefDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for delete
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call deleteCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call deleteValidateBeforeCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling delete(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling delete(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = deleteCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete a table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public void delete(Long id, Long databaseId, Long tableId) throws ApiException {
-        deleteWithHttpInfo(id, databaseId, tableId);
-    }
-
-    /**
-     * Delete a table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;Void&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Void> deleteWithHttpInfo(Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, tableId, null, null);
-        return apiClient.execute(call);
-    }
-
-    /**
-     * Delete a table (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call deleteAsync(Long id, Long databaseId, Long tableId, final ApiCallback<Void> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        apiClient.executeAsync(call, callback);
-        return call;
-    }
-    /**
-     * Build call for findById
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findByIdCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findByIdValidateBeforeCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findById(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling findById(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling findById(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findByIdCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Get information about table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return TableDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public TableDto findById(Long id, Long databaseId, Long tableId) throws ApiException {
-        ApiResponse<TableDto> resp = findByIdWithHttpInfo(id, databaseId, tableId);
-        return resp.getData();
-    }
-
-    /**
-     * Get information about table
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;TableDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<TableDto> findByIdWithHttpInfo(Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, databaseId, tableId, null, null);
-        Type localVarReturnType = new TypeToken<TableDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Get information about table (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findByIdAsync(Long id, Long databaseId, Long tableId, final ApiCallback<TableDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findByIdValidateBeforeCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<TableDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for list
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call listCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call listValidateBeforeCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling list(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling list(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = listCall(id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * List all tables
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return List&lt;TableBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<TableBriefDto> list(Long id, Long databaseId) throws ApiException {
-        ApiResponse<List<TableBriefDto>> resp = listWithHttpInfo(id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * List all tables
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;List&lt;TableBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<TableBriefDto>> listWithHttpInfo(Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = listValidateBeforeCall(id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<List<TableBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * List all tables (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call listAsync(Long id, Long databaseId, final ApiCallback<List<TableBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = listValidateBeforeCall(id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<TableBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/TableHistoryEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/TableHistoryEndpointApi.java
deleted file mode 100644
index 6ee447dd9d59477f32247c6e4883476bb367eaf5..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/TableHistoryEndpointApi.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.TableHistoryDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class TableHistoryEndpointApi {
-    private ApiClient apiClient;
-
-    public TableHistoryEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public TableHistoryEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for getAll
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call getAllCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/history"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "HEAD", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call getAllValidateBeforeCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling getAll(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling getAll(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling getAll(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = getAllCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find all history
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return List&lt;TableHistoryDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<TableHistoryDto> getAll(Long id, Long databaseId, Long tableId) throws ApiException {
-        ApiResponse<List<TableHistoryDto>> resp = getAllWithHttpInfo(id, databaseId, tableId);
-        return resp.getData();
-    }
-
-    /**
-     * Find all history
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;List&lt;TableHistoryDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<TableHistoryDto>> getAllWithHttpInfo(Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = getAllValidateBeforeCall(id, databaseId, tableId, null, null);
-        Type localVarReturnType = new TypeToken<List<TableHistoryDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find all history (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call getAllAsync(Long id, Long databaseId, Long tableId, final ApiCallback<List<TableHistoryDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = getAllValidateBeforeCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<TableHistoryDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for getAll1
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call getAll1Call(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/table/{tableId}/history"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "tableId" + "\\}", apiClient.escapeString(tableId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call getAll1ValidateBeforeCall(Long id, Long databaseId, Long tableId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling getAll1(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling getAll1(Async)");
-        }
-        // verify the required parameter 'tableId' is set
-        if (tableId == null) {
-            throw new ApiException("Missing the required parameter 'tableId' when calling getAll1(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = getAll1Call(id, databaseId, tableId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find all history
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return List&lt;TableHistoryDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<TableHistoryDto> getAll1(Long id, Long databaseId, Long tableId) throws ApiException {
-        ApiResponse<List<TableHistoryDto>> resp = getAll1WithHttpInfo(id, databaseId, tableId);
-        return resp.getData();
-    }
-
-    /**
-     * Find all history
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @return ApiResponse&lt;List&lt;TableHistoryDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<TableHistoryDto>> getAll1WithHttpInfo(Long id, Long databaseId, Long tableId) throws ApiException {
-        com.squareup.okhttp.Call call = getAll1ValidateBeforeCall(id, databaseId, tableId, null, null);
-        Type localVarReturnType = new TypeToken<List<TableHistoryDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find all history (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param tableId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call getAll1Async(Long id, Long databaseId, Long tableId, final ApiCallback<List<TableHistoryDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = getAll1ValidateBeforeCall(id, databaseId, tableId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<TableHistoryDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/api/ViewEndpointApi.java b/.java-stubs/src/main/java/io/swagger/client/api/ViewEndpointApi.java
deleted file mode 100644
index 8594cb5e199aa5fb9327531b607999ad6a183f21..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/api/ViewEndpointApi.java
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.api;
-
-import io.swagger.client.ApiCallback;
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.ApiResponse;
-import io.swagger.client.Configuration;
-import io.swagger.client.Pair;
-import io.swagger.client.ProgressRequestBody;
-import io.swagger.client.ProgressResponseBody;
-
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-
-
-import io.swagger.client.model.ApiErrorDto;
-import io.swagger.client.model.QueryResultDto;
-import io.swagger.client.model.ViewBriefDto;
-import io.swagger.client.model.ViewCreateDto;
-import io.swagger.client.model.ViewDto;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ViewEndpointApi {
-    private ApiClient apiClient;
-
-    public ViewEndpointApi() {
-        this(Configuration.getDefaultApiClient());
-    }
-
-    public ViewEndpointApi(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    public ApiClient getApiClient() {
-        return apiClient;
-    }
-
-    public void setApiClient(ApiClient apiClient) {
-        this.apiClient = apiClient;
-    }
-
-    /**
-     * Build call for create
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call createCall(ViewCreateDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = body;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/view"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            "application/json"
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call createValidateBeforeCall(ViewCreateDto body, Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'body' is set
-        if (body == null) {
-            throw new ApiException("Missing the required parameter 'body' when calling create(Async)");
-        }
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling create(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling create(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = createCall(body, id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Create a view
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ViewBriefDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ViewBriefDto create(ViewCreateDto body, Long id, Long databaseId) throws ApiException {
-        ApiResponse<ViewBriefDto> resp = createWithHttpInfo(body, id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Create a view
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;ViewBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ViewBriefDto> createWithHttpInfo(ViewCreateDto body, Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<ViewBriefDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Create a view (asynchronously)
-     * 
-     * @param body  (required)
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call createAsync(ViewCreateDto body, Long id, Long databaseId, final ApiCallback<ViewBriefDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = createValidateBeforeCall(body, id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ViewBriefDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for data
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call dataCall(Long id, Long databaseId, Long viewId, Long page, Long size, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/view/{viewId}/data"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "viewId" + "\\}", apiClient.escapeString(viewId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-        if (page != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("page", page));
-        if (size != null)
-        localVarQueryParams.addAll(apiClient.parameterToPair("size", size));
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call dataValidateBeforeCall(Long id, Long databaseId, Long viewId, Long page, Long size, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling data(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling data(Async)");
-        }
-        // verify the required parameter 'viewId' is set
-        if (viewId == null) {
-            throw new ApiException("Missing the required parameter 'viewId' when calling data(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = dataCall(id, databaseId, viewId, page, size, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find view data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @return QueryResultDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public QueryResultDto data(Long id, Long databaseId, Long viewId, Long page, Long size) throws ApiException {
-        ApiResponse<QueryResultDto> resp = dataWithHttpInfo(id, databaseId, viewId, page, size);
-        return resp.getData();
-    }
-
-    /**
-     * Find view data
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @return ApiResponse&lt;QueryResultDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<QueryResultDto> dataWithHttpInfo(Long id, Long databaseId, Long viewId, Long page, Long size) throws ApiException {
-        com.squareup.okhttp.Call call = dataValidateBeforeCall(id, databaseId, viewId, page, size, null, null);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find view data (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param page  (optional)
-     * @param size  (optional)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call dataAsync(Long id, Long databaseId, Long viewId, Long page, Long size, final ApiCallback<QueryResultDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = dataValidateBeforeCall(id, databaseId, viewId, page, size, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<QueryResultDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for delete
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call deleteCall(Long id, Long databaseId, Long viewId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/view/{viewId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "viewId" + "\\}", apiClient.escapeString(viewId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call deleteValidateBeforeCall(Long id, Long databaseId, Long viewId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling delete(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling delete(Async)");
-        }
-        // verify the required parameter 'viewId' is set
-        if (viewId == null) {
-            throw new ApiException("Missing the required parameter 'viewId' when calling delete(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = deleteCall(id, databaseId, viewId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Delete one view
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @return Object
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public Object delete(Long id, Long databaseId, Long viewId) throws ApiException {
-        ApiResponse<Object> resp = deleteWithHttpInfo(id, databaseId, viewId);
-        return resp.getData();
-    }
-
-    /**
-     * Delete one view
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @return ApiResponse&lt;Object&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<Object> deleteWithHttpInfo(Long id, Long databaseId, Long viewId) throws ApiException {
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, viewId, null, null);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Delete one view (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call deleteAsync(Long id, Long databaseId, Long viewId, final ApiCallback<Object> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = deleteValidateBeforeCall(id, databaseId, viewId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<Object>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for find
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findCall(Long id, Long databaseId, Long viewId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/view/{viewId}"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()))
-            .replaceAll("\\{" + "viewId" + "\\}", apiClient.escapeString(viewId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findValidateBeforeCall(Long id, Long databaseId, Long viewId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling find(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling find(Async)");
-        }
-        // verify the required parameter 'viewId' is set
-        if (viewId == null) {
-            throw new ApiException("Missing the required parameter 'viewId' when calling find(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findCall(id, databaseId, viewId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find one view
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @return ViewDto
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ViewDto find(Long id, Long databaseId, Long viewId) throws ApiException {
-        ApiResponse<ViewDto> resp = findWithHttpInfo(id, databaseId, viewId);
-        return resp.getData();
-    }
-
-    /**
-     * Find one view
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @return ApiResponse&lt;ViewDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<ViewDto> findWithHttpInfo(Long id, Long databaseId, Long viewId) throws ApiException {
-        com.squareup.okhttp.Call call = findValidateBeforeCall(id, databaseId, viewId, null, null);
-        Type localVarReturnType = new TypeToken<ViewDto>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find one view (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param viewId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAsync(Long id, Long databaseId, Long viewId, final ApiCallback<ViewDto> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findValidateBeforeCall(id, databaseId, viewId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<ViewDto>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-    /**
-     * Build call for findAll
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param progressListener Progress listener
-     * @param progressRequestListener Progress request listener
-     * @return Call to execute
-     * @throws ApiException If fail to serialize the request body object
-     */
-    public com.squareup.okhttp.Call findAllCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        Object localVarPostBody = null;
-        
-        // create path and map variables
-        String localVarPath = "/api/container/{id}/database/{databaseId}/view"
-            .replaceAll("\\{" + "id" + "\\}", apiClient.escapeString(id.toString()))
-            .replaceAll("\\{" + "databaseId" + "\\}", apiClient.escapeString(databaseId.toString()));
-
-        List<Pair> localVarQueryParams = new ArrayList<Pair>();
-        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
-
-        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
-
-        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
-
-        final String[] localVarAccepts = {
-            "*/*"
-        };
-        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
-        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);
-
-        final String[] localVarContentTypes = {
-            
-        };
-        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
-        localVarHeaderParams.put("Content-Type", localVarContentType);
-
-        if(progressListener != null) {
-            apiClient.getHttpClient().networkInterceptors().add(new com.squareup.okhttp.Interceptor() {
-                @Override
-                public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
-                    com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
-                    return originalResponse.newBuilder()
-                    .body(new ProgressResponseBody(originalResponse.body(), progressListener))
-                    .build();
-                }
-            });
-        }
-
-        String[] localVarAuthNames = new String[] { "bearerAuth" };
-        return apiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, progressRequestListener);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private com.squareup.okhttp.Call findAllValidateBeforeCall(Long id, Long databaseId, final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
-        // verify the required parameter 'id' is set
-        if (id == null) {
-            throw new ApiException("Missing the required parameter 'id' when calling findAll(Async)");
-        }
-        // verify the required parameter 'databaseId' is set
-        if (databaseId == null) {
-            throw new ApiException("Missing the required parameter 'databaseId' when calling findAll(Async)");
-        }
-        
-        com.squareup.okhttp.Call call = findAllCall(id, databaseId, progressListener, progressRequestListener);
-        return call;
-
-        
-        
-        
-        
-    }
-
-    /**
-     * Find all views
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return List&lt;ViewBriefDto&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public List<ViewBriefDto> findAll(Long id, Long databaseId) throws ApiException {
-        ApiResponse<List<ViewBriefDto>> resp = findAllWithHttpInfo(id, databaseId);
-        return resp.getData();
-    }
-
-    /**
-     * Find all views
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @return ApiResponse&lt;List&lt;ViewBriefDto&gt;&gt;
-     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
-     */
-    public ApiResponse<List<ViewBriefDto>> findAllWithHttpInfo(Long id, Long databaseId) throws ApiException {
-        com.squareup.okhttp.Call call = findAllValidateBeforeCall(id, databaseId, null, null);
-        Type localVarReturnType = new TypeToken<List<ViewBriefDto>>(){}.getType();
-        return apiClient.execute(call, localVarReturnType);
-    }
-
-    /**
-     * Find all views (asynchronously)
-     * 
-     * @param id  (required)
-     * @param databaseId  (required)
-     * @param callback The callback to be executed when the API call finishes
-     * @return The request call
-     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
-     */
-    public com.squareup.okhttp.Call findAllAsync(Long id, Long databaseId, final ApiCallback<List<ViewBriefDto>> callback) throws ApiException {
-
-        ProgressResponseBody.ProgressListener progressListener = null;
-        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;
-
-        if (callback != null) {
-            progressListener = new ProgressResponseBody.ProgressListener() {
-                @Override
-                public void update(long bytesRead, long contentLength, boolean done) {
-                    callback.onDownloadProgress(bytesRead, contentLength, done);
-                }
-            };
-
-            progressRequestListener = new ProgressRequestBody.ProgressRequestListener() {
-                @Override
-                public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
-                    callback.onUploadProgress(bytesWritten, contentLength, done);
-                }
-            };
-        }
-
-        com.squareup.okhttp.Call call = findAllValidateBeforeCall(id, databaseId, progressListener, progressRequestListener);
-        Type localVarReturnType = new TypeToken<List<ViewBriefDto>>(){}.getType();
-        apiClient.executeAsync(call, localVarReturnType, callback);
-        return call;
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/auth/ApiKeyAuth.java b/.java-stubs/src/main/java/io/swagger/client/auth/ApiKeyAuth.java
deleted file mode 100644
index 5f828b277f1bdc1860d8cfa33eadf19ffb223cc7..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/auth/ApiKeyAuth.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.auth;
-
-import io.swagger.client.Pair;
-
-import java.util.Map;
-import java.util.List;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class ApiKeyAuth implements Authentication {
-  private final String location;
-  private final String paramName;
-
-  private String apiKey;
-  private String apiKeyPrefix;
-
-  public ApiKeyAuth(String location, String paramName) {
-    this.location = location;
-    this.paramName = paramName;
-  }
-
-  public String getLocation() {
-    return location;
-  }
-
-  public String getParamName() {
-    return paramName;
-  }
-
-  public String getApiKey() {
-    return apiKey;
-  }
-
-  public void setApiKey(String apiKey) {
-    this.apiKey = apiKey;
-  }
-
-  public String getApiKeyPrefix() {
-    return apiKeyPrefix;
-  }
-
-  public void setApiKeyPrefix(String apiKeyPrefix) {
-    this.apiKeyPrefix = apiKeyPrefix;
-  }
-
-  @Override
-  public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
-    if (apiKey == null) {
-      return;
-    }
-    String value;
-    if (apiKeyPrefix != null) {
-      value = apiKeyPrefix + " " + apiKey;
-    } else {
-      value = apiKey;
-    }
-    if ("query".equals(location)) {
-      queryParams.add(new Pair(paramName, value));
-    } else if ("header".equals(location)) {
-      headerParams.put(paramName, value);
-    }
-  }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/auth/Authentication.java b/.java-stubs/src/main/java/io/swagger/client/auth/Authentication.java
deleted file mode 100644
index a8b5052e6c9461d692ed5e745cc217ac42c51121..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/auth/Authentication.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.auth;
-
-import io.swagger.client.Pair;
-
-import java.util.Map;
-import java.util.List;
-
-public interface Authentication {
-    /**
-     * Apply authentication settings to header and query params.
-     *
-     * @param queryParams List of query parameters
-     * @param headerParams Map of header parameters
-     */
-    void applyToParams(List<Pair> queryParams, Map<String, String> headerParams);
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/auth/HttpBasicAuth.java b/.java-stubs/src/main/java/io/swagger/client/auth/HttpBasicAuth.java
deleted file mode 100644
index 9209b7ff8ca0f0caa68e39a6f8e92b3ca297f3f4..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/auth/HttpBasicAuth.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.auth;
-
-import io.swagger.client.Pair;
-
-import com.squareup.okhttp.Credentials;
-
-import java.util.Map;
-import java.util.List;
-
-import java.io.UnsupportedEncodingException;
-
-public class HttpBasicAuth implements Authentication {
-    private String username;
-    private String password;
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    @Override
-    public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
-        if (username == null && password == null) {
-            return;
-        }
-        headerParams.put("Authorization", Credentials.basic(
-            username == null ? "" : username,
-            password == null ? "" : password));
-    }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/auth/OAuth.java b/.java-stubs/src/main/java/io/swagger/client/auth/OAuth.java
deleted file mode 100644
index 57164a16c8b647a06cc5693d75fa8a382348425f..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/auth/OAuth.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.auth;
-
-import io.swagger.client.Pair;
-
-import java.util.Map;
-import java.util.List;
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")public class OAuth implements Authentication {
-  private String accessToken;
-
-  public String getAccessToken() {
-    return accessToken;
-  }
-
-  public void setAccessToken(String accessToken) {
-    this.accessToken = accessToken;
-  }
-
-  @Override
-  public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
-    if (accessToken != null) {
-      headerParams.put("Authorization", "Bearer " + accessToken);
-    }
-  }
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/auth/OAuthFlow.java b/.java-stubs/src/main/java/io/swagger/client/auth/OAuthFlow.java
deleted file mode 100644
index 28e8cf57687d2292547448cfb3eaa07be195257f..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/auth/OAuthFlow.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.auth;
-
-public enum OAuthFlow {
-    accessCode, implicit, password, application
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ApiErrorDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ApiErrorDto.java
deleted file mode 100644
index f41e594fe488582ecd4b2391134c44eb9e969ed6..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ApiErrorDto.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ApiErrorDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ApiErrorDto {
-  /**
-   * Gets or Sets status
-   */
-  @JsonAdapter(StatusEnum.Adapter.class)
-  public enum StatusEnum {
-    _100_CONTINUE("100 CONTINUE"),
-    _101_SWITCHING_PROTOCOLS("101 SWITCHING_PROTOCOLS"),
-    _102_PROCESSING("102 PROCESSING"),
-    _103_CHECKPOINT("103 CHECKPOINT"),
-    _200_OK("200 OK"),
-    _201_CREATED("201 CREATED"),
-    _202_ACCEPTED("202 ACCEPTED"),
-    _203_NON_AUTHORITATIVE_INFORMATION("203 NON_AUTHORITATIVE_INFORMATION"),
-    _204_NO_CONTENT("204 NO_CONTENT"),
-    _205_RESET_CONTENT("205 RESET_CONTENT"),
-    _206_PARTIAL_CONTENT("206 PARTIAL_CONTENT"),
-    _207_MULTI_STATUS("207 MULTI_STATUS"),
-    _208_ALREADY_REPORTED("208 ALREADY_REPORTED"),
-    _226_IM_USED("226 IM_USED"),
-    _300_MULTIPLE_CHOICES("300 MULTIPLE_CHOICES"),
-    _301_MOVED_PERMANENTLY("301 MOVED_PERMANENTLY"),
-    _302_FOUND("302 FOUND"),
-    _302_MOVED_TEMPORARILY("302 MOVED_TEMPORARILY"),
-    _303_SEE_OTHER("303 SEE_OTHER"),
-    _304_NOT_MODIFIED("304 NOT_MODIFIED"),
-    _305_USE_PROXY("305 USE_PROXY"),
-    _307_TEMPORARY_REDIRECT("307 TEMPORARY_REDIRECT"),
-    _308_PERMANENT_REDIRECT("308 PERMANENT_REDIRECT"),
-    _400_BAD_REQUEST("400 BAD_REQUEST"),
-    _401_UNAUTHORIZED("401 UNAUTHORIZED"),
-    _402_PAYMENT_REQUIRED("402 PAYMENT_REQUIRED"),
-    _403_FORBIDDEN("403 FORBIDDEN"),
-    _404_NOT_FOUND("404 NOT_FOUND"),
-    _405_METHOD_NOT_ALLOWED("405 METHOD_NOT_ALLOWED"),
-    _406_NOT_ACCEPTABLE("406 NOT_ACCEPTABLE"),
-    _407_PROXY_AUTHENTICATION_REQUIRED("407 PROXY_AUTHENTICATION_REQUIRED"),
-    _408_REQUEST_TIMEOUT("408 REQUEST_TIMEOUT"),
-    _409_CONFLICT("409 CONFLICT"),
-    _410_GONE("410 GONE"),
-    _411_LENGTH_REQUIRED("411 LENGTH_REQUIRED"),
-    _412_PRECONDITION_FAILED("412 PRECONDITION_FAILED"),
-    _413_PAYLOAD_TOO_LARGE("413 PAYLOAD_TOO_LARGE"),
-    _413_REQUEST_ENTITY_TOO_LARGE("413 REQUEST_ENTITY_TOO_LARGE"),
-    _414_URI_TOO_LONG("414 URI_TOO_LONG"),
-    _414_REQUEST_URI_TOO_LONG("414 REQUEST_URI_TOO_LONG"),
-    _415_UNSUPPORTED_MEDIA_TYPE("415 UNSUPPORTED_MEDIA_TYPE"),
-    _416_REQUESTED_RANGE_NOT_SATISFIABLE("416 REQUESTED_RANGE_NOT_SATISFIABLE"),
-    _417_EXPECTATION_FAILED("417 EXPECTATION_FAILED"),
-    _418_I_AM_A_TEAPOT("418 I_AM_A_TEAPOT"),
-    _419_INSUFFICIENT_SPACE_ON_RESOURCE("419 INSUFFICIENT_SPACE_ON_RESOURCE"),
-    _420_METHOD_FAILURE("420 METHOD_FAILURE"),
-    _421_DESTINATION_LOCKED("421 DESTINATION_LOCKED"),
-    _422_UNPROCESSABLE_ENTITY("422 UNPROCESSABLE_ENTITY"),
-    _423_LOCKED("423 LOCKED"),
-    _424_FAILED_DEPENDENCY("424 FAILED_DEPENDENCY"),
-    _425_TOO_EARLY("425 TOO_EARLY"),
-    _426_UPGRADE_REQUIRED("426 UPGRADE_REQUIRED"),
-    _428_PRECONDITION_REQUIRED("428 PRECONDITION_REQUIRED"),
-    _429_TOO_MANY_REQUESTS("429 TOO_MANY_REQUESTS"),
-    _431_REQUEST_HEADER_FIELDS_TOO_LARGE("431 REQUEST_HEADER_FIELDS_TOO_LARGE"),
-    _451_UNAVAILABLE_FOR_LEGAL_REASONS("451 UNAVAILABLE_FOR_LEGAL_REASONS"),
-    _500_INTERNAL_SERVER_ERROR("500 INTERNAL_SERVER_ERROR"),
-    _501_NOT_IMPLEMENTED("501 NOT_IMPLEMENTED"),
-    _502_BAD_GATEWAY("502 BAD_GATEWAY"),
-    _503_SERVICE_UNAVAILABLE("503 SERVICE_UNAVAILABLE"),
-    _504_GATEWAY_TIMEOUT("504 GATEWAY_TIMEOUT"),
-    _505_HTTP_VERSION_NOT_SUPPORTED("505 HTTP_VERSION_NOT_SUPPORTED"),
-    _506_VARIANT_ALSO_NEGOTIATES("506 VARIANT_ALSO_NEGOTIATES"),
-    _507_INSUFFICIENT_STORAGE("507 INSUFFICIENT_STORAGE"),
-    _508_LOOP_DETECTED("508 LOOP_DETECTED"),
-    _509_BANDWIDTH_LIMIT_EXCEEDED("509 BANDWIDTH_LIMIT_EXCEEDED"),
-    _510_NOT_EXTENDED("510 NOT_EXTENDED"),
-    _511_NETWORK_AUTHENTICATION_REQUIRED("511 NETWORK_AUTHENTICATION_REQUIRED");
-
-    private String value;
-
-    StatusEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static StatusEnum fromValue(String input) {
-      for (StatusEnum b : StatusEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<StatusEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final StatusEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public StatusEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return StatusEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("status")
-  private StatusEnum status = null;
-
-  @SerializedName("message")
-  private String message = null;
-
-  @SerializedName("code")
-  private String code = null;
-
-  public ApiErrorDto status(StatusEnum status) {
-    this.status = status;
-    return this;
-  }
-
-   /**
-   * Get status
-   * @return status
-  **/
-  @Schema(example = "NOT_FOUND", required = true, description = "")
-  public StatusEnum getStatus() {
-    return status;
-  }
-
-  public void setStatus(StatusEnum status) {
-    this.status = status;
-  }
-
-  public ApiErrorDto message(String message) {
-    this.message = message;
-    return this;
-  }
-
-   /**
-   * Get message
-   * @return message
-  **/
-  @Schema(example = "Could not find container", required = true, description = "")
-  public String getMessage() {
-    return message;
-  }
-
-  public void setMessage(String message) {
-    this.message = message;
-  }
-
-  public ApiErrorDto code(String code) {
-    this.code = code;
-    return this;
-  }
-
-   /**
-   * Get code
-   * @return code
-  **/
-  @Schema(example = "error.container.notfound", required = true, description = "")
-  public String getCode() {
-    return code;
-  }
-
-  public void setCode(String code) {
-    this.code = code;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ApiErrorDto apiErrorDto = (ApiErrorDto) o;
-    return Objects.equals(this.status, apiErrorDto.status) &&
-        Objects.equals(this.message, apiErrorDto.message) &&
-        Objects.equals(this.code, apiErrorDto.code);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(status, message, code);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ApiErrorDto {\n");
-    
-    sb.append("    status: ").append(toIndentedString(status)).append("\n");
-    sb.append("    message: ").append(toIndentedString(message)).append("\n");
-    sb.append("    code: ").append(toIndentedString(code)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ColumnCreateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ColumnCreateDto.java
deleted file mode 100644
index d3e868c8c81b6e787bd54cbf71e35f33c7cac130..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ColumnCreateDto.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * ColumnCreateDto
- */
-
-public class ColumnCreateDto {
-  @SerializedName("name")
-  private String name = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    ENUM("enum"),
-    NUMBER("number"),
-    DECIMAL("decimal"),
-    STRING("string"),
-    TEXT("text"),
-    BOOLEAN("boolean"),
-    DATE("date"),
-    TIMESTAMP("timestamp"),
-    BLOB("blob");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  @SerializedName("dfid")
-  private Long dfid = null;
-
-  @SerializedName("unique")
-  private Boolean unique = null;
-
-  @SerializedName("references")
-  private String references = null;
-
-  @SerializedName("primary_key")
-  private Boolean primaryKey = null;
-
-  @SerializedName("null_allowed")
-  private Boolean nullAllowed = null;
-
-  @SerializedName("check_expression")
-  private String checkExpression = null;
-
-  @SerializedName("foreign_key")
-  private String foreignKey = null;
-
-  @SerializedName("enum_values")
-  private List<String> enumValues = null;
-
-  public ColumnCreateDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Date", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ColumnCreateDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(example = "string", required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public ColumnCreateDto dfid(Long dfid) {
-    this.dfid = dfid;
-    return this;
-  }
-
-   /**
-   * date format id
-   * @return dfid
-  **/
-  @Schema(description = "date format id")
-  public Long getDfid() {
-    return dfid;
-  }
-
-  public void setDfid(Long dfid) {
-    this.dfid = dfid;
-  }
-
-  public ColumnCreateDto unique(Boolean unique) {
-    this.unique = unique;
-    return this;
-  }
-
-   /**
-   * Get unique
-   * @return unique
-  **/
-  @Schema(example = "false", required = true, description = "")
-  public Boolean isUnique() {
-    return unique;
-  }
-
-  public void setUnique(Boolean unique) {
-    this.unique = unique;
-  }
-
-  public ColumnCreateDto references(String references) {
-    this.references = references;
-    return this;
-  }
-
-   /**
-   * foreign key reference, only considered when foreignKey !&#x3D; null
-   * @return references
-  **/
-  @Schema(description = "foreign key reference, only considered when foreignKey != null")
-  public String getReferences() {
-    return references;
-  }
-
-  public void setReferences(String references) {
-    this.references = references;
-  }
-
-  public ColumnCreateDto primaryKey(Boolean primaryKey) {
-    this.primaryKey = primaryKey;
-    return this;
-  }
-
-   /**
-   * Get primaryKey
-   * @return primaryKey
-  **/
-  @Schema(example = "false", required = true, description = "")
-  public Boolean isPrimaryKey() {
-    return primaryKey;
-  }
-
-  public void setPrimaryKey(Boolean primaryKey) {
-    this.primaryKey = primaryKey;
-  }
-
-  public ColumnCreateDto nullAllowed(Boolean nullAllowed) {
-    this.nullAllowed = nullAllowed;
-    return this;
-  }
-
-   /**
-   * Get nullAllowed
-   * @return nullAllowed
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isNullAllowed() {
-    return nullAllowed;
-  }
-
-  public void setNullAllowed(Boolean nullAllowed) {
-    this.nullAllowed = nullAllowed;
-  }
-
-  public ColumnCreateDto checkExpression(String checkExpression) {
-    this.checkExpression = checkExpression;
-    return this;
-  }
-
-   /**
-   * check constraint
-   * @return checkExpression
-  **/
-  @Schema(example = "id > 0", description = "check constraint")
-  public String getCheckExpression() {
-    return checkExpression;
-  }
-
-  public void setCheckExpression(String checkExpression) {
-    this.checkExpression = checkExpression;
-  }
-
-  public ColumnCreateDto foreignKey(String foreignKey) {
-    this.foreignKey = foreignKey;
-    return this;
-  }
-
-   /**
-   * Get foreignKey
-   * @return foreignKey
-  **/
-  @Schema(description = "")
-  public String getForeignKey() {
-    return foreignKey;
-  }
-
-  public void setForeignKey(String foreignKey) {
-    this.foreignKey = foreignKey;
-  }
-
-  public ColumnCreateDto enumValues(List<String> enumValues) {
-    this.enumValues = enumValues;
-    return this;
-  }
-
-  public ColumnCreateDto addEnumValuesItem(String enumValuesItem) {
-    if (this.enumValues == null) {
-      this.enumValues = new ArrayList<String>();
-    }
-    this.enumValues.add(enumValuesItem);
-    return this;
-  }
-
-   /**
-   * enum values, only considered when type &#x3D; ENUM
-   * @return enumValues
-  **/
-  @Schema(description = "enum values, only considered when type = ENUM")
-  public List<String> getEnumValues() {
-    return enumValues;
-  }
-
-  public void setEnumValues(List<String> enumValues) {
-    this.enumValues = enumValues;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ColumnCreateDto columnCreateDto = (ColumnCreateDto) o;
-    return Objects.equals(this.name, columnCreateDto.name) &&
-        Objects.equals(this.type, columnCreateDto.type) &&
-        Objects.equals(this.dfid, columnCreateDto.dfid) &&
-        Objects.equals(this.unique, columnCreateDto.unique) &&
-        Objects.equals(this.references, columnCreateDto.references) &&
-        Objects.equals(this.primaryKey, columnCreateDto.primaryKey) &&
-        Objects.equals(this.nullAllowed, columnCreateDto.nullAllowed) &&
-        Objects.equals(this.checkExpression, columnCreateDto.checkExpression) &&
-        Objects.equals(this.foreignKey, columnCreateDto.foreignKey) &&
-        Objects.equals(this.enumValues, columnCreateDto.enumValues);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(name, type, dfid, unique, references, primaryKey, nullAllowed, checkExpression, foreignKey, enumValues);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ColumnCreateDto {\n");
-    
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    dfid: ").append(toIndentedString(dfid)).append("\n");
-    sb.append("    unique: ").append(toIndentedString(unique)).append("\n");
-    sb.append("    references: ").append(toIndentedString(references)).append("\n");
-    sb.append("    primaryKey: ").append(toIndentedString(primaryKey)).append("\n");
-    sb.append("    nullAllowed: ").append(toIndentedString(nullAllowed)).append("\n");
-    sb.append("    checkExpression: ").append(toIndentedString(checkExpression)).append("\n");
-    sb.append("    foreignKey: ").append(toIndentedString(foreignKey)).append("\n");
-    sb.append("    enumValues: ").append(toIndentedString(enumValues)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ColumnDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ColumnDto.java
deleted file mode 100644
index cef0e04f2c781bd6f313dff548160ad7fc131558..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ColumnDto.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ConceptDto;
-import io.swagger.client.model.ImageDateDto;
-import io.swagger.client.model.UnitDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * ColumnDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class ColumnDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("concept")
-  private ConceptDto concept = null;
-
-  @SerializedName("unit")
-  private UnitDto unit = null;
-
-  @SerializedName("unique")
-  private Boolean unique = null;
-
-  @SerializedName("references")
-  private String references = null;
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  @SerializedName("date_format")
-  private ImageDateDto dateFormat = null;
-
-  @SerializedName("auto_generated")
-  private Boolean autoGenerated = null;
-
-  @SerializedName("is_primary_key")
-  private Boolean isPrimaryKey = null;
-
-  /**
-   * Gets or Sets columnType
-   */
-  @JsonAdapter(ColumnTypeEnum.Adapter.class)
-  public enum ColumnTypeEnum {
-    ENUM("enum"),
-    NUMBER("number"),
-    DECIMAL("decimal"),
-    STRING("string"),
-    TEXT("text"),
-    BOOLEAN("boolean"),
-    DATE("date"),
-    TIMESTAMP("timestamp"),
-    BLOB("blob");
-
-    private String value;
-
-    ColumnTypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static ColumnTypeEnum fromValue(String input) {
-      for (ColumnTypeEnum b : ColumnTypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<ColumnTypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final ColumnTypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public ColumnTypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return ColumnTypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("column_type")
-  private ColumnTypeEnum columnType = null;
-
-  @SerializedName("is_null_allowed")
-  private Boolean isNullAllowed = null;
-
-  @SerializedName("check_expression")
-  private String checkExpression = null;
-
-  @SerializedName("foreign_key")
-  private String foreignKey = null;
-
-  @SerializedName("enum_values")
-  private List<String> enumValues = null;
-
-  public ColumnDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ColumnDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Date", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ColumnDto concept(ConceptDto concept) {
-    this.concept = concept;
-    return this;
-  }
-
-   /**
-   * Get concept
-   * @return concept
-  **/
-  @Schema(description = "")
-  public ConceptDto getConcept() {
-    return concept;
-  }
-
-  public void setConcept(ConceptDto concept) {
-    this.concept = concept;
-  }
-
-  public ColumnDto unit(UnitDto unit) {
-    this.unit = unit;
-    return this;
-  }
-
-   /**
-   * Get unit
-   * @return unit
-  **/
-  @Schema(description = "")
-  public UnitDto getUnit() {
-    return unit;
-  }
-
-  public void setUnit(UnitDto unit) {
-    this.unit = unit;
-  }
-
-  public ColumnDto unique(Boolean unique) {
-    this.unique = unique;
-    return this;
-  }
-
-   /**
-   * Get unique
-   * @return unique
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isUnique() {
-    return unique;
-  }
-
-  public void setUnique(Boolean unique) {
-    this.unique = unique;
-  }
-
-  public ColumnDto references(String references) {
-    this.references = references;
-    return this;
-  }
-
-   /**
-   * Get references
-   * @return references
-  **/
-  @Schema(description = "")
-  public String getReferences() {
-    return references;
-  }
-
-  public void setReferences(String references) {
-    this.references = references;
-  }
-
-  public ColumnDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "mdb_date", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public ColumnDto dateFormat(ImageDateDto dateFormat) {
-    this.dateFormat = dateFormat;
-    return this;
-  }
-
-   /**
-   * Get dateFormat
-   * @return dateFormat
-  **/
-  @Schema(description = "")
-  public ImageDateDto getDateFormat() {
-    return dateFormat;
-  }
-
-  public void setDateFormat(ImageDateDto dateFormat) {
-    this.dateFormat = dateFormat;
-  }
-
-  public ColumnDto autoGenerated(Boolean autoGenerated) {
-    this.autoGenerated = autoGenerated;
-    return this;
-  }
-
-   /**
-   * Get autoGenerated
-   * @return autoGenerated
-  **/
-  @Schema(example = "false", required = true, description = "")
-  public Boolean isAutoGenerated() {
-    return autoGenerated;
-  }
-
-  public void setAutoGenerated(Boolean autoGenerated) {
-    this.autoGenerated = autoGenerated;
-  }
-
-  public ColumnDto isPrimaryKey(Boolean isPrimaryKey) {
-    this.isPrimaryKey = isPrimaryKey;
-    return this;
-  }
-
-   /**
-   * Get isPrimaryKey
-   * @return isPrimaryKey
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isIsPrimaryKey() {
-    return isPrimaryKey;
-  }
-
-  public void setIsPrimaryKey(Boolean isPrimaryKey) {
-    this.isPrimaryKey = isPrimaryKey;
-  }
-
-  public ColumnDto columnType(ColumnTypeEnum columnType) {
-    this.columnType = columnType;
-    return this;
-  }
-
-   /**
-   * Get columnType
-   * @return columnType
-  **/
-  @Schema(example = "string", required = true, description = "")
-  public ColumnTypeEnum getColumnType() {
-    return columnType;
-  }
-
-  public void setColumnType(ColumnTypeEnum columnType) {
-    this.columnType = columnType;
-  }
-
-  public ColumnDto isNullAllowed(Boolean isNullAllowed) {
-    this.isNullAllowed = isNullAllowed;
-    return this;
-  }
-
-   /**
-   * Get isNullAllowed
-   * @return isNullAllowed
-  **/
-  @Schema(example = "false", required = true, description = "")
-  public Boolean isIsNullAllowed() {
-    return isNullAllowed;
-  }
-
-  public void setIsNullAllowed(Boolean isNullAllowed) {
-    this.isNullAllowed = isNullAllowed;
-  }
-
-  public ColumnDto checkExpression(String checkExpression) {
-    this.checkExpression = checkExpression;
-    return this;
-  }
-
-   /**
-   * Get checkExpression
-   * @return checkExpression
-  **/
-  @Schema(description = "")
-  public String getCheckExpression() {
-    return checkExpression;
-  }
-
-  public void setCheckExpression(String checkExpression) {
-    this.checkExpression = checkExpression;
-  }
-
-  public ColumnDto foreignKey(String foreignKey) {
-    this.foreignKey = foreignKey;
-    return this;
-  }
-
-   /**
-   * Get foreignKey
-   * @return foreignKey
-  **/
-  @Schema(description = "")
-  public String getForeignKey() {
-    return foreignKey;
-  }
-
-  public void setForeignKey(String foreignKey) {
-    this.foreignKey = foreignKey;
-  }
-
-  public ColumnDto enumValues(List<String> enumValues) {
-    this.enumValues = enumValues;
-    return this;
-  }
-
-  public ColumnDto addEnumValuesItem(String enumValuesItem) {
-    if (this.enumValues == null) {
-      this.enumValues = new ArrayList<String>();
-    }
-    this.enumValues.add(enumValuesItem);
-    return this;
-  }
-
-   /**
-   * Get enumValues
-   * @return enumValues
-  **/
-  @Schema(description = "")
-  public List<String> getEnumValues() {
-    return enumValues;
-  }
-
-  public void setEnumValues(List<String> enumValues) {
-    this.enumValues = enumValues;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ColumnDto columnDto = (ColumnDto) o;
-    return Objects.equals(this.id, columnDto.id) &&
-        Objects.equals(this.name, columnDto.name) &&
-        Objects.equals(this.concept, columnDto.concept) &&
-        Objects.equals(this.unit, columnDto.unit) &&
-        Objects.equals(this.unique, columnDto.unique) &&
-        Objects.equals(this.references, columnDto.references) &&
-        Objects.equals(this.internalName, columnDto.internalName) &&
-        Objects.equals(this.dateFormat, columnDto.dateFormat) &&
-        Objects.equals(this.autoGenerated, columnDto.autoGenerated) &&
-        Objects.equals(this.isPrimaryKey, columnDto.isPrimaryKey) &&
-        Objects.equals(this.columnType, columnDto.columnType) &&
-        Objects.equals(this.isNullAllowed, columnDto.isNullAllowed) &&
-        Objects.equals(this.checkExpression, columnDto.checkExpression) &&
-        Objects.equals(this.foreignKey, columnDto.foreignKey) &&
-        Objects.equals(this.enumValues, columnDto.enumValues);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, name, concept, unit, unique, references, internalName, dateFormat, autoGenerated, isPrimaryKey, columnType, isNullAllowed, checkExpression, foreignKey, enumValues);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ColumnDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    concept: ").append(toIndentedString(concept)).append("\n");
-    sb.append("    unit: ").append(toIndentedString(unit)).append("\n");
-    sb.append("    unique: ").append(toIndentedString(unique)).append("\n");
-    sb.append("    references: ").append(toIndentedString(references)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    dateFormat: ").append(toIndentedString(dateFormat)).append("\n");
-    sb.append("    autoGenerated: ").append(toIndentedString(autoGenerated)).append("\n");
-    sb.append("    isPrimaryKey: ").append(toIndentedString(isPrimaryKey)).append("\n");
-    sb.append("    columnType: ").append(toIndentedString(columnType)).append("\n");
-    sb.append("    isNullAllowed: ").append(toIndentedString(isNullAllowed)).append("\n");
-    sb.append("    checkExpression: ").append(toIndentedString(checkExpression)).append("\n");
-    sb.append("    foreignKey: ").append(toIndentedString(foreignKey)).append("\n");
-    sb.append("    enumValues: ").append(toIndentedString(enumValues)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ColumnSemanticsUpdateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ColumnSemanticsUpdateDto.java
deleted file mode 100644
index 715a2b98ef5f3ea68d4fb56a8ea8fa4159fdf0fc..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ColumnSemanticsUpdateDto.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ColumnSemanticsUpdateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class ColumnSemanticsUpdateDto {
-  @SerializedName("concept_uri")
-  private String conceptUri = null;
-
-  @SerializedName("unit_uri")
-  private String unitUri = null;
-
-  public ColumnSemanticsUpdateDto conceptUri(String conceptUri) {
-    this.conceptUri = conceptUri;
-    return this;
-  }
-
-   /**
-   * Get conceptUri
-   * @return conceptUri
-  **/
-  @Schema(description = "")
-  public String getConceptUri() {
-    return conceptUri;
-  }
-
-  public void setConceptUri(String conceptUri) {
-    this.conceptUri = conceptUri;
-  }
-
-  public ColumnSemanticsUpdateDto unitUri(String unitUri) {
-    this.unitUri = unitUri;
-    return this;
-  }
-
-   /**
-   * Get unitUri
-   * @return unitUri
-  **/
-  @Schema(description = "")
-  public String getUnitUri() {
-    return unitUri;
-  }
-
-  public void setUnitUri(String unitUri) {
-    this.unitUri = unitUri;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ColumnSemanticsUpdateDto columnSemanticsUpdateDto = (ColumnSemanticsUpdateDto) o;
-    return Objects.equals(this.conceptUri, columnSemanticsUpdateDto.conceptUri) &&
-        Objects.equals(this.unitUri, columnSemanticsUpdateDto.unitUri);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(conceptUri, unitUri);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ColumnSemanticsUpdateDto {\n");
-    
-    sb.append("    conceptUri: ").append(toIndentedString(conceptUri)).append("\n");
-    sb.append("    unitUri: ").append(toIndentedString(unitUri)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ConceptDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ConceptDto.java
deleted file mode 100644
index d678ca104b262fc51fdf26e776c1d7f9b35ab706..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ConceptDto.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ConceptDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class ConceptDto {
-  @SerializedName("uri")
-  private String uri = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  public ConceptDto uri(String uri) {
-    this.uri = uri;
-    return this;
-  }
-
-   /**
-   * Get uri
-   * @return uri
-  **/
-  @Schema(required = true, description = "")
-  public String getUri() {
-    return uri;
-  }
-
-  public void setUri(String uri) {
-    this.uri = uri;
-  }
-
-  public ConceptDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ConceptDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ConceptDto conceptDto = (ConceptDto) o;
-    return Objects.equals(this.uri, conceptDto.uri) &&
-        Objects.equals(this.name, conceptDto.name) &&
-        Objects.equals(this.created, conceptDto.created);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(uri, name, created);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ConceptDto {\n");
-    
-    sb.append("    uri: ").append(toIndentedString(uri)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ContainerBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ContainerBriefDto.java
deleted file mode 100644
index 565aac85e7351242c5dfb8e5695fd7d3fb68d240..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ContainerBriefDto.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.UserBriefDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ContainerBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ContainerBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("hash")
-  private String hash = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("creator")
-  private UserBriefDto creator = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  public ContainerBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ContainerBriefDto hash(String hash) {
-    this.hash = hash;
-    return this;
-  }
-
-   /**
-   * Get hash
-   * @return hash
-  **/
-  @Schema(example = "f829dd8a884182d0da846f365dee1221fd16610a14c81b8f9f295ff162749e50", required = true, description = "")
-  public String getHash() {
-    return hash;
-  }
-
-  public void setHash(String hash) {
-    this.hash = hash;
-  }
-
-  public ContainerBriefDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ContainerBriefDto creator(UserBriefDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(description = "")
-  public UserBriefDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserBriefDto creator) {
-    this.creator = creator;
-  }
-
-  public ContainerBriefDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public ContainerBriefDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air-quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ContainerBriefDto containerBriefDto = (ContainerBriefDto) o;
-    return Objects.equals(this.id, containerBriefDto.id) &&
-        Objects.equals(this.hash, containerBriefDto.hash) &&
-        Objects.equals(this.name, containerBriefDto.name) &&
-        Objects.equals(this.creator, containerBriefDto.creator) &&
-        Objects.equals(this.created, containerBriefDto.created) &&
-        Objects.equals(this.internalName, containerBriefDto.internalName);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, hash, name, creator, created, internalName);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ContainerBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    hash: ").append(toIndentedString(hash)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ContainerChangeDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ContainerChangeDto.java
deleted file mode 100644
index f90bf25edc210c9b06595b88e6466dd297218016..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ContainerChangeDto.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ContainerChangeDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ContainerChangeDto {
-  /**
-   * Gets or Sets action
-   */
-  @JsonAdapter(ActionEnum.Adapter.class)
-  public enum ActionEnum {
-    START("start"),
-    STOP("stop");
-
-    private String value;
-
-    ActionEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static ActionEnum fromValue(String input) {
-      for (ActionEnum b : ActionEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<ActionEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final ActionEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public ActionEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return ActionEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("action")
-  private ActionEnum action = null;
-
-  public ContainerChangeDto action(ActionEnum action) {
-    this.action = action;
-    return this;
-  }
-
-   /**
-   * Get action
-   * @return action
-  **/
-  @Schema(required = true, description = "")
-  public ActionEnum getAction() {
-    return action;
-  }
-
-  public void setAction(ActionEnum action) {
-    this.action = action;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ContainerChangeDto containerChangeDto = (ContainerChangeDto) o;
-    return Objects.equals(this.action, containerChangeDto.action);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(action);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ContainerChangeDto {\n");
-    
-    sb.append("    action: ").append(toIndentedString(action)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ContainerCreateRequestDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ContainerCreateRequestDto.java
deleted file mode 100644
index 4291a9137e65c0f3172ca357a66160062fe8b53a..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ContainerCreateRequestDto.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ContainerCreateRequestDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ContainerCreateRequestDto {
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("repository")
-  private String repository = null;
-
-  @SerializedName("tag")
-  private String tag = null;
-
-  public ContainerCreateRequestDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ContainerCreateRequestDto repository(String repository) {
-    this.repository = repository;
-    return this;
-  }
-
-   /**
-   * Get repository
-   * @return repository
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getRepository() {
-    return repository;
-  }
-
-  public void setRepository(String repository) {
-    this.repository = repository;
-  }
-
-  public ContainerCreateRequestDto tag(String tag) {
-    this.tag = tag;
-    return this;
-  }
-
-   /**
-   * Get tag
-   * @return tag
-  **/
-  @Schema(example = "10.5", required = true, description = "")
-  public String getTag() {
-    return tag;
-  }
-
-  public void setTag(String tag) {
-    this.tag = tag;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ContainerCreateRequestDto containerCreateRequestDto = (ContainerCreateRequestDto) o;
-    return Objects.equals(this.name, containerCreateRequestDto.name) &&
-        Objects.equals(this.repository, containerCreateRequestDto.repository) &&
-        Objects.equals(this.tag, containerCreateRequestDto.tag);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(name, repository, tag);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ContainerCreateRequestDto {\n");
-    
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    repository: ").append(toIndentedString(repository)).append("\n");
-    sb.append("    tag: ").append(toIndentedString(tag)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ContainerDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ContainerDto.java
deleted file mode 100644
index 4a27ce3b32701d10833a9326c341651d5b0cf216..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ContainerDto.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.DatabaseDto;
-import io.swagger.client.model.ImageBriefDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ContainerDto
- */
-
-public class ContainerDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("hash")
-  private String hash = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  /**
-   * Gets or Sets state
-   */
-  @JsonAdapter(StateEnum.Adapter.class)
-  public enum StateEnum {
-    CREATED("created"),
-    RESTARTING("restarting"),
-    RUNNING("running"),
-    PAUSED("paused"),
-    EXITED("exited"),
-    DEAD("dead");
-
-    private String value;
-
-    StateEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static StateEnum fromValue(String input) {
-      for (StateEnum b : StateEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<StateEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final StateEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public StateEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return StateEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("state")
-  private StateEnum state = null;
-
-  @SerializedName("database")
-  private DatabaseDto database = null;
-
-  @SerializedName("image")
-  private ImageBriefDto image = null;
-
-  @SerializedName("port")
-  private Integer port = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  @SerializedName("ip_address")
-  private String ipAddress = null;
-
-  public ContainerDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ContainerDto hash(String hash) {
-    this.hash = hash;
-    return this;
-  }
-
-   /**
-   * Get hash
-   * @return hash
-  **/
-  @Schema(example = "f829dd8a884182d0da846f365dee1221fd16610a14c81b8f9f295ff162749e50", required = true, description = "")
-  public String getHash() {
-    return hash;
-  }
-
-  public void setHash(String hash) {
-    this.hash = hash;
-  }
-
-  public ContainerDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ContainerDto state(StateEnum state) {
-    this.state = state;
-    return this;
-  }
-
-   /**
-   * Get state
-   * @return state
-  **/
-  @Schema(example = "running", description = "")
-  public StateEnum getState() {
-    return state;
-  }
-
-  public void setState(StateEnum state) {
-    this.state = state;
-  }
-
-  public ContainerDto database(DatabaseDto database) {
-    this.database = database;
-    return this;
-  }
-
-   /**
-   * Get database
-   * @return database
-  **/
-  @Schema(description = "")
-  public DatabaseDto getDatabase() {
-    return database;
-  }
-
-  public void setDatabase(DatabaseDto database) {
-    this.database = database;
-  }
-
-  public ContainerDto image(ImageBriefDto image) {
-    this.image = image;
-    return this;
-  }
-
-   /**
-   * Get image
-   * @return image
-  **/
-  @Schema(description = "")
-  public ImageBriefDto getImage() {
-    return image;
-  }
-
-  public void setImage(ImageBriefDto image) {
-    this.image = image;
-  }
-
-  public ContainerDto port(Integer port) {
-    this.port = port;
-    return this;
-  }
-
-   /**
-   * Get port
-   * @return port
-  **/
-  @Schema(description = "")
-  public Integer getPort() {
-    return port;
-  }
-
-  public void setPort(Integer port) {
-    this.port = port;
-  }
-
-  public ContainerDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(example = "2021-03-12T15:26:21.678396092Z", required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public ContainerDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air-quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public ContainerDto ipAddress(String ipAddress) {
-    this.ipAddress = ipAddress;
-    return this;
-  }
-
-   /**
-   * Get ipAddress
-   * @return ipAddress
-  **/
-  @Schema(description = "")
-  public String getIpAddress() {
-    return ipAddress;
-  }
-
-  public void setIpAddress(String ipAddress) {
-    this.ipAddress = ipAddress;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ContainerDto containerDto = (ContainerDto) o;
-    return Objects.equals(this.id, containerDto.id) &&
-        Objects.equals(this.hash, containerDto.hash) &&
-        Objects.equals(this.name, containerDto.name) &&
-        Objects.equals(this.state, containerDto.state) &&
-        Objects.equals(this.database, containerDto.database) &&
-        Objects.equals(this.image, containerDto.image) &&
-        Objects.equals(this.port, containerDto.port) &&
-        Objects.equals(this.created, containerDto.created) &&
-        Objects.equals(this.internalName, containerDto.internalName) &&
-        Objects.equals(this.ipAddress, containerDto.ipAddress);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, hash, name, state, database, image, port, created, internalName, ipAddress);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ContainerDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    hash: ").append(toIndentedString(hash)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    state: ").append(toIndentedString(state)).append("\n");
-    sb.append("    database: ").append(toIndentedString(database)).append("\n");
-    sb.append("    image: ").append(toIndentedString(image)).append("\n");
-    sb.append("    port: ").append(toIndentedString(port)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    ipAddress: ").append(toIndentedString(ipAddress)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/CreatorDto.java b/.java-stubs/src/main/java/io/swagger/client/model/CreatorDto.java
deleted file mode 100644
index b19e0b1905883253967c526991b2a5a392f7ca38..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/CreatorDto.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * CreatorDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class CreatorDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("firstname")
-  private String firstname = null;
-
-  @SerializedName("lastname")
-  private String lastname = null;
-
-  @SerializedName("affiliation")
-  private String affiliation = null;
-
-  @SerializedName("orcid")
-  private String orcid = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("lastModified")
-  private OffsetDateTime lastModified = null;
-
-  public CreatorDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public CreatorDto firstname(String firstname) {
-    this.firstname = firstname;
-    return this;
-  }
-
-   /**
-   * Get firstname
-   * @return firstname
-  **/
-  @Schema(example = "Josiah", required = true, description = "")
-  public String getFirstname() {
-    return firstname;
-  }
-
-  public void setFirstname(String firstname) {
-    this.firstname = firstname;
-  }
-
-  public CreatorDto lastname(String lastname) {
-    this.lastname = lastname;
-    return this;
-  }
-
-   /**
-   * Get lastname
-   * @return lastname
-  **/
-  @Schema(example = "Carberry", required = true, description = "")
-  public String getLastname() {
-    return lastname;
-  }
-
-  public void setLastname(String lastname) {
-    this.lastname = lastname;
-  }
-
-  public CreatorDto affiliation(String affiliation) {
-    this.affiliation = affiliation;
-    return this;
-  }
-
-   /**
-   * Get affiliation
-   * @return affiliation
-  **/
-  @Schema(example = "Wesleyan University", description = "")
-  public String getAffiliation() {
-    return affiliation;
-  }
-
-  public void setAffiliation(String affiliation) {
-    this.affiliation = affiliation;
-  }
-
-  public CreatorDto orcid(String orcid) {
-    this.orcid = orcid;
-    return this;
-  }
-
-   /**
-   * Get orcid
-   * @return orcid
-  **/
-  @Schema(example = "0000-0002-1825-0097", description = "")
-  public String getOrcid() {
-    return orcid;
-  }
-
-  public void setOrcid(String orcid) {
-    this.orcid = orcid;
-  }
-
-  public CreatorDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public CreatorDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    CreatorDto creatorDto = (CreatorDto) o;
-    return Objects.equals(this.id, creatorDto.id) &&
-        Objects.equals(this.firstname, creatorDto.firstname) &&
-        Objects.equals(this.lastname, creatorDto.lastname) &&
-        Objects.equals(this.affiliation, creatorDto.affiliation) &&
-        Objects.equals(this.orcid, creatorDto.orcid) &&
-        Objects.equals(this.created, creatorDto.created) &&
-        Objects.equals(this.lastModified, creatorDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, firstname, lastname, affiliation, orcid, created, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class CreatorDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    firstname: ").append(toIndentedString(firstname)).append("\n");
-    sb.append("    lastname: ").append(toIndentedString(lastname)).append("\n");
-    sb.append("    affiliation: ").append(toIndentedString(affiliation)).append("\n");
-    sb.append("    orcid: ").append(toIndentedString(orcid)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseAccessDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseAccessDto.java
deleted file mode 100644
index e60f354fcf92285284a5857868a3e980cb7f7ac8..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseAccessDto.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.UserDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * DatabaseAccessDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class DatabaseAccessDto {
-  @SerializedName("user")
-  private UserDto user = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    READ("read"),
-    WRITE_OWN("write_own"),
-    WRITE_ALL("write_all");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  public DatabaseAccessDto user(UserDto user) {
-    this.user = user;
-    return this;
-  }
-
-   /**
-   * Get user
-   * @return user
-  **/
-  @Schema(required = true, description = "")
-  public UserDto getUser() {
-    return user;
-  }
-
-  public void setUser(UserDto user) {
-    this.user = user;
-  }
-
-  public DatabaseAccessDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public DatabaseAccessDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseAccessDto databaseAccessDto = (DatabaseAccessDto) o;
-    return Objects.equals(this.user, databaseAccessDto.user) &&
-        Objects.equals(this.type, databaseAccessDto.type) &&
-        Objects.equals(this.created, databaseAccessDto.created);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(user, type, created);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseAccessDto {\n");
-    
-    sb.append("    user: ").append(toIndentedString(user)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseBriefDto.java
deleted file mode 100644
index e30e89a66dc918c2736884db7c09fb6e0b584816..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseBriefDto.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import com.google.gson.annotations.SerializedName;
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.threeten.bp.OffsetDateTime;
-
-import java.util.Objects;
-/**
- * DatabaseBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:04:35.418127+01:00[Europe/Vienna]")
-public class DatabaseBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("identifier")
-  private IdentifierDto identifier = null;
-
-  @SerializedName("engine")
-  private String engine = null;
-
-  @SerializedName("container")
-  private ContainerBriefDto container = null;
-
-  @SerializedName("creator")
-  private UserBriefDto creator = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  public DatabaseBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public DatabaseBriefDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public DatabaseBriefDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Air Quality in Austria", description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public DatabaseBriefDto identifier(IdentifierDto identifier) {
-    this.identifier = identifier;
-    return this;
-  }
-
-   /**
-   * Get identifier
-   * @return identifier
-  **/
-  @Schema(description = "")
-  public IdentifierDto getIdentifier() {
-    return identifier;
-  }
-
-  public void setIdentifier(IdentifierDto identifier) {
-    this.identifier = identifier;
-  }
-
-  public DatabaseBriefDto engine(String engine) {
-    this.engine = engine;
-    return this;
-  }
-
-   /**
-   * Get engine
-   * @return engine
-  **/
-  @Schema(example = "mariadb:10.5", description = "")
-  public String getEngine() {
-    return engine;
-  }
-
-  public void setEngine(String engine) {
-    this.engine = engine;
-  }
-
-  public DatabaseBriefDto container(ContainerBriefDto container) {
-    this.container = container;
-    return this;
-  }
-
-   /**
-   * Get container
-   * @return container
-  **/
-  @Schema(description = "")
-  public ContainerBriefDto getContainer() {
-    return container;
-  }
-
-  public void setContainer(ContainerBriefDto container) {
-    this.container = container;
-  }
-
-  public DatabaseBriefDto creator(UserBriefDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(description = "")
-  public UserBriefDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserBriefDto creator) {
-    this.creator = creator;
-  }
-
-  public DatabaseBriefDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public DatabaseBriefDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseBriefDto databaseBriefDto = (DatabaseBriefDto) o;
-    return Objects.equals(this.id, databaseBriefDto.id) &&
-        Objects.equals(this.name, databaseBriefDto.name) &&
-        Objects.equals(this.description, databaseBriefDto.description) &&
-        Objects.equals(this.identifier, databaseBriefDto.identifier) &&
-        Objects.equals(this.engine, databaseBriefDto.engine) &&
-        Objects.equals(this.container, databaseBriefDto.container) &&
-        Objects.equals(this.creator, databaseBriefDto.creator) &&
-        Objects.equals(this.created, databaseBriefDto.created) &&
-        Objects.equals(this.isPublic, databaseBriefDto.isPublic);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, name, description, identifier, engine, container, creator, created, isPublic);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    identifier: ").append(toIndentedString(identifier)).append("\n");
-    sb.append("    engine: ").append(toIndentedString(engine)).append("\n");
-    sb.append("    container: ").append(toIndentedString(container)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseCreateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseCreateDto.java
deleted file mode 100644
index 829517bd30d812ed46471b212612aeb8612ee5b1..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseCreateDto.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import com.google.gson.annotations.SerializedName;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.util.Objects;
-
-/**
- * DatabaseCreateDto
- */
-
-public class DatabaseCreateDto {
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  public DatabaseCreateDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public DatabaseCreateDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseCreateDto databaseCreateDto = (DatabaseCreateDto) o;
-    return Objects.equals(this.name, databaseCreateDto.name) &&
-        Objects.equals(this.isPublic, databaseCreateDto.isPublic);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(name, isPublic);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseCreateDto {\n");
-    
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseDto.java
deleted file mode 100644
index 9c3d6eda0b184bf6ec4315a08d3fbf0b3fcd50be..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseDto.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ContainerDto;
-import io.swagger.client.model.DatabaseAccessDto;
-import io.swagger.client.model.IdentifierDto;
-import io.swagger.client.model.ImageDto;
-import io.swagger.client.model.TableBriefDto;
-import io.swagger.client.model.UserBriefDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.threeten.bp.OffsetDateTime;
-/**
- * DatabaseDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class DatabaseDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("creator")
-  private UserBriefDto creator = null;
-
-  @SerializedName("identifier")
-  private IdentifierDto identifier = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("tables")
-  private List<TableBriefDto> tables = null;
-
-  @SerializedName("image")
-  private ImageDto image = null;
-
-  @SerializedName("container")
-  private ContainerDto container = null;
-
-  @SerializedName("accesses")
-  private List<DatabaseAccessDto> accesses = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("exchange_name")
-  private String exchangeName = null;
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  public DatabaseDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public DatabaseDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public DatabaseDto creator(UserBriefDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserBriefDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserBriefDto creator) {
-    this.creator = creator;
-  }
-
-  public DatabaseDto identifier(IdentifierDto identifier) {
-    this.identifier = identifier;
-    return this;
-  }
-
-   /**
-   * Get identifier
-   * @return identifier
-  **/
-  @Schema(description = "")
-  public IdentifierDto getIdentifier() {
-    return identifier;
-  }
-
-  public void setIdentifier(IdentifierDto identifier) {
-    this.identifier = identifier;
-  }
-
-  public DatabaseDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Weather Australia 2009-2021", description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public DatabaseDto tables(List<TableBriefDto> tables) {
-    this.tables = tables;
-    return this;
-  }
-
-  public DatabaseDto addTablesItem(TableBriefDto tablesItem) {
-    if (this.tables == null) {
-      this.tables = new ArrayList<TableBriefDto>();
-    }
-    this.tables.add(tablesItem);
-    return this;
-  }
-
-   /**
-   * Get tables
-   * @return tables
-  **/
-  @Schema(description = "")
-  public List<TableBriefDto> getTables() {
-    return tables;
-  }
-
-  public void setTables(List<TableBriefDto> tables) {
-    this.tables = tables;
-  }
-
-  public DatabaseDto image(ImageDto image) {
-    this.image = image;
-    return this;
-  }
-
-   /**
-   * Get image
-   * @return image
-  **/
-  @Schema(description = "")
-  public ImageDto getImage() {
-    return image;
-  }
-
-  public void setImage(ImageDto image) {
-    this.image = image;
-  }
-
-  public DatabaseDto container(ContainerDto container) {
-    this.container = container;
-    return this;
-  }
-
-   /**
-   * Get container
-   * @return container
-  **/
-  @Schema(description = "")
-  public ContainerDto getContainer() {
-    return container;
-  }
-
-  public void setContainer(ContainerDto container) {
-    this.container = container;
-  }
-
-  public DatabaseDto accesses(List<DatabaseAccessDto> accesses) {
-    this.accesses = accesses;
-    return this;
-  }
-
-  public DatabaseDto addAccessesItem(DatabaseAccessDto accessesItem) {
-    if (this.accesses == null) {
-      this.accesses = new ArrayList<DatabaseAccessDto>();
-    }
-    this.accesses.add(accessesItem);
-    return this;
-  }
-
-   /**
-   * Get accesses
-   * @return accesses
-  **/
-  @Schema(description = "")
-  public List<DatabaseAccessDto> getAccesses() {
-    return accesses;
-  }
-
-  public void setAccesses(List<DatabaseAccessDto> accesses) {
-    this.accesses = accesses;
-  }
-
-  public DatabaseDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public DatabaseDto exchangeName(String exchangeName) {
-    this.exchangeName = exchangeName;
-    return this;
-  }
-
-   /**
-   * Get exchangeName
-   * @return exchangeName
-  **/
-  @Schema(example = "dbrepo/4/4", required = true, description = "")
-  public String getExchangeName() {
-    return exchangeName;
-  }
-
-  public void setExchangeName(String exchangeName) {
-    this.exchangeName = exchangeName;
-  }
-
-  public DatabaseDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "weather_australia", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public DatabaseDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseDto databaseDto = (DatabaseDto) o;
-    return Objects.equals(this.id, databaseDto.id) &&
-        Objects.equals(this.name, databaseDto.name) &&
-        Objects.equals(this.creator, databaseDto.creator) &&
-        Objects.equals(this.identifier, databaseDto.identifier) &&
-        Objects.equals(this.description, databaseDto.description) &&
-        Objects.equals(this.tables, databaseDto.tables) &&
-        Objects.equals(this.image, databaseDto.image) &&
-        Objects.equals(this.container, databaseDto.container) &&
-        Objects.equals(this.accesses, databaseDto.accesses) &&
-        Objects.equals(this.created, databaseDto.created) &&
-        Objects.equals(this.exchangeName, databaseDto.exchangeName) &&
-        Objects.equals(this.internalName, databaseDto.internalName) &&
-        Objects.equals(this.isPublic, databaseDto.isPublic);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, name, creator, identifier, description, tables, image, container, accesses, created, exchangeName, internalName, isPublic);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    identifier: ").append(toIndentedString(identifier)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    tables: ").append(toIndentedString(tables)).append("\n");
-    sb.append("    image: ").append(toIndentedString(image)).append("\n");
-    sb.append("    container: ").append(toIndentedString(container)).append("\n");
-    sb.append("    accesses: ").append(toIndentedString(accesses)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    exchangeName: ").append(toIndentedString(exchangeName)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseGiveAccessDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseGiveAccessDto.java
deleted file mode 100644
index 07f05530346ac309eac6403ffce10d32cfa327c2..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseGiveAccessDto.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.io.IOException;
-import java.util.Objects;
-/**
- * DatabaseGiveAccessDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:04:35.418127+01:00[Europe/Vienna]")
-public class DatabaseGiveAccessDto {
-  @SerializedName("username")
-  private String username = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    READ("read"),
-    WRITE_OWN("write_own"),
-    WRITE_ALL("write_all");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  public DatabaseGiveAccessDto username(String username) {
-    this.username = username;
-    return this;
-  }
-
-   /**
-   * Get username
-   * @return username
-  **/
-  @Schema(required = true, description = "")
-  public String getUsername() {
-    return username;
-  }
-
-  public void setUsername(String username) {
-    this.username = username;
-  }
-
-  public DatabaseGiveAccessDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseGiveAccessDto databaseGiveAccessDto = (DatabaseGiveAccessDto) o;
-    return Objects.equals(this.username, databaseGiveAccessDto.username) &&
-        Objects.equals(this.type, databaseGiveAccessDto.type);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(username, type);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseGiveAccessDto {\n");
-    
-    sb.append("    username: ").append(toIndentedString(username)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseModifyAccessDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseModifyAccessDto.java
deleted file mode 100644
index 251e292bf30690b004b434eeebe9003954777814..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseModifyAccessDto.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.io.IOException;
-import java.util.Objects;
-/**
- * DatabaseModifyAccessDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:04:35.418127+01:00[Europe/Vienna]")
-public class DatabaseModifyAccessDto {
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    READ("read"),
-    WRITE_OWN("write_own"),
-    WRITE_ALL("write_all");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  public DatabaseModifyAccessDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseModifyAccessDto databaseModifyAccessDto = (DatabaseModifyAccessDto) o;
-    return Objects.equals(this.type, databaseModifyAccessDto.type);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(type);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseModifyAccessDto {\n");
-    
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseTransferDto.java b/.java-stubs/src/main/java/io/swagger/client/model/DatabaseTransferDto.java
deleted file mode 100644
index e6aeb29755ef422df8b292fffc14eb566e0031e9..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/DatabaseTransferDto.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Database Repository Database Service API
- * Service that manages the databases
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import com.google.gson.annotations.SerializedName;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.util.Objects;
-
-/**
- * DatabaseTransferDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:04:35.418127+01:00[Europe/Vienna]")
-public class DatabaseTransferDto {
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  public DatabaseTransferDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    DatabaseTransferDto databaseTransferDto = (DatabaseTransferDto) o;
-    return Objects.equals(this.isPublic, databaseTransferDto.isPublic);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(isPublic);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class DatabaseTransferDto {\n");
-    
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ExecuteStatementDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ExecuteStatementDto.java
deleted file mode 100644
index d834275b9c6859beb2f33fe9b6b9a88dd462d0c2..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ExecuteStatementDto.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ExecuteStatementDto
- */
-
-public class ExecuteStatementDto {
-  @SerializedName("statement")
-  private String statement = null;
-
-  public ExecuteStatementDto statement(String statement) {
-    this.statement = statement;
-    return this;
-  }
-
-   /**
-   * Get statement
-   * @return statement
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", required = true, description = "")
-  public String getStatement() {
-    return statement;
-  }
-
-  public void setStatement(String statement) {
-    this.statement = statement;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ExecuteStatementDto executeStatementDto = (ExecuteStatementDto) o;
-    return Objects.equals(this.statement, executeStatementDto.statement);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(statement);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ExecuteStatementDto {\n");
-    
-    sb.append("    statement: ").append(toIndentedString(statement)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/GrantedAuthorityDto.java b/.java-stubs/src/main/java/io/swagger/client/model/GrantedAuthorityDto.java
deleted file mode 100644
index 6ae594c5b6611ad0c83249a091d352e3cfe85b85..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/GrantedAuthorityDto.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * GrantedAuthorityDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class GrantedAuthorityDto {
-  @SerializedName("authority")
-  private String authority = null;
-
-  public GrantedAuthorityDto authority(String authority) {
-    this.authority = authority;
-    return this;
-  }
-
-   /**
-   * Get authority
-   * @return authority
-  **/
-  @Schema(example = "ROLE_RESEARCHER", description = "")
-  public String getAuthority() {
-    return authority;
-  }
-
-  public void setAuthority(String authority) {
-    this.authority = authority;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    GrantedAuthorityDto grantedAuthorityDto = (GrantedAuthorityDto) o;
-    return Objects.equals(this.authority, grantedAuthorityDto.authority);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(authority);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class GrantedAuthorityDto {\n");
-    
-    sb.append("    authority: ").append(toIndentedString(authority)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/IdentifierDto.java b/.java-stubs/src/main/java/io/swagger/client/model/IdentifierDto.java
deleted file mode 100644
index 3644adf2e1f7ddca14e2fe3bf68423c7f5ab4aff..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/IdentifierDto.java
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.CreatorDto;
-import io.swagger.client.model.LicenseDto;
-import io.swagger.client.model.RelatedIdentifierDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.threeten.bp.OffsetDateTime;
-/**
- * IdentifierDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class IdentifierDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    DATABASE("database"),
-    SUBSET("subset");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  @SerializedName("title")
-  private String title = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  @SerializedName("execution")
-  private OffsetDateTime execution = null;
-
-  /**
-   * Gets or Sets visibility
-   */
-  @JsonAdapter(VisibilityEnum.Adapter.class)
-  public enum VisibilityEnum {
-    EVERYONE("everyone"),
-    TRUSTED("trusted"),
-    SELF("self");
-
-    private String value;
-
-    VisibilityEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static VisibilityEnum fromValue(String input) {
-      for (VisibilityEnum b : VisibilityEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<VisibilityEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final VisibilityEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public VisibilityEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return VisibilityEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("visibility")
-  private VisibilityEnum visibility = null;
-
-  @SerializedName("doi")
-  private String doi = null;
-
-  @SerializedName("publisher")
-  private String publisher = null;
-
-  /**
-   * Gets or Sets language
-   */
-  @JsonAdapter(LanguageEnum.Adapter.class)
-  public enum LanguageEnum {
-    AB("ab"),
-    AA("aa"),
-    AF("af"),
-    AK("ak"),
-    SQ("sq"),
-    AM("am"),
-    AR("ar"),
-    AN("an"),
-    HY("hy"),
-    AS("as"),
-    AV("av"),
-    AE("ae"),
-    AY("ay"),
-    AZ("az"),
-    BM("bm"),
-    BA("ba"),
-    EU("eu"),
-    BE("be"),
-    BN("bn"),
-    BH("bh"),
-    BI("bi"),
-    BS("bs"),
-    BR("br"),
-    BG("bg"),
-    MY("my"),
-    CA("ca"),
-    KM("km"),
-    CH("ch"),
-    CE("ce"),
-    NY("ny"),
-    ZH("zh"),
-    CU("cu"),
-    CV("cv"),
-    KW("kw"),
-    CO("co"),
-    CR("cr"),
-    HR("hr"),
-    CS("cs"),
-    DA("da"),
-    DV("dv"),
-    NL("nl"),
-    DZ("dz"),
-    EN("en"),
-    EO("eo"),
-    ET("et"),
-    EE("ee"),
-    FO("fo"),
-    FJ("fj"),
-    FI("fi"),
-    FR("fr"),
-    FF("ff"),
-    GD("gd"),
-    GL("gl"),
-    LG("lg"),
-    KA("ka"),
-    DE("de"),
-    KI("ki"),
-    EL("el"),
-    KL("kl"),
-    GN("gn"),
-    GU("gu"),
-    HT("ht"),
-    HA("ha"),
-    HE("he"),
-    HZ("hz"),
-    HI("hi"),
-    HO("ho"),
-    HU("hu"),
-    IS("is"),
-    IO("io"),
-    IG("ig"),
-    ID("id"),
-    IA("ia"),
-    IE("ie"),
-    IU("iu"),
-    IK("ik"),
-    GA("ga"),
-    IT("it"),
-    JA("ja"),
-    JV("jv"),
-    KN("kn"),
-    KR("kr"),
-    KS("ks"),
-    KK("kk"),
-    RW("rw"),
-    KV("kv"),
-    KG("kg"),
-    KO("ko"),
-    KJ("kj"),
-    KU("ku"),
-    KY("ky"),
-    LO("lo"),
-    LA("la"),
-    LV("lv"),
-    LB("lb"),
-    LI("li"),
-    LN("ln"),
-    LT("lt"),
-    LU("lu"),
-    MK("mk"),
-    MG("mg"),
-    MS("ms"),
-    ML("ml"),
-    MT("mt"),
-    GV("gv"),
-    MI("mi"),
-    MR("mr"),
-    MH("mh"),
-    RO("ro"),
-    MN("mn"),
-    NA("na"),
-    NV("nv"),
-    ND("nd"),
-    NG("ng"),
-    NE("ne"),
-    SE("se"),
-    NO("no"),
-    NB("nb"),
-    NN("nn"),
-    II("ii"),
-    OC("oc"),
-    OJ("oj"),
-    OR("or"),
-    OM("om"),
-    OS("os"),
-    PI("pi"),
-    PA("pa"),
-    PS("ps"),
-    FA("fa"),
-    PL("pl"),
-    PT("pt"),
-    QU("qu"),
-    RM("rm"),
-    RN("rn"),
-    RU("ru"),
-    SM("sm"),
-    SG("sg"),
-    SA("sa"),
-    SC("sc"),
-    SR("sr"),
-    SN("sn"),
-    SD("sd"),
-    SI("si"),
-    SK("sk"),
-    SL("sl"),
-    SO("so"),
-    ST("st"),
-    NR("nr"),
-    ES("es"),
-    SU("su"),
-    SW("sw"),
-    SS("ss"),
-    SV("sv"),
-    TL("tl"),
-    TY("ty"),
-    TG("tg"),
-    TA("ta"),
-    TT("tt"),
-    TE("te"),
-    TH("th"),
-    BO("bo"),
-    TI("ti"),
-    TO("to"),
-    TS("ts"),
-    TN("tn"),
-    TR("tr"),
-    TK("tk"),
-    TW("tw"),
-    UG("ug"),
-    UK("uk"),
-    UR("ur"),
-    UZ("uz"),
-    VE("ve"),
-    VI("vi"),
-    VO("vo"),
-    WA("wa"),
-    CY("cy"),
-    FY("fy"),
-    WO("wo"),
-    XH("xh"),
-    YI("yi"),
-    YO("yo"),
-    ZA("za"),
-    ZU("zu");
-
-    private String value;
-
-    LanguageEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static LanguageEnum fromValue(String input) {
-      for (LanguageEnum b : LanguageEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<LanguageEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final LanguageEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public LanguageEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return LanguageEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("language")
-  private LanguageEnum language = null;
-
-  @SerializedName("license")
-  private LicenseDto license = null;
-
-  @SerializedName("creators")
-  private List<CreatorDto> creators = new ArrayList<CreatorDto>();
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("container id")
-  private Long containerId = null;
-
-  @SerializedName("database id")
-  private Long databaseId = null;
-
-  @SerializedName("query id")
-  private Long queryId = null;
-
-  @SerializedName("query_normalized")
-  private String queryNormalized = null;
-
-  @SerializedName("related")
-  private List<RelatedIdentifierDto> related = null;
-
-  @SerializedName("query_hash")
-  private String queryHash = null;
-
-  @SerializedName("result_hash")
-  private String resultHash = null;
-
-  @SerializedName("result_number")
-  private Long resultNumber = null;
-
-  @SerializedName("publication_day")
-  private Integer publicationDay = null;
-
-  @SerializedName("publication_month")
-  private Integer publicationMonth = null;
-
-  @SerializedName("publication_year")
-  private Integer publicationYear = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public IdentifierDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public IdentifierDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public IdentifierDto title(String title) {
-    this.title = title;
-    return this;
-  }
-
-   /**
-   * Get title
-   * @return title
-  **/
-  @Schema(example = "Airquality Stephansplatz, Vienna, Austria", required = true, description = "")
-  public String getTitle() {
-    return title;
-  }
-
-  public void setTitle(String title) {
-    this.title = title;
-  }
-
-  public IdentifierDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Air quality reports at Stephansplatz, Vienna", description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public IdentifierDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id`, `value`, `location` FROM `air_quality` WHERE `location` = \"09:STEF\"", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public IdentifierDto execution(OffsetDateTime execution) {
-    this.execution = execution;
-    return this;
-  }
-
-   /**
-   * Get execution
-   * @return execution
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getExecution() {
-    return execution;
-  }
-
-  public void setExecution(OffsetDateTime execution) {
-    this.execution = execution;
-  }
-
-  public IdentifierDto visibility(VisibilityEnum visibility) {
-    this.visibility = visibility;
-    return this;
-  }
-
-   /**
-   * Get visibility
-   * @return visibility
-  **/
-  @Schema(example = "everyone", required = true, description = "")
-  public VisibilityEnum getVisibility() {
-    return visibility;
-  }
-
-  public void setVisibility(VisibilityEnum visibility) {
-    this.visibility = visibility;
-  }
-
-  public IdentifierDto doi(String doi) {
-    this.doi = doi;
-    return this;
-  }
-
-   /**
-   * Get doi
-   * @return doi
-  **/
-  @Schema(example = "10.1038/nphys1170", description = "")
-  public String getDoi() {
-    return doi;
-  }
-
-  public void setDoi(String doi) {
-    this.doi = doi;
-  }
-
-  public IdentifierDto publisher(String publisher) {
-    this.publisher = publisher;
-    return this;
-  }
-
-   /**
-   * Get publisher
-   * @return publisher
-  **/
-  @Schema(example = "TU Wien", description = "")
-  public String getPublisher() {
-    return publisher;
-  }
-
-  public void setPublisher(String publisher) {
-    this.publisher = publisher;
-  }
-
-  public IdentifierDto language(LanguageEnum language) {
-    this.language = language;
-    return this;
-  }
-
-   /**
-   * Get language
-   * @return language
-  **/
-  @Schema(description = "")
-  public LanguageEnum getLanguage() {
-    return language;
-  }
-
-  public void setLanguage(LanguageEnum language) {
-    this.language = language;
-  }
-
-  public IdentifierDto license(LicenseDto license) {
-    this.license = license;
-    return this;
-  }
-
-   /**
-   * Get license
-   * @return license
-  **/
-  @Schema(description = "")
-  public LicenseDto getLicense() {
-    return license;
-  }
-
-  public void setLicense(LicenseDto license) {
-    this.license = license;
-  }
-
-  public IdentifierDto creators(List<CreatorDto> creators) {
-    this.creators = creators;
-    return this;
-  }
-
-  public IdentifierDto addCreatorsItem(CreatorDto creatorsItem) {
-    this.creators.add(creatorsItem);
-    return this;
-  }
-
-   /**
-   * Get creators
-   * @return creators
-  **/
-  @Schema(required = true, description = "")
-  public List<CreatorDto> getCreators() {
-    return creators;
-  }
-
-  public void setCreators(List<CreatorDto> creators) {
-    this.creators = creators;
-  }
-
-  public IdentifierDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public IdentifierDto containerId(Long containerId) {
-    this.containerId = containerId;
-    return this;
-  }
-
-   /**
-   * Get containerId
-   * @return containerId
-  **/
-  @Schema(example = "1", required = true, description = "")
-  public Long getContainerId() {
-    return containerId;
-  }
-
-  public void setContainerId(Long containerId) {
-    this.containerId = containerId;
-  }
-
-  public IdentifierDto databaseId(Long databaseId) {
-    this.databaseId = databaseId;
-    return this;
-  }
-
-   /**
-   * Get databaseId
-   * @return databaseId
-  **/
-  @Schema(example = "1", required = true, description = "")
-  public Long getDatabaseId() {
-    return databaseId;
-  }
-
-  public void setDatabaseId(Long databaseId) {
-    this.databaseId = databaseId;
-  }
-
-  public IdentifierDto queryId(Long queryId) {
-    this.queryId = queryId;
-    return this;
-  }
-
-   /**
-   * Get queryId
-   * @return queryId
-  **/
-  @Schema(example = "1", description = "")
-  public Long getQueryId() {
-    return queryId;
-  }
-
-  public void setQueryId(Long queryId) {
-    this.queryId = queryId;
-  }
-
-  public IdentifierDto queryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-    return this;
-  }
-
-   /**
-   * Get queryNormalized
-   * @return queryNormalized
-  **/
-  @Schema(example = "SELECT `id`, `value`, `location` FROM `air_quality` WHERE `location` = \"09:STEF\"", required = true, description = "")
-  public String getQueryNormalized() {
-    return queryNormalized;
-  }
-
-  public void setQueryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-  }
-
-  public IdentifierDto related(List<RelatedIdentifierDto> related) {
-    this.related = related;
-    return this;
-  }
-
-  public IdentifierDto addRelatedItem(RelatedIdentifierDto relatedItem) {
-    if (this.related == null) {
-      this.related = new ArrayList<RelatedIdentifierDto>();
-    }
-    this.related.add(relatedItem);
-    return this;
-  }
-
-   /**
-   * Get related
-   * @return related
-  **/
-  @Schema(description = "")
-  public List<RelatedIdentifierDto> getRelated() {
-    return related;
-  }
-
-  public void setRelated(List<RelatedIdentifierDto> related) {
-    this.related = related;
-  }
-
-  public IdentifierDto queryHash(String queryHash) {
-    this.queryHash = queryHash;
-    return this;
-  }
-
-   /**
-   * query hash in sha512
-   * @return queryHash
-  **/
-  @Schema(required = true, description = "query hash in sha512")
-  public String getQueryHash() {
-    return queryHash;
-  }
-
-  public void setQueryHash(String queryHash) {
-    this.queryHash = queryHash;
-  }
-
-  public IdentifierDto resultHash(String resultHash) {
-    this.resultHash = resultHash;
-    return this;
-  }
-
-   /**
-   * Get resultHash
-   * @return resultHash
-  **/
-  @Schema(required = true, description = "")
-  public String getResultHash() {
-    return resultHash;
-  }
-
-  public void setResultHash(String resultHash) {
-    this.resultHash = resultHash;
-  }
-
-  public IdentifierDto resultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-    return this;
-  }
-
-   /**
-   * Get resultNumber
-   * @return resultNumber
-  **/
-  @Schema(example = "1", required = true, description = "")
-  public Long getResultNumber() {
-    return resultNumber;
-  }
-
-  public void setResultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-  }
-
-  public IdentifierDto publicationDay(Integer publicationDay) {
-    this.publicationDay = publicationDay;
-    return this;
-  }
-
-   /**
-   * Get publicationDay
-   * @return publicationDay
-  **/
-  @Schema(example = "15", description = "")
-  public Integer getPublicationDay() {
-    return publicationDay;
-  }
-
-  public void setPublicationDay(Integer publicationDay) {
-    this.publicationDay = publicationDay;
-  }
-
-  public IdentifierDto publicationMonth(Integer publicationMonth) {
-    this.publicationMonth = publicationMonth;
-    return this;
-  }
-
-   /**
-   * Get publicationMonth
-   * @return publicationMonth
-  **/
-  @Schema(example = "12", description = "")
-  public Integer getPublicationMonth() {
-    return publicationMonth;
-  }
-
-  public void setPublicationMonth(Integer publicationMonth) {
-    this.publicationMonth = publicationMonth;
-  }
-
-  public IdentifierDto publicationYear(Integer publicationYear) {
-    this.publicationYear = publicationYear;
-    return this;
-  }
-
-   /**
-   * Get publicationYear
-   * @return publicationYear
-  **/
-  @Schema(example = "2022", required = true, description = "")
-  public Integer getPublicationYear() {
-    return publicationYear;
-  }
-
-  public void setPublicationYear(Integer publicationYear) {
-    this.publicationYear = publicationYear;
-  }
-
-  public IdentifierDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    IdentifierDto identifierDto = (IdentifierDto) o;
-    return Objects.equals(this.id, identifierDto.id) &&
-        Objects.equals(this.type, identifierDto.type) &&
-        Objects.equals(this.title, identifierDto.title) &&
-        Objects.equals(this.description, identifierDto.description) &&
-        Objects.equals(this.query, identifierDto.query) &&
-        Objects.equals(this.execution, identifierDto.execution) &&
-        Objects.equals(this.visibility, identifierDto.visibility) &&
-        Objects.equals(this.doi, identifierDto.doi) &&
-        Objects.equals(this.publisher, identifierDto.publisher) &&
-        Objects.equals(this.language, identifierDto.language) &&
-        Objects.equals(this.license, identifierDto.license) &&
-        Objects.equals(this.creators, identifierDto.creators) &&
-        Objects.equals(this.created, identifierDto.created) &&
-        Objects.equals(this.containerId, identifierDto.containerId) &&
-        Objects.equals(this.databaseId, identifierDto.databaseId) &&
-        Objects.equals(this.queryId, identifierDto.queryId) &&
-        Objects.equals(this.queryNormalized, identifierDto.queryNormalized) &&
-        Objects.equals(this.related, identifierDto.related) &&
-        Objects.equals(this.queryHash, identifierDto.queryHash) &&
-        Objects.equals(this.resultHash, identifierDto.resultHash) &&
-        Objects.equals(this.resultNumber, identifierDto.resultNumber) &&
-        Objects.equals(this.publicationDay, identifierDto.publicationDay) &&
-        Objects.equals(this.publicationMonth, identifierDto.publicationMonth) &&
-        Objects.equals(this.publicationYear, identifierDto.publicationYear) &&
-        Objects.equals(this.lastModified, identifierDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, type, title, description, query, execution, visibility, doi, publisher, language, license, creators, created, containerId, databaseId, queryId, queryNormalized, related, queryHash, resultHash, resultNumber, publicationDay, publicationMonth, publicationYear, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class IdentifierDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    title: ").append(toIndentedString(title)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    execution: ").append(toIndentedString(execution)).append("\n");
-    sb.append("    visibility: ").append(toIndentedString(visibility)).append("\n");
-    sb.append("    doi: ").append(toIndentedString(doi)).append("\n");
-    sb.append("    publisher: ").append(toIndentedString(publisher)).append("\n");
-    sb.append("    language: ").append(toIndentedString(language)).append("\n");
-    sb.append("    license: ").append(toIndentedString(license)).append("\n");
-    sb.append("    creators: ").append(toIndentedString(creators)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    containerId: ").append(toIndentedString(containerId)).append("\n");
-    sb.append("    databaseId: ").append(toIndentedString(databaseId)).append("\n");
-    sb.append("    queryId: ").append(toIndentedString(queryId)).append("\n");
-    sb.append("    queryNormalized: ").append(toIndentedString(queryNormalized)).append("\n");
-    sb.append("    related: ").append(toIndentedString(related)).append("\n");
-    sb.append("    queryHash: ").append(toIndentedString(queryHash)).append("\n");
-    sb.append("    resultHash: ").append(toIndentedString(resultHash)).append("\n");
-    sb.append("    resultNumber: ").append(toIndentedString(resultNumber)).append("\n");
-    sb.append("    publicationDay: ").append(toIndentedString(publicationDay)).append("\n");
-    sb.append("    publicationMonth: ").append(toIndentedString(publicationMonth)).append("\n");
-    sb.append("    publicationYear: ").append(toIndentedString(publicationYear)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageBriefDto.java
deleted file mode 100644
index d2ae31a12d5d7fec391c19c1c689dce288bbc5e4..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageBriefDto.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ImageBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("repository")
-  private String repository = null;
-
-  @SerializedName("tag")
-  private String tag = null;
-
-  public ImageBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ImageBriefDto repository(String repository) {
-    this.repository = repository;
-    return this;
-  }
-
-   /**
-   * Get repository
-   * @return repository
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getRepository() {
-    return repository;
-  }
-
-  public void setRepository(String repository) {
-    this.repository = repository;
-  }
-
-  public ImageBriefDto tag(String tag) {
-    this.tag = tag;
-    return this;
-  }
-
-   /**
-   * Get tag
-   * @return tag
-  **/
-  @Schema(example = "10.5", required = true, description = "")
-  public String getTag() {
-    return tag;
-  }
-
-  public void setTag(String tag) {
-    this.tag = tag;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageBriefDto imageBriefDto = (ImageBriefDto) o;
-    return Objects.equals(this.id, imageBriefDto.id) &&
-        Objects.equals(this.repository, imageBriefDto.repository) &&
-        Objects.equals(this.tag, imageBriefDto.tag);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, repository, tag);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    repository: ").append(toIndentedString(repository)).append("\n");
-    sb.append("    tag: ").append(toIndentedString(tag)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageChangeDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageChangeDto.java
deleted file mode 100644
index b8f65e8d1e08684e9391d32faa1d4d300ea2c6a5..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageChangeDto.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ImageEnvItemDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * ImageChangeDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageChangeDto {
-  @SerializedName("defaultPort")
-  private Integer defaultPort = null;
-
-  @SerializedName("environment")
-  private List<ImageEnvItemDto> environment = null;
-
-  @SerializedName("dialect")
-  private String dialect = null;
-
-  @SerializedName("driver_class")
-  private String driverClass = null;
-
-  @SerializedName("jdbc_method")
-  private String jdbcMethod = null;
-
-  public ImageChangeDto defaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-    return this;
-  }
-
-   /**
-   * Get defaultPort
-   * minimum: 1024
-   * maximum: 65535
-   * @return defaultPort
-  **/
-  @Schema(example = "5432", description = "")
-  public Integer getDefaultPort() {
-    return defaultPort;
-  }
-
-  public void setDefaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-  }
-
-  public ImageChangeDto environment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-    return this;
-  }
-
-  public ImageChangeDto addEnvironmentItem(ImageEnvItemDto environmentItem) {
-    if (this.environment == null) {
-      this.environment = new ArrayList<ImageEnvItemDto>();
-    }
-    this.environment.add(environmentItem);
-    return this;
-  }
-
-   /**
-   * Get environment
-   * @return environment
-  **/
-  @Schema(description = "")
-  public List<ImageEnvItemDto> getEnvironment() {
-    return environment;
-  }
-
-  public void setEnvironment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-  }
-
-  public ImageChangeDto dialect(String dialect) {
-    this.dialect = dialect;
-    return this;
-  }
-
-   /**
-   * Get dialect
-   * @return dialect
-  **/
-  @Schema(example = "Postgres", required = true, description = "")
-  public String getDialect() {
-    return dialect;
-  }
-
-  public void setDialect(String dialect) {
-    this.dialect = dialect;
-  }
-
-  public ImageChangeDto driverClass(String driverClass) {
-    this.driverClass = driverClass;
-    return this;
-  }
-
-   /**
-   * Get driverClass
-   * @return driverClass
-  **/
-  @Schema(example = "org.postgresql.Driver", required = true, description = "")
-  public String getDriverClass() {
-    return driverClass;
-  }
-
-  public void setDriverClass(String driverClass) {
-    this.driverClass = driverClass;
-  }
-
-  public ImageChangeDto jdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-    return this;
-  }
-
-   /**
-   * Get jdbcMethod
-   * @return jdbcMethod
-  **/
-  @Schema(example = "postgresql", required = true, description = "")
-  public String getJdbcMethod() {
-    return jdbcMethod;
-  }
-
-  public void setJdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageChangeDto imageChangeDto = (ImageChangeDto) o;
-    return Objects.equals(this.defaultPort, imageChangeDto.defaultPort) &&
-        Objects.equals(this.environment, imageChangeDto.environment) &&
-        Objects.equals(this.dialect, imageChangeDto.dialect) &&
-        Objects.equals(this.driverClass, imageChangeDto.driverClass) &&
-        Objects.equals(this.jdbcMethod, imageChangeDto.jdbcMethod);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(defaultPort, environment, dialect, driverClass, jdbcMethod);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageChangeDto {\n");
-    
-    sb.append("    defaultPort: ").append(toIndentedString(defaultPort)).append("\n");
-    sb.append("    environment: ").append(toIndentedString(environment)).append("\n");
-    sb.append("    dialect: ").append(toIndentedString(dialect)).append("\n");
-    sb.append("    driverClass: ").append(toIndentedString(driverClass)).append("\n");
-    sb.append("    jdbcMethod: ").append(toIndentedString(jdbcMethod)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageCreateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageCreateDto.java
deleted file mode 100644
index 3260671ca72dfeeccf9ae377aa89109a8e36250e..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageCreateDto.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ImageEnvItemDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * ImageCreateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageCreateDto {
-  @SerializedName("repository")
-  private String repository = null;
-
-  @SerializedName("tag")
-  private String tag = null;
-
-  @SerializedName("dialect")
-  private String dialect = null;
-
-  @SerializedName("environment")
-  private List<ImageEnvItemDto> environment = null;
-
-  @SerializedName("driver_class")
-  private String driverClass = null;
-
-  @SerializedName("jdbc_method")
-  private String jdbcMethod = null;
-
-  @SerializedName("default_port")
-  private Integer defaultPort = null;
-
-  public ImageCreateDto repository(String repository) {
-    this.repository = repository;
-    return this;
-  }
-
-   /**
-   * Get repository
-   * @return repository
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getRepository() {
-    return repository;
-  }
-
-  public void setRepository(String repository) {
-    this.repository = repository;
-  }
-
-  public ImageCreateDto tag(String tag) {
-    this.tag = tag;
-    return this;
-  }
-
-   /**
-   * Get tag
-   * @return tag
-  **/
-  @Schema(required = true, description = "")
-  public String getTag() {
-    return tag;
-  }
-
-  public void setTag(String tag) {
-    this.tag = tag;
-  }
-
-  public ImageCreateDto dialect(String dialect) {
-    this.dialect = dialect;
-    return this;
-  }
-
-   /**
-   * Get dialect
-   * @return dialect
-  **/
-  @Schema(required = true, description = "")
-  public String getDialect() {
-    return dialect;
-  }
-
-  public void setDialect(String dialect) {
-    this.dialect = dialect;
-  }
-
-  public ImageCreateDto environment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-    return this;
-  }
-
-  public ImageCreateDto addEnvironmentItem(ImageEnvItemDto environmentItem) {
-    if (this.environment == null) {
-      this.environment = new ArrayList<ImageEnvItemDto>();
-    }
-    this.environment.add(environmentItem);
-    return this;
-  }
-
-   /**
-   * Get environment
-   * @return environment
-  **/
-  @Schema(description = "")
-  public List<ImageEnvItemDto> getEnvironment() {
-    return environment;
-  }
-
-  public void setEnvironment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-  }
-
-  public ImageCreateDto driverClass(String driverClass) {
-    this.driverClass = driverClass;
-    return this;
-  }
-
-   /**
-   * Get driverClass
-   * @return driverClass
-  **/
-  @Schema(required = true, description = "")
-  public String getDriverClass() {
-    return driverClass;
-  }
-
-  public void setDriverClass(String driverClass) {
-    this.driverClass = driverClass;
-  }
-
-  public ImageCreateDto jdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-    return this;
-  }
-
-   /**
-   * Get jdbcMethod
-   * @return jdbcMethod
-  **/
-  @Schema(required = true, description = "")
-  public String getJdbcMethod() {
-    return jdbcMethod;
-  }
-
-  public void setJdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-  }
-
-  public ImageCreateDto defaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-    return this;
-  }
-
-   /**
-   * Get defaultPort
-   * @return defaultPort
-  **/
-  @Schema(required = true, description = "")
-  public Integer getDefaultPort() {
-    return defaultPort;
-  }
-
-  public void setDefaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageCreateDto imageCreateDto = (ImageCreateDto) o;
-    return Objects.equals(this.repository, imageCreateDto.repository) &&
-        Objects.equals(this.tag, imageCreateDto.tag) &&
-        Objects.equals(this.dialect, imageCreateDto.dialect) &&
-        Objects.equals(this.environment, imageCreateDto.environment) &&
-        Objects.equals(this.driverClass, imageCreateDto.driverClass) &&
-        Objects.equals(this.jdbcMethod, imageCreateDto.jdbcMethod) &&
-        Objects.equals(this.defaultPort, imageCreateDto.defaultPort);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(repository, tag, dialect, environment, driverClass, jdbcMethod, defaultPort);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageCreateDto {\n");
-    
-    sb.append("    repository: ").append(toIndentedString(repository)).append("\n");
-    sb.append("    tag: ").append(toIndentedString(tag)).append("\n");
-    sb.append("    dialect: ").append(toIndentedString(dialect)).append("\n");
-    sb.append("    environment: ").append(toIndentedString(environment)).append("\n");
-    sb.append("    driverClass: ").append(toIndentedString(driverClass)).append("\n");
-    sb.append("    jdbcMethod: ").append(toIndentedString(jdbcMethod)).append("\n");
-    sb.append("    defaultPort: ").append(toIndentedString(defaultPort)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageDateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageDateDto.java
deleted file mode 100644
index 632d57bbab95fc0e76915954d1812d4a9417028b..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageDateDto.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ImageDateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageDateDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("example")
-  private String example = null;
-
-  @SerializedName("database_format")
-  private String databaseFormat = null;
-
-  @SerializedName("unix_format")
-  private String unixFormat = null;
-
-  @SerializedName("has_time")
-  private Boolean hasTime = null;
-
-  @SerializedName("created_at")
-  private OffsetDateTime createdAt = null;
-
-  public ImageDateDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ImageDateDto example(String example) {
-    this.example = example;
-    return this;
-  }
-
-   /**
-   * Get example
-   * @return example
-  **/
-  @Schema(example = "30.01.2022", required = true, description = "")
-  public String getExample() {
-    return example;
-  }
-
-  public void setExample(String example) {
-    this.example = example;
-  }
-
-  public ImageDateDto databaseFormat(String databaseFormat) {
-    this.databaseFormat = databaseFormat;
-    return this;
-  }
-
-   /**
-   * Get databaseFormat
-   * @return databaseFormat
-  **/
-  @Schema(example = "%d.%c.%Y", required = true, description = "")
-  public String getDatabaseFormat() {
-    return databaseFormat;
-  }
-
-  public void setDatabaseFormat(String databaseFormat) {
-    this.databaseFormat = databaseFormat;
-  }
-
-  public ImageDateDto unixFormat(String unixFormat) {
-    this.unixFormat = unixFormat;
-    return this;
-  }
-
-   /**
-   * Get unixFormat
-   * @return unixFormat
-  **/
-  @Schema(example = "dd.MM.YYYY", required = true, description = "")
-  public String getUnixFormat() {
-    return unixFormat;
-  }
-
-  public void setUnixFormat(String unixFormat) {
-    this.unixFormat = unixFormat;
-  }
-
-  public ImageDateDto hasTime(Boolean hasTime) {
-    this.hasTime = hasTime;
-    return this;
-  }
-
-   /**
-   * Get hasTime
-   * @return hasTime
-  **/
-  @Schema(example = "false", required = true, description = "")
-  public Boolean isHasTime() {
-    return hasTime;
-  }
-
-  public void setHasTime(Boolean hasTime) {
-    this.hasTime = hasTime;
-  }
-
-  public ImageDateDto createdAt(OffsetDateTime createdAt) {
-    this.createdAt = createdAt;
-    return this;
-  }
-
-   /**
-   * Get createdAt
-   * @return createdAt
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreatedAt() {
-    return createdAt;
-  }
-
-  public void setCreatedAt(OffsetDateTime createdAt) {
-    this.createdAt = createdAt;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageDateDto imageDateDto = (ImageDateDto) o;
-    return Objects.equals(this.id, imageDateDto.id) &&
-        Objects.equals(this.example, imageDateDto.example) &&
-        Objects.equals(this.databaseFormat, imageDateDto.databaseFormat) &&
-        Objects.equals(this.unixFormat, imageDateDto.unixFormat) &&
-        Objects.equals(this.hasTime, imageDateDto.hasTime) &&
-        Objects.equals(this.createdAt, imageDateDto.createdAt);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, example, databaseFormat, unixFormat, hasTime, createdAt);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageDateDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    example: ").append(toIndentedString(example)).append("\n");
-    sb.append("    databaseFormat: ").append(toIndentedString(databaseFormat)).append("\n");
-    sb.append("    unixFormat: ").append(toIndentedString(unixFormat)).append("\n");
-    sb.append("    hasTime: ").append(toIndentedString(hasTime)).append("\n");
-    sb.append("    createdAt: ").append(toIndentedString(createdAt)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageDto.java
deleted file mode 100644
index 2649563381cdc21f413ea01b32a8b6ea748c011e..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageDto.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ImageDateDto;
-import io.swagger.client.model.ImageEnvItemDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ImageDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("repository")
-  private String repository = null;
-
-  @SerializedName("tag")
-  private String tag = null;
-
-  @SerializedName("dialect")
-  private String dialect = null;
-
-  @SerializedName("hash")
-  private String hash = null;
-
-  @SerializedName("compiled")
-  private OffsetDateTime compiled = null;
-
-  @SerializedName("size")
-  private Integer size = null;
-
-  @SerializedName("environment")
-  private List<ImageEnvItemDto> environment = new ArrayList<ImageEnvItemDto>();
-
-  @SerializedName("driver_class")
-  private String driverClass = null;
-
-  @SerializedName("date_formats")
-  private List<ImageDateDto> dateFormats = null;
-
-  @SerializedName("jdbc_method")
-  private String jdbcMethod = null;
-
-  @SerializedName("default_port")
-  private Integer defaultPort = null;
-
-  public ImageDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ImageDto repository(String repository) {
-    this.repository = repository;
-    return this;
-  }
-
-   /**
-   * Get repository
-   * @return repository
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getRepository() {
-    return repository;
-  }
-
-  public void setRepository(String repository) {
-    this.repository = repository;
-  }
-
-  public ImageDto tag(String tag) {
-    this.tag = tag;
-    return this;
-  }
-
-   /**
-   * Get tag
-   * @return tag
-  **/
-  @Schema(example = "10.5", required = true, description = "")
-  public String getTag() {
-    return tag;
-  }
-
-  public void setTag(String tag) {
-    this.tag = tag;
-  }
-
-  public ImageDto dialect(String dialect) {
-    this.dialect = dialect;
-    return this;
-  }
-
-   /**
-   * Get dialect
-   * @return dialect
-  **/
-  @Schema(example = "org.hibernate.dialect.MariaDBDialect", required = true, description = "")
-  public String getDialect() {
-    return dialect;
-  }
-
-  public void setDialect(String dialect) {
-    this.dialect = dialect;
-  }
-
-  public ImageDto hash(String hash) {
-    this.hash = hash;
-    return this;
-  }
-
-   /**
-   * Get hash
-   * @return hash
-  **/
-  @Schema(example = "sha256:c5ec7353d87dfc35067e7bffeb25d6a0d52dad41e8b7357213e3b12d6e7ff78e", description = "")
-  public String getHash() {
-    return hash;
-  }
-
-  public void setHash(String hash) {
-    this.hash = hash;
-  }
-
-  public ImageDto compiled(OffsetDateTime compiled) {
-    this.compiled = compiled;
-    return this;
-  }
-
-   /**
-   * Get compiled
-   * @return compiled
-  **/
-  @Schema(example = "2021-03-12T15:26:21.678396092Z", description = "")
-  public OffsetDateTime getCompiled() {
-    return compiled;
-  }
-
-  public void setCompiled(OffsetDateTime compiled) {
-    this.compiled = compiled;
-  }
-
-  public ImageDto size(Integer size) {
-    this.size = size;
-    return this;
-  }
-
-   /**
-   * Get size
-   * @return size
-  **/
-  @Schema(example = "314295447", description = "")
-  public Integer getSize() {
-    return size;
-  }
-
-  public void setSize(Integer size) {
-    this.size = size;
-  }
-
-  public ImageDto environment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-    return this;
-  }
-
-  public ImageDto addEnvironmentItem(ImageEnvItemDto environmentItem) {
-    this.environment.add(environmentItem);
-    return this;
-  }
-
-   /**
-   * Get environment
-   * @return environment
-  **/
-  @Schema(required = true, description = "")
-  public List<ImageEnvItemDto> getEnvironment() {
-    return environment;
-  }
-
-  public void setEnvironment(List<ImageEnvItemDto> environment) {
-    this.environment = environment;
-  }
-
-  public ImageDto driverClass(String driverClass) {
-    this.driverClass = driverClass;
-    return this;
-  }
-
-   /**
-   * Get driverClass
-   * @return driverClass
-  **/
-  @Schema(example = "org.mariadb.jdbc.Driver", required = true, description = "")
-  public String getDriverClass() {
-    return driverClass;
-  }
-
-  public void setDriverClass(String driverClass) {
-    this.driverClass = driverClass;
-  }
-
-  public ImageDto dateFormats(List<ImageDateDto> dateFormats) {
-    this.dateFormats = dateFormats;
-    return this;
-  }
-
-  public ImageDto addDateFormatsItem(ImageDateDto dateFormatsItem) {
-    if (this.dateFormats == null) {
-      this.dateFormats = new ArrayList<ImageDateDto>();
-    }
-    this.dateFormats.add(dateFormatsItem);
-    return this;
-  }
-
-   /**
-   * Get dateFormats
-   * @return dateFormats
-  **/
-  @Schema(description = "")
-  public List<ImageDateDto> getDateFormats() {
-    return dateFormats;
-  }
-
-  public void setDateFormats(List<ImageDateDto> dateFormats) {
-    this.dateFormats = dateFormats;
-  }
-
-  public ImageDto jdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-    return this;
-  }
-
-   /**
-   * Get jdbcMethod
-   * @return jdbcMethod
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getJdbcMethod() {
-    return jdbcMethod;
-  }
-
-  public void setJdbcMethod(String jdbcMethod) {
-    this.jdbcMethod = jdbcMethod;
-  }
-
-  public ImageDto defaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-    return this;
-  }
-
-   /**
-   * Get defaultPort
-   * @return defaultPort
-  **/
-  @Schema(example = "3306", required = true, description = "")
-  public Integer getDefaultPort() {
-    return defaultPort;
-  }
-
-  public void setDefaultPort(Integer defaultPort) {
-    this.defaultPort = defaultPort;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageDto imageDto = (ImageDto) o;
-    return Objects.equals(this.id, imageDto.id) &&
-        Objects.equals(this.repository, imageDto.repository) &&
-        Objects.equals(this.tag, imageDto.tag) &&
-        Objects.equals(this.dialect, imageDto.dialect) &&
-        Objects.equals(this.hash, imageDto.hash) &&
-        Objects.equals(this.compiled, imageDto.compiled) &&
-        Objects.equals(this.size, imageDto.size) &&
-        Objects.equals(this.environment, imageDto.environment) &&
-        Objects.equals(this.driverClass, imageDto.driverClass) &&
-        Objects.equals(this.dateFormats, imageDto.dateFormats) &&
-        Objects.equals(this.jdbcMethod, imageDto.jdbcMethod) &&
-        Objects.equals(this.defaultPort, imageDto.defaultPort);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, repository, tag, dialect, hash, compiled, size, environment, driverClass, dateFormats, jdbcMethod, defaultPort);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    repository: ").append(toIndentedString(repository)).append("\n");
-    sb.append("    tag: ").append(toIndentedString(tag)).append("\n");
-    sb.append("    dialect: ").append(toIndentedString(dialect)).append("\n");
-    sb.append("    hash: ").append(toIndentedString(hash)).append("\n");
-    sb.append("    compiled: ").append(toIndentedString(compiled)).append("\n");
-    sb.append("    size: ").append(toIndentedString(size)).append("\n");
-    sb.append("    environment: ").append(toIndentedString(environment)).append("\n");
-    sb.append("    driverClass: ").append(toIndentedString(driverClass)).append("\n");
-    sb.append("    dateFormats: ").append(toIndentedString(dateFormats)).append("\n");
-    sb.append("    jdbcMethod: ").append(toIndentedString(jdbcMethod)).append("\n");
-    sb.append("    defaultPort: ").append(toIndentedString(defaultPort)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImageEnvItemDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImageEnvItemDto.java
deleted file mode 100644
index bdd73d8fc340af373692095261b50424ad4f35a7..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImageEnvItemDto.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ImageEnvItemDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class ImageEnvItemDto {
-  @SerializedName("iid")
-  private Long iid = null;
-
-  @SerializedName("key")
-  private String key = null;
-
-  @SerializedName("value")
-  private String value = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    USERNAME("username"),
-    PASSWORD("password"),
-    PRIVILEGED_USERNAME("privileged_username"),
-    PRIVILEGED_PASSWORD("privileged_password");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  public ImageEnvItemDto iid(Long iid) {
-    this.iid = iid;
-    return this;
-  }
-
-   /**
-   * Get iid
-   * @return iid
-  **/
-  @Schema(required = true, description = "")
-  public Long getIid() {
-    return iid;
-  }
-
-  public void setIid(Long iid) {
-    this.iid = iid;
-  }
-
-  public ImageEnvItemDto key(String key) {
-    this.key = key;
-    return this;
-  }
-
-   /**
-   * Get key
-   * @return key
-  **/
-  @Schema(example = "MARIADB_ROOT_PASSWORD", required = true, description = "")
-  public String getKey() {
-    return key;
-  }
-
-  public void setKey(String key) {
-    this.key = key;
-  }
-
-  public ImageEnvItemDto value(String value) {
-    this.value = value;
-    return this;
-  }
-
-   /**
-   * Get value
-   * @return value
-  **/
-  @Schema(example = "mariadb", required = true, description = "")
-  public String getValue() {
-    return value;
-  }
-
-  public void setValue(String value) {
-    this.value = value;
-  }
-
-  public ImageEnvItemDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(example = "PRIVILEGED_PASSWORD", required = true, description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImageEnvItemDto imageEnvItemDto = (ImageEnvItemDto) o;
-    return Objects.equals(this.iid, imageEnvItemDto.iid) &&
-        Objects.equals(this.key, imageEnvItemDto.key) &&
-        Objects.equals(this.value, imageEnvItemDto.value) &&
-        Objects.equals(this.type, imageEnvItemDto.type);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(iid, key, value, type);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImageEnvItemDto {\n");
-    
-    sb.append("    iid: ").append(toIndentedString(iid)).append("\n");
-    sb.append("    key: ").append(toIndentedString(key)).append("\n");
-    sb.append("    value: ").append(toIndentedString(value)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ImportDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ImportDto.java
deleted file mode 100644
index 2aa325af7f733473341aa71bc228332d5c9f1850..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ImportDto.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ImportDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class ImportDto {
-  @SerializedName("location")
-  private String location = null;
-
-  @SerializedName("separator")
-  private String separator = null;
-
-  @SerializedName("quote")
-  private String quote = null;
-
-  @SerializedName("skip_lines")
-  private Long skipLines = null;
-
-  @SerializedName("false_element")
-  private String falseElement = null;
-
-  @SerializedName("true_element")
-  private String trueElement = null;
-
-  @SerializedName("null_element")
-  private String nullElement = null;
-
-  public ImportDto location(String location) {
-    this.location = location;
-    return this;
-  }
-
-   /**
-   * Get location
-   * @return location
-  **/
-  @Schema(example = "/tmp/file.csv", required = true, description = "")
-  public String getLocation() {
-    return location;
-  }
-
-  public void setLocation(String location) {
-    this.location = location;
-  }
-
-  public ImportDto separator(String separator) {
-    this.separator = separator;
-    return this;
-  }
-
-   /**
-   * Get separator
-   * @return separator
-  **/
-  @Schema(example = ",", required = true, description = "")
-  public String getSeparator() {
-    return separator;
-  }
-
-  public void setSeparator(String separator) {
-    this.separator = separator;
-  }
-
-  public ImportDto quote(String quote) {
-    this.quote = quote;
-    return this;
-  }
-
-   /**
-   * Get quote
-   * @return quote
-  **/
-  @Schema(example = "\"", description = "")
-  public String getQuote() {
-    return quote;
-  }
-
-  public void setQuote(String quote) {
-    this.quote = quote;
-  }
-
-  public ImportDto skipLines(Long skipLines) {
-    this.skipLines = skipLines;
-    return this;
-  }
-
-   /**
-   * Get skipLines
-   * minimum: 0
-   * @return skipLines
-  **/
-  @Schema(description = "")
-  public Long getSkipLines() {
-    return skipLines;
-  }
-
-  public void setSkipLines(Long skipLines) {
-    this.skipLines = skipLines;
-  }
-
-  public ImportDto falseElement(String falseElement) {
-    this.falseElement = falseElement;
-    return this;
-  }
-
-   /**
-   * Get falseElement
-   * @return falseElement
-  **/
-  @Schema(description = "")
-  public String getFalseElement() {
-    return falseElement;
-  }
-
-  public void setFalseElement(String falseElement) {
-    this.falseElement = falseElement;
-  }
-
-  public ImportDto trueElement(String trueElement) {
-    this.trueElement = trueElement;
-    return this;
-  }
-
-   /**
-   * Get trueElement
-   * @return trueElement
-  **/
-  @Schema(description = "")
-  public String getTrueElement() {
-    return trueElement;
-  }
-
-  public void setTrueElement(String trueElement) {
-    this.trueElement = trueElement;
-  }
-
-  public ImportDto nullElement(String nullElement) {
-    this.nullElement = nullElement;
-    return this;
-  }
-
-   /**
-   * Get nullElement
-   * @return nullElement
-  **/
-  @Schema(example = "NA", description = "")
-  public String getNullElement() {
-    return nullElement;
-  }
-
-  public void setNullElement(String nullElement) {
-    this.nullElement = nullElement;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ImportDto importDto = (ImportDto) o;
-    return Objects.equals(this.location, importDto.location) &&
-        Objects.equals(this.separator, importDto.separator) &&
-        Objects.equals(this.quote, importDto.quote) &&
-        Objects.equals(this.skipLines, importDto.skipLines) &&
-        Objects.equals(this.falseElement, importDto.falseElement) &&
-        Objects.equals(this.trueElement, importDto.trueElement) &&
-        Objects.equals(this.nullElement, importDto.nullElement);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(location, separator, quote, skipLines, falseElement, trueElement, nullElement);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ImportDto {\n");
-    
-    sb.append("    location: ").append(toIndentedString(location)).append("\n");
-    sb.append("    separator: ").append(toIndentedString(separator)).append("\n");
-    sb.append("    quote: ").append(toIndentedString(quote)).append("\n");
-    sb.append("    skipLines: ").append(toIndentedString(skipLines)).append("\n");
-    sb.append("    falseElement: ").append(toIndentedString(falseElement)).append("\n");
-    sb.append("    trueElement: ").append(toIndentedString(trueElement)).append("\n");
-    sb.append("    nullElement: ").append(toIndentedString(nullElement)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/LicenseDto.java b/.java-stubs/src/main/java/io/swagger/client/model/LicenseDto.java
deleted file mode 100644
index 05bfde41254ffbe87812bd882d6a9401f3098084..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/LicenseDto.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * LicenseDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class LicenseDto {
-  @SerializedName("identifier")
-  private String identifier = null;
-
-  @SerializedName("uri")
-  private String uri = null;
-
-  public LicenseDto identifier(String identifier) {
-    this.identifier = identifier;
-    return this;
-  }
-
-   /**
-   * Get identifier
-   * @return identifier
-  **/
-  @Schema(example = "MIT", required = true, description = "")
-  public String getIdentifier() {
-    return identifier;
-  }
-
-  public void setIdentifier(String identifier) {
-    this.identifier = identifier;
-  }
-
-  public LicenseDto uri(String uri) {
-    this.uri = uri;
-    return this;
-  }
-
-   /**
-   * Get uri
-   * @return uri
-  **/
-  @Schema(example = "https://opensource.org/licenses/MIT", required = true, description = "")
-  public String getUri() {
-    return uri;
-  }
-
-  public void setUri(String uri) {
-    this.uri = uri;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    LicenseDto licenseDto = (LicenseDto) o;
-    return Objects.equals(this.identifier, licenseDto.identifier) &&
-        Objects.equals(this.uri, licenseDto.uri);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(identifier, uri);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class LicenseDto {\n");
-    
-    sb.append("    identifier: ").append(toIndentedString(identifier)).append("\n");
-    sb.append("    uri: ").append(toIndentedString(uri)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/QueryBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/QueryBriefDto.java
deleted file mode 100644
index 50ac6d4abed03f64623da1237facad7eeba6ae03..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/QueryBriefDto.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.UserDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * QueryBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class QueryBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("cid")
-  private Long cid = null;
-
-  @SerializedName("dbid")
-  private Long dbid = null;
-
-  @SerializedName("creator")
-  private UserDto creator = null;
-
-  @SerializedName("execution")
-  private OffsetDateTime execution = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    QUERY("query"),
-    VIEW("view");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("query_normalized")
-  private String queryNormalized = null;
-
-  @SerializedName("query_hash")
-  private String queryHash = null;
-
-  @SerializedName("result_hash")
-  private String resultHash = null;
-
-  @SerializedName("result_number")
-  private Long resultNumber = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public QueryBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public QueryBriefDto cid(Long cid) {
-    this.cid = cid;
-    return this;
-  }
-
-   /**
-   * Get cid
-   * @return cid
-  **/
-  @Schema(required = true, description = "")
-  public Long getCid() {
-    return cid;
-  }
-
-  public void setCid(Long cid) {
-    this.cid = cid;
-  }
-
-  public QueryBriefDto dbid(Long dbid) {
-    this.dbid = dbid;
-    return this;
-  }
-
-   /**
-   * Get dbid
-   * @return dbid
-  **/
-  @Schema(required = true, description = "")
-  public Long getDbid() {
-    return dbid;
-  }
-
-  public void setDbid(Long dbid) {
-    this.dbid = dbid;
-  }
-
-  public QueryBriefDto creator(UserDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserDto creator) {
-    this.creator = creator;
-  }
-
-  public QueryBriefDto execution(OffsetDateTime execution) {
-    this.execution = execution;
-    return this;
-  }
-
-   /**
-   * Get execution
-   * @return execution
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getExecution() {
-    return execution;
-  }
-
-  public void setExecution(OffsetDateTime execution) {
-    this.execution = execution;
-  }
-
-  public QueryBriefDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public QueryBriefDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(example = "query", description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public QueryBriefDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public QueryBriefDto queryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-    return this;
-  }
-
-   /**
-   * Get queryNormalized
-   * @return queryNormalized
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", description = "")
-  public String getQueryNormalized() {
-    return queryNormalized;
-  }
-
-  public void setQueryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-  }
-
-  public QueryBriefDto queryHash(String queryHash) {
-    this.queryHash = queryHash;
-    return this;
-  }
-
-   /**
-   * Get queryHash
-   * @return queryHash
-  **/
-  @Schema(example = "17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76", required = true, description = "")
-  public String getQueryHash() {
-    return queryHash;
-  }
-
-  public void setQueryHash(String queryHash) {
-    this.queryHash = queryHash;
-  }
-
-  public QueryBriefDto resultHash(String resultHash) {
-    this.resultHash = resultHash;
-    return this;
-  }
-
-   /**
-   * Get resultHash
-   * @return resultHash
-  **/
-  @Schema(example = "17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76", description = "")
-  public String getResultHash() {
-    return resultHash;
-  }
-
-  public void setResultHash(String resultHash) {
-    this.resultHash = resultHash;
-  }
-
-  public QueryBriefDto resultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-    return this;
-  }
-
-   /**
-   * Get resultNumber
-   * @return resultNumber
-  **/
-  @Schema(example = "1", description = "")
-  public Long getResultNumber() {
-    return resultNumber;
-  }
-
-  public void setResultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-  }
-
-  public QueryBriefDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    QueryBriefDto queryBriefDto = (QueryBriefDto) o;
-    return Objects.equals(this.id, queryBriefDto.id) &&
-        Objects.equals(this.cid, queryBriefDto.cid) &&
-        Objects.equals(this.dbid, queryBriefDto.dbid) &&
-        Objects.equals(this.creator, queryBriefDto.creator) &&
-        Objects.equals(this.execution, queryBriefDto.execution) &&
-        Objects.equals(this.query, queryBriefDto.query) &&
-        Objects.equals(this.type, queryBriefDto.type) &&
-        Objects.equals(this.created, queryBriefDto.created) &&
-        Objects.equals(this.queryNormalized, queryBriefDto.queryNormalized) &&
-        Objects.equals(this.queryHash, queryBriefDto.queryHash) &&
-        Objects.equals(this.resultHash, queryBriefDto.resultHash) &&
-        Objects.equals(this.resultNumber, queryBriefDto.resultNumber) &&
-        Objects.equals(this.lastModified, queryBriefDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, cid, dbid, creator, execution, query, type, created, queryNormalized, queryHash, resultHash, resultNumber, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class QueryBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    cid: ").append(toIndentedString(cid)).append("\n");
-    sb.append("    dbid: ").append(toIndentedString(dbid)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    execution: ").append(toIndentedString(execution)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    queryNormalized: ").append(toIndentedString(queryNormalized)).append("\n");
-    sb.append("    queryHash: ").append(toIndentedString(queryHash)).append("\n");
-    sb.append("    resultHash: ").append(toIndentedString(resultHash)).append("\n");
-    sb.append("    resultNumber: ").append(toIndentedString(resultNumber)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/QueryDto.java b/.java-stubs/src/main/java/io/swagger/client/model/QueryDto.java
deleted file mode 100644
index 3740c6d3fdcc1352e3140e6e9418b799949646e1..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/QueryDto.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.UserDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * QueryDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class QueryDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("cid")
-  private Long cid = null;
-
-  @SerializedName("dbid")
-  private Long dbid = null;
-
-  @SerializedName("creator")
-  private UserDto creator = null;
-
-  @SerializedName("execution")
-  private OffsetDateTime execution = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    QUERY("query"),
-    VIEW("view");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("query_normalized")
-  private String queryNormalized = null;
-
-  @SerializedName("query_hash")
-  private String queryHash = null;
-
-  @SerializedName("is_persisted")
-  private Boolean isPersisted = null;
-
-  @SerializedName("result_hash")
-  private String resultHash = null;
-
-  @SerializedName("result_number")
-  private Long resultNumber = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public QueryDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public QueryDto cid(Long cid) {
-    this.cid = cid;
-    return this;
-  }
-
-   /**
-   * Get cid
-   * @return cid
-  **/
-  @Schema(required = true, description = "")
-  public Long getCid() {
-    return cid;
-  }
-
-  public void setCid(Long cid) {
-    this.cid = cid;
-  }
-
-  public QueryDto dbid(Long dbid) {
-    this.dbid = dbid;
-    return this;
-  }
-
-   /**
-   * Get dbid
-   * @return dbid
-  **/
-  @Schema(required = true, description = "")
-  public Long getDbid() {
-    return dbid;
-  }
-
-  public void setDbid(Long dbid) {
-    this.dbid = dbid;
-  }
-
-  public QueryDto creator(UserDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserDto creator) {
-    this.creator = creator;
-  }
-
-  public QueryDto execution(OffsetDateTime execution) {
-    this.execution = execution;
-    return this;
-  }
-
-   /**
-   * Get execution
-   * @return execution
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getExecution() {
-    return execution;
-  }
-
-  public void setExecution(OffsetDateTime execution) {
-    this.execution = execution;
-  }
-
-  public QueryDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public QueryDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(example = "query", description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public QueryDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public QueryDto queryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-    return this;
-  }
-
-   /**
-   * Get queryNormalized
-   * @return queryNormalized
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", description = "")
-  public String getQueryNormalized() {
-    return queryNormalized;
-  }
-
-  public void setQueryNormalized(String queryNormalized) {
-    this.queryNormalized = queryNormalized;
-  }
-
-  public QueryDto queryHash(String queryHash) {
-    this.queryHash = queryHash;
-    return this;
-  }
-
-   /**
-   * Get queryHash
-   * @return queryHash
-  **/
-  @Schema(required = true, description = "")
-  public String getQueryHash() {
-    return queryHash;
-  }
-
-  public void setQueryHash(String queryHash) {
-    this.queryHash = queryHash;
-  }
-
-  public QueryDto isPersisted(Boolean isPersisted) {
-    this.isPersisted = isPersisted;
-    return this;
-  }
-
-   /**
-   * Get isPersisted
-   * @return isPersisted
-  **/
-  @Schema(required = true, description = "")
-  public Boolean isIsPersisted() {
-    return isPersisted;
-  }
-
-  public void setIsPersisted(Boolean isPersisted) {
-    this.isPersisted = isPersisted;
-  }
-
-  public QueryDto resultHash(String resultHash) {
-    this.resultHash = resultHash;
-    return this;
-  }
-
-   /**
-   * Get resultHash
-   * @return resultHash
-  **/
-  @Schema(description = "")
-  public String getResultHash() {
-    return resultHash;
-  }
-
-  public void setResultHash(String resultHash) {
-    this.resultHash = resultHash;
-  }
-
-  public QueryDto resultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-    return this;
-  }
-
-   /**
-   * Get resultNumber
-   * @return resultNumber
-  **/
-  @Schema(example = "1", description = "")
-  public Long getResultNumber() {
-    return resultNumber;
-  }
-
-  public void setResultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-  }
-
-  public QueryDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    QueryDto queryDto = (QueryDto) o;
-    return Objects.equals(this.id, queryDto.id) &&
-        Objects.equals(this.cid, queryDto.cid) &&
-        Objects.equals(this.dbid, queryDto.dbid) &&
-        Objects.equals(this.creator, queryDto.creator) &&
-        Objects.equals(this.execution, queryDto.execution) &&
-        Objects.equals(this.query, queryDto.query) &&
-        Objects.equals(this.type, queryDto.type) &&
-        Objects.equals(this.created, queryDto.created) &&
-        Objects.equals(this.queryNormalized, queryDto.queryNormalized) &&
-        Objects.equals(this.queryHash, queryDto.queryHash) &&
-        Objects.equals(this.isPersisted, queryDto.isPersisted) &&
-        Objects.equals(this.resultHash, queryDto.resultHash) &&
-        Objects.equals(this.resultNumber, queryDto.resultNumber) &&
-        Objects.equals(this.lastModified, queryDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, cid, dbid, creator, execution, query, type, created, queryNormalized, queryHash, isPersisted, resultHash, resultNumber, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class QueryDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    cid: ").append(toIndentedString(cid)).append("\n");
-    sb.append("    dbid: ").append(toIndentedString(dbid)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    execution: ").append(toIndentedString(execution)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    queryNormalized: ").append(toIndentedString(queryNormalized)).append("\n");
-    sb.append("    queryHash: ").append(toIndentedString(queryHash)).append("\n");
-    sb.append("    isPersisted: ").append(toIndentedString(isPersisted)).append("\n");
-    sb.append("    resultHash: ").append(toIndentedString(resultHash)).append("\n");
-    sb.append("    resultNumber: ").append(toIndentedString(resultNumber)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/QueryResultDto.java b/.java-stubs/src/main/java/io/swagger/client/model/QueryResultDto.java
deleted file mode 100644
index f1f037c2f6bdd4b9adb2209e509e5414e5f32149..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/QueryResultDto.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-/**
- * QueryResultDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class QueryResultDto {
-  @SerializedName("result")
-  private List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
-
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("resultNumber")
-  private Long resultNumber = null;
-
-  public QueryResultDto result(List<Map<String, Object>> result) {
-    this.result = result;
-    return this;
-  }
-
-  public QueryResultDto addResultItem(Map<String, Object> resultItem) {
-    this.result.add(resultItem);
-    return this;
-  }
-
-   /**
-   * Get result
-   * @return result
-  **/
-  @Schema(required = true, description = "")
-  public List<Map<String, Object>> getResult() {
-    return result;
-  }
-
-  public void setResult(List<Map<String, Object>> result) {
-    this.result = result;
-  }
-
-  public QueryResultDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public QueryResultDto resultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-    return this;
-  }
-
-   /**
-   * Get resultNumber
-   * @return resultNumber
-  **/
-  @Schema(example = "1", description = "")
-  public Long getResultNumber() {
-    return resultNumber;
-  }
-
-  public void setResultNumber(Long resultNumber) {
-    this.resultNumber = resultNumber;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    QueryResultDto queryResultDto = (QueryResultDto) o;
-    return Objects.equals(this.result, queryResultDto.result) &&
-        Objects.equals(this.id, queryResultDto.id) &&
-        Objects.equals(this.resultNumber, queryResultDto.resultNumber);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(result, id, resultNumber);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class QueryResultDto {\n");
-    
-    sb.append("    result: ").append(toIndentedString(result)).append("\n");
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    resultNumber: ").append(toIndentedString(resultNumber)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/RelatedIdentifierDto.java b/.java-stubs/src/main/java/io/swagger/client/model/RelatedIdentifierDto.java
deleted file mode 100644
index 80a7699239def21abce8c596b599a63be5404fa1..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/RelatedIdentifierDto.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * RelatedIdentifierDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class RelatedIdentifierDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("value")
-  private String value = null;
-
-  /**
-   * Gets or Sets type
-   */
-  @JsonAdapter(TypeEnum.Adapter.class)
-  public enum TypeEnum {
-    DOI("DOI"),
-    URL("URL"),
-    URN("URN"),
-    ARK("ARK"),
-    ARXIV("arXiv"),
-    BIBCODE("bibcode"),
-    EAN13("EAN13"),
-    EISSN("EISSN"),
-    HANDLE("Handle"),
-    IGSN("IGSN"),
-    ISBN("ISBN"),
-    ISTC("ISTC"),
-    LISSN("LISSN"),
-    LSID("LSID"),
-    PMID("PMID"),
-    PURL("PURL"),
-    UPC("UPC"),
-    W3ID("w3id");
-
-    private String value;
-
-    TypeEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static TypeEnum fromValue(String input) {
-      for (TypeEnum b : TypeEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<TypeEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final TypeEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public TypeEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return TypeEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("type")
-  private TypeEnum type = null;
-
-  /**
-   * Gets or Sets relation
-   */
-  @JsonAdapter(RelationEnum.Adapter.class)
-  public enum RelationEnum {
-    ISCITEDBY("IsCitedBy"),
-    CITES("Cites"),
-    ISSUPPLEMENTTO("IsSupplementTo"),
-    ISSUPPLEMENTEDBY("IsSupplementedBy"),
-    ISCONTINUEDBY("IsContinuedBy"),
-    CONTINUES("Continues"),
-    ISDESCRIBEDBY("IsDescribedBy"),
-    DESCRIBES("Describes"),
-    HASMETADATA("HasMetadata"),
-    ISMETADATAFOR("IsMetadataFor"),
-    HASVERSION("HasVersion"),
-    ISVERSIONOF("IsVersionOf"),
-    ISNEWVERSIONOF("IsNewVersionOf"),
-    ISPREVIOUSVERSIONOF("IsPreviousVersionOf"),
-    ISPARTOF("IsPartOf"),
-    HASPART("HasPart"),
-    ISPUBLISHEDIN("IsPublishedIn"),
-    ISREFERENCEDBY("IsReferencedBy"),
-    REFERENCES("References"),
-    ISDOCUMENTEDBY("IsDocumentedBy"),
-    DOCUMENTS("Documents"),
-    ISCOMPILEDBY("IsCompiledBy"),
-    COMPILES("Compiles"),
-    ISVARIANTFORMOF("IsVariantFormOf"),
-    ISORIGINALFORMOF("IsOriginalFormOf"),
-    ISIDENTICALTO("IsIdenticalTo"),
-    ISREVIEWEDBY("IsReviewedBy"),
-    REVIEWS("Reviews"),
-    ISDERIVEDFROM("IsDerivedFrom"),
-    ISSOURCEOF("IsSourceOf"),
-    ISREQUIREDBY("IsRequiredBy"),
-    REQUIRES("Requires"),
-    ISOBSOLETEDBY("IsObsoletedBy"),
-    OBSOLETES("Obsoletes");
-
-    private String value;
-
-    RelationEnum(String value) {
-      this.value = value;
-    }
-    public String getValue() {
-      return value;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(value);
-    }
-    public static RelationEnum fromValue(String input) {
-      for (RelationEnum b : RelationEnum.values()) {
-        if (b.value.equals(input)) {
-          return b;
-        }
-      }
-      return null;
-    }
-    public static class Adapter extends TypeAdapter<RelationEnum> {
-      @Override
-      public void write(final JsonWriter jsonWriter, final RelationEnum enumeration) throws IOException {
-        jsonWriter.value(String.valueOf(enumeration.getValue()));
-      }
-
-      @Override
-      public RelationEnum read(final JsonReader jsonReader) throws IOException {
-        Object value = jsonReader.nextString();
-        return RelationEnum.fromValue((String)(value));
-      }
-    }
-  }  @SerializedName("relation")
-  private RelationEnum relation = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public RelatedIdentifierDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public RelatedIdentifierDto value(String value) {
-    this.value = value;
-    return this;
-  }
-
-   /**
-   * Get value
-   * @return value
-  **/
-  @Schema(example = "10.70124/dc4zh-9ce78", required = true, description = "")
-  public String getValue() {
-    return value;
-  }
-
-  public void setValue(String value) {
-    this.value = value;
-  }
-
-  public RelatedIdentifierDto type(TypeEnum type) {
-    this.type = type;
-    return this;
-  }
-
-   /**
-   * Get type
-   * @return type
-  **/
-  @Schema(example = "DOI", description = "")
-  public TypeEnum getType() {
-    return type;
-  }
-
-  public void setType(TypeEnum type) {
-    this.type = type;
-  }
-
-  public RelatedIdentifierDto relation(RelationEnum relation) {
-    this.relation = relation;
-    return this;
-  }
-
-   /**
-   * Get relation
-   * @return relation
-  **/
-  @Schema(example = "Cites", description = "")
-  public RelationEnum getRelation() {
-    return relation;
-  }
-
-  public void setRelation(RelationEnum relation) {
-    this.relation = relation;
-  }
-
-  public RelatedIdentifierDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public RelatedIdentifierDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    RelatedIdentifierDto relatedIdentifierDto = (RelatedIdentifierDto) o;
-    return Objects.equals(this.id, relatedIdentifierDto.id) &&
-        Objects.equals(this.value, relatedIdentifierDto.value) &&
-        Objects.equals(this.type, relatedIdentifierDto.type) &&
-        Objects.equals(this.relation, relatedIdentifierDto.relation) &&
-        Objects.equals(this.created, relatedIdentifierDto.created) &&
-        Objects.equals(this.lastModified, relatedIdentifierDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, value, type, relation, created, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class RelatedIdentifierDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    value: ").append(toIndentedString(value)).append("\n");
-    sb.append("    type: ").append(toIndentedString(type)).append("\n");
-    sb.append("    relation: ").append(toIndentedString(relation)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableBriefDto.java
deleted file mode 100644
index 58333a9470f0a410661d2cc779cf8e1b26b889d5..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableBriefDto.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.UserBriefDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * TableBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class TableBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("creator")
-  private UserBriefDto creator = null;
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  public TableBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public TableBriefDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public TableBriefDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Air Quality in Austria", required = true, description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public TableBriefDto creator(UserBriefDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserBriefDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserBriefDto creator) {
-    this.creator = creator;
-  }
-
-  public TableBriefDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air_quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableBriefDto tableBriefDto = (TableBriefDto) o;
-    return Objects.equals(this.id, tableBriefDto.id) &&
-        Objects.equals(this.name, tableBriefDto.name) &&
-        Objects.equals(this.description, tableBriefDto.description) &&
-        Objects.equals(this.creator, tableBriefDto.creator) &&
-        Objects.equals(this.internalName, tableBriefDto.internalName);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, name, description, creator, internalName);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableCreateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableCreateDto.java
deleted file mode 100644
index b8ecae936c41edab8cf96531b1e04e095f3c787c..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableCreateDto.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ColumnCreateDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * TableCreateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class TableCreateDto {
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("columns")
-  private List<ColumnCreateDto> columns = new ArrayList<ColumnCreateDto>();
-
-  public TableCreateDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public TableCreateDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Air Quality in Austria", required = true, description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public TableCreateDto columns(List<ColumnCreateDto> columns) {
-    this.columns = columns;
-    return this;
-  }
-
-  public TableCreateDto addColumnsItem(ColumnCreateDto columnsItem) {
-    this.columns.add(columnsItem);
-    return this;
-  }
-
-   /**
-   * Get columns
-   * @return columns
-  **/
-  @Schema(required = true, description = "")
-  public List<ColumnCreateDto> getColumns() {
-    return columns;
-  }
-
-  public void setColumns(List<ColumnCreateDto> columns) {
-    this.columns = columns;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableCreateDto tableCreateDto = (TableCreateDto) o;
-    return Objects.equals(this.name, tableCreateDto.name) &&
-        Objects.equals(this.description, tableCreateDto.description) &&
-        Objects.equals(this.columns, tableCreateDto.columns);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(name, description, columns);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableCreateDto {\n");
-    
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    columns: ").append(toIndentedString(columns)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDeleteDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDeleteDto.java
deleted file mode 100644
index 72da04d41b3ec817c92646f0b24b5f7fee1ba3f8..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDeleteDto.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-/**
- * TableCsvDeleteDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class TableCsvDeleteDto {
-  @SerializedName("keys")
-  private Map<String, Object> keys = new HashMap<String, Object>();
-
-  public TableCsvDeleteDto keys(Map<String, Object> keys) {
-    this.keys = keys;
-    return this;
-  }
-
-  public TableCsvDeleteDto putKeysItem(String key, Object keysItem) {
-    this.keys.put(key, keysItem);
-    return this;
-  }
-
-   /**
-   * Get keys
-   * @return keys
-  **/
-  @Schema(required = true, description = "")
-  public Map<String, Object> getKeys() {
-    return keys;
-  }
-
-  public void setKeys(Map<String, Object> keys) {
-    this.keys = keys;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableCsvDeleteDto tableCsvDeleteDto = (TableCsvDeleteDto) o;
-    return Objects.equals(this.keys, tableCsvDeleteDto.keys);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(keys);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableCsvDeleteDto {\n");
-    
-    sb.append("    keys: ").append(toIndentedString(keys)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDto.java
deleted file mode 100644
index 8051dbde21314605377a3b772598473582922fd2..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvDto.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-/**
- * TableCsvDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class TableCsvDto {
-  @SerializedName("data")
-  private Map<String, Object> data = new HashMap<String, Object>();
-
-  public TableCsvDto data(Map<String, Object> data) {
-    this.data = data;
-    return this;
-  }
-
-  public TableCsvDto putDataItem(String key, Object dataItem) {
-    this.data.put(key, dataItem);
-    return this;
-  }
-
-   /**
-   * Get data
-   * @return data
-  **/
-  @Schema(required = true, description = "")
-  public Map<String, Object> getData() {
-    return data;
-  }
-
-  public void setData(Map<String, Object> data) {
-    this.data = data;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableCsvDto tableCsvDto = (TableCsvDto) o;
-    return Objects.equals(this.data, tableCsvDto.data);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(data);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableCsvDto {\n");
-    
-    sb.append("    data: ").append(toIndentedString(data)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvUpdateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableCsvUpdateDto.java
deleted file mode 100644
index be6dd6782e85e29be7aca22de9c86804bfa31cf9..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableCsvUpdateDto.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-/**
- * TableCsvUpdateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class TableCsvUpdateDto {
-  @SerializedName("data")
-  private Map<String, Object> data = new HashMap<String, Object>();
-
-  @SerializedName("keys")
-  private Map<String, Object> keys = new HashMap<String, Object>();
-
-  public TableCsvUpdateDto data(Map<String, Object> data) {
-    this.data = data;
-    return this;
-  }
-
-  public TableCsvUpdateDto putDataItem(String key, Object dataItem) {
-    this.data.put(key, dataItem);
-    return this;
-  }
-
-   /**
-   * Get data
-   * @return data
-  **/
-  @Schema(required = true, description = "")
-  public Map<String, Object> getData() {
-    return data;
-  }
-
-  public void setData(Map<String, Object> data) {
-    this.data = data;
-  }
-
-  public TableCsvUpdateDto keys(Map<String, Object> keys) {
-    this.keys = keys;
-    return this;
-  }
-
-  public TableCsvUpdateDto putKeysItem(String key, Object keysItem) {
-    this.keys.put(key, keysItem);
-    return this;
-  }
-
-   /**
-   * Get keys
-   * @return keys
-  **/
-  @Schema(required = true, description = "")
-  public Map<String, Object> getKeys() {
-    return keys;
-  }
-
-  public void setKeys(Map<String, Object> keys) {
-    this.keys = keys;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableCsvUpdateDto tableCsvUpdateDto = (TableCsvUpdateDto) o;
-    return Objects.equals(this.data, tableCsvUpdateDto.data) &&
-        Objects.equals(this.keys, tableCsvUpdateDto.keys);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(data, keys);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableCsvUpdateDto {\n");
-    
-    sb.append("    data: ").append(toIndentedString(data)).append("\n");
-    sb.append("    keys: ").append(toIndentedString(keys)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableDto.java
deleted file mode 100644
index a27eac17cb10055675b958dd256f369217c60e9a..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableDto.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ColumnDto;
-import io.swagger.client.model.UserBriefDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.threeten.bp.OffsetDateTime;
-/**
- * TableDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class TableDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("creator")
-  private UserBriefDto creator = null;
-
-  @SerializedName("description")
-  private String description = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("columns")
-  private List<ColumnDto> columns = new ArrayList<ColumnDto>();
-
-  @SerializedName("internal_name")
-  private String internalName = null;
-
-  @SerializedName("queue_name")
-  private String queueName = null;
-
-  @SerializedName("routing_key")
-  private String routingKey = null;
-
-  public TableDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public TableDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public TableDto creator(UserBriefDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserBriefDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserBriefDto creator) {
-    this.creator = creator;
-  }
-
-  public TableDto description(String description) {
-    this.description = description;
-    return this;
-  }
-
-   /**
-   * Get description
-   * @return description
-  **/
-  @Schema(example = "Air Quality in Austria", required = true, description = "")
-  public String getDescription() {
-    return description;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public TableDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public TableDto columns(List<ColumnDto> columns) {
-    this.columns = columns;
-    return this;
-  }
-
-  public TableDto addColumnsItem(ColumnDto columnsItem) {
-    this.columns.add(columnsItem);
-    return this;
-  }
-
-   /**
-   * Get columns
-   * @return columns
-  **/
-  @Schema(required = true, description = "")
-  public List<ColumnDto> getColumns() {
-    return columns;
-  }
-
-  public void setColumns(List<ColumnDto> columns) {
-    this.columns = columns;
-  }
-
-  public TableDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air_quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public TableDto queueName(String queueName) {
-    this.queueName = queueName;
-    return this;
-  }
-
-   /**
-   * Get queueName
-   * @return queueName
-  **/
-  @Schema(example = "dbrepo/4/4/2", required = true, description = "")
-  public String getQueueName() {
-    return queueName;
-  }
-
-  public void setQueueName(String queueName) {
-    this.queueName = queueName;
-  }
-
-  public TableDto routingKey(String routingKey) {
-    this.routingKey = routingKey;
-    return this;
-  }
-
-   /**
-   * Get routingKey
-   * @return routingKey
-  **/
-  @Schema(example = "dbrepo/4/4/2/1", required = true, description = "")
-  public String getRoutingKey() {
-    return routingKey;
-  }
-
-  public void setRoutingKey(String routingKey) {
-    this.routingKey = routingKey;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableDto tableDto = (TableDto) o;
-    return Objects.equals(this.id, tableDto.id) &&
-        Objects.equals(this.name, tableDto.name) &&
-        Objects.equals(this.creator, tableDto.creator) &&
-        Objects.equals(this.description, tableDto.description) &&
-        Objects.equals(this.created, tableDto.created) &&
-        Objects.equals(this.columns, tableDto.columns) &&
-        Objects.equals(this.internalName, tableDto.internalName) &&
-        Objects.equals(this.queueName, tableDto.queueName) &&
-        Objects.equals(this.routingKey, tableDto.routingKey);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, name, creator, description, created, columns, internalName, queueName, routingKey);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    description: ").append(toIndentedString(description)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    columns: ").append(toIndentedString(columns)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    queueName: ").append(toIndentedString(queueName)).append("\n");
-    sb.append("    routingKey: ").append(toIndentedString(routingKey)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/TableHistoryDto.java b/.java-stubs/src/main/java/io/swagger/client/model/TableHistoryDto.java
deleted file mode 100644
index c5925de33416b663dc4c73a7766ea7bbe7d43cca..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/TableHistoryDto.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * TableHistoryDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class TableHistoryDto {
-  @SerializedName("timestamp")
-  private OffsetDateTime timestamp = null;
-
-  @SerializedName("event")
-  private String event = null;
-
-  @SerializedName("total")
-  private Long total = null;
-
-  public TableHistoryDto timestamp(OffsetDateTime timestamp) {
-    this.timestamp = timestamp;
-    return this;
-  }
-
-   /**
-   * Get timestamp
-   * @return timestamp
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getTimestamp() {
-    return timestamp;
-  }
-
-  public void setTimestamp(OffsetDateTime timestamp) {
-    this.timestamp = timestamp;
-  }
-
-  public TableHistoryDto event(String event) {
-    this.event = event;
-    return this;
-  }
-
-   /**
-   * Get event
-   * @return event
-  **/
-  @Schema(required = true, description = "")
-  public String getEvent() {
-    return event;
-  }
-
-  public void setEvent(String event) {
-    this.event = event;
-  }
-
-  public TableHistoryDto total(Long total) {
-    this.total = total;
-    return this;
-  }
-
-   /**
-   * Get total
-   * @return total
-  **/
-  @Schema(example = "1", required = true, description = "")
-  public Long getTotal() {
-    return total;
-  }
-
-  public void setTotal(Long total) {
-    this.total = total;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    TableHistoryDto tableHistoryDto = (TableHistoryDto) o;
-    return Objects.equals(this.timestamp, tableHistoryDto.timestamp) &&
-        Objects.equals(this.event, tableHistoryDto.event) &&
-        Objects.equals(this.total, tableHistoryDto.total);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(timestamp, event, total);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class TableHistoryDto {\n");
-    
-    sb.append("    timestamp: ").append(toIndentedString(timestamp)).append("\n");
-    sb.append("    event: ").append(toIndentedString(event)).append("\n");
-    sb.append("    total: ").append(toIndentedString(total)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/UnitDto.java b/.java-stubs/src/main/java/io/swagger/client/model/UnitDto.java
deleted file mode 100644
index da25cd960a9e1f4d75e8e987d7f7f11fc1954228..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/UnitDto.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Database Repository Table Service API
- * Service that manages the tables
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * UnitDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:29:06.419178+01:00[Europe/Vienna]")
-public class UnitDto {
-  @SerializedName("uri")
-  private String uri = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  public UnitDto uri(String uri) {
-    this.uri = uri;
-    return this;
-  }
-
-   /**
-   * Get uri
-   * @return uri
-  **/
-  @Schema(required = true, description = "")
-  public String getUri() {
-    return uri;
-  }
-
-  public void setUri(String uri) {
-    this.uri = uri;
-  }
-
-  public UnitDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public UnitDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    UnitDto unitDto = (UnitDto) o;
-    return Objects.equals(this.uri, unitDto.uri) &&
-        Objects.equals(this.name, unitDto.name) &&
-        Objects.equals(this.created, unitDto.created);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(uri, name, created);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class UnitDto {\n");
-    
-    sb.append("    uri: ").append(toIndentedString(uri)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/UserBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/UserBriefDto.java
deleted file mode 100644
index d0b5924a233bdf2db900d84617adb1e126807683..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/UserBriefDto.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * UserBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class UserBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("username")
-  private String username = null;
-
-  @SerializedName("titlesBefore")
-  private String titlesBefore = null;
-
-  @SerializedName("titlesAfter")
-  private String titlesAfter = null;
-
-  @SerializedName("firstname")
-  private String firstname = null;
-
-  @SerializedName("lastname")
-  private String lastname = null;
-
-  @SerializedName("affiliation")
-  private String affiliation = null;
-
-  @SerializedName("orcid")
-  private String orcid = null;
-
-  @SerializedName("roles")
-  private List<String> roles = new ArrayList<String>();
-
-  @SerializedName("themeDark")
-  private Boolean themeDark = null;
-
-  @SerializedName("emailVerified")
-  private Boolean emailVerified = null;
-
-  public UserBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public UserBriefDto username(String username) {
-    this.username = username;
-    return this;
-  }
-
-   /**
-   * Only contains lowercase characters
-   * @return username
-  **/
-  @Schema(example = "user", required = true, description = "Only contains lowercase characters")
-  public String getUsername() {
-    return username;
-  }
-
-  public void setUsername(String username) {
-    this.username = username;
-  }
-
-  public UserBriefDto titlesBefore(String titlesBefore) {
-    this.titlesBefore = titlesBefore;
-    return this;
-  }
-
-   /**
-   * Get titlesBefore
-   * @return titlesBefore
-  **/
-  @Schema(description = "")
-  public String getTitlesBefore() {
-    return titlesBefore;
-  }
-
-  public void setTitlesBefore(String titlesBefore) {
-    this.titlesBefore = titlesBefore;
-  }
-
-  public UserBriefDto titlesAfter(String titlesAfter) {
-    this.titlesAfter = titlesAfter;
-    return this;
-  }
-
-   /**
-   * Get titlesAfter
-   * @return titlesAfter
-  **/
-  @Schema(description = "")
-  public String getTitlesAfter() {
-    return titlesAfter;
-  }
-
-  public void setTitlesAfter(String titlesAfter) {
-    this.titlesAfter = titlesAfter;
-  }
-
-  public UserBriefDto firstname(String firstname) {
-    this.firstname = firstname;
-    return this;
-  }
-
-   /**
-   * Get firstname
-   * @return firstname
-  **/
-  @Schema(example = "Josiah", description = "")
-  public String getFirstname() {
-    return firstname;
-  }
-
-  public void setFirstname(String firstname) {
-    this.firstname = firstname;
-  }
-
-  public UserBriefDto lastname(String lastname) {
-    this.lastname = lastname;
-    return this;
-  }
-
-   /**
-   * Get lastname
-   * @return lastname
-  **/
-  @Schema(example = "Carberry", description = "")
-  public String getLastname() {
-    return lastname;
-  }
-
-  public void setLastname(String lastname) {
-    this.lastname = lastname;
-  }
-
-  public UserBriefDto affiliation(String affiliation) {
-    this.affiliation = affiliation;
-    return this;
-  }
-
-   /**
-   * Get affiliation
-   * @return affiliation
-  **/
-  @Schema(example = "Brown University", description = "")
-  public String getAffiliation() {
-    return affiliation;
-  }
-
-  public void setAffiliation(String affiliation) {
-    this.affiliation = affiliation;
-  }
-
-  public UserBriefDto orcid(String orcid) {
-    this.orcid = orcid;
-    return this;
-  }
-
-   /**
-   * Get orcid
-   * @return orcid
-  **/
-  @Schema(example = "0000-0002-1825-0097", description = "")
-  public String getOrcid() {
-    return orcid;
-  }
-
-  public void setOrcid(String orcid) {
-    this.orcid = orcid;
-  }
-
-  public UserBriefDto roles(List<String> roles) {
-    this.roles = roles;
-    return this;
-  }
-
-  public UserBriefDto addRolesItem(String rolesItem) {
-    this.roles.add(rolesItem);
-    return this;
-  }
-
-   /**
-   * Roles of the user
-   * @return roles
-  **/
-  @Schema(example = "[ROLE_RESEARCHER]", required = true, description = "Roles of the user")
-  public List<String> getRoles() {
-    return roles;
-  }
-
-  public void setRoles(List<String> roles) {
-    this.roles = roles;
-  }
-
-  public UserBriefDto themeDark(Boolean themeDark) {
-    this.themeDark = themeDark;
-    return this;
-  }
-
-   /**
-   * Get themeDark
-   * @return themeDark
-  **/
-  @Schema(description = "")
-  public Boolean isThemeDark() {
-    return themeDark;
-  }
-
-  public void setThemeDark(Boolean themeDark) {
-    this.themeDark = themeDark;
-  }
-
-  public UserBriefDto emailVerified(Boolean emailVerified) {
-    this.emailVerified = emailVerified;
-    return this;
-  }
-
-   /**
-   * Get emailVerified
-   * @return emailVerified
-  **/
-  @Schema(description = "")
-  public Boolean isEmailVerified() {
-    return emailVerified;
-  }
-
-  public void setEmailVerified(Boolean emailVerified) {
-    this.emailVerified = emailVerified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    UserBriefDto userBriefDto = (UserBriefDto) o;
-    return Objects.equals(this.id, userBriefDto.id) &&
-        Objects.equals(this.username, userBriefDto.username) &&
-        Objects.equals(this.titlesBefore, userBriefDto.titlesBefore) &&
-        Objects.equals(this.titlesAfter, userBriefDto.titlesAfter) &&
-        Objects.equals(this.firstname, userBriefDto.firstname) &&
-        Objects.equals(this.lastname, userBriefDto.lastname) &&
-        Objects.equals(this.affiliation, userBriefDto.affiliation) &&
-        Objects.equals(this.orcid, userBriefDto.orcid) &&
-        Objects.equals(this.roles, userBriefDto.roles) &&
-        Objects.equals(this.themeDark, userBriefDto.themeDark) &&
-        Objects.equals(this.emailVerified, userBriefDto.emailVerified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, username, titlesBefore, titlesAfter, firstname, lastname, affiliation, orcid, roles, themeDark, emailVerified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class UserBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    username: ").append(toIndentedString(username)).append("\n");
-    sb.append("    titlesBefore: ").append(toIndentedString(titlesBefore)).append("\n");
-    sb.append("    titlesAfter: ").append(toIndentedString(titlesAfter)).append("\n");
-    sb.append("    firstname: ").append(toIndentedString(firstname)).append("\n");
-    sb.append("    lastname: ").append(toIndentedString(lastname)).append("\n");
-    sb.append("    affiliation: ").append(toIndentedString(affiliation)).append("\n");
-    sb.append("    orcid: ").append(toIndentedString(orcid)).append("\n");
-    sb.append("    roles: ").append(toIndentedString(roles)).append("\n");
-    sb.append("    themeDark: ").append(toIndentedString(themeDark)).append("\n");
-    sb.append("    emailVerified: ").append(toIndentedString(emailVerified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/UserDto.java b/.java-stubs/src/main/java/io/swagger/client/model/UserDto.java
deleted file mode 100644
index ccddfc131bf7e1bb5105d9b73df38c76fe9971c1..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/UserDto.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Database Repository Container Service API
- * Service that manages the containers
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.ContainerDto;
-import io.swagger.client.model.GrantedAuthorityDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * UserDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T11:48:18.502846+01:00[Europe/Vienna]")
-public class UserDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("authorities")
-  private List<GrantedAuthorityDto> authorities = null;
-
-  @SerializedName("username")
-  private String username = null;
-
-  @SerializedName("firstname")
-  private String firstname = null;
-
-  @SerializedName("lastname")
-  private String lastname = null;
-
-  @SerializedName("affiliation")
-  private String affiliation = null;
-
-  @SerializedName("orcid")
-  private String orcid = null;
-
-  @SerializedName("roles")
-  private List<String> roles = new ArrayList<String>();
-
-  @SerializedName("containers")
-  private List<ContainerDto> containers = null;
-
-  @SerializedName("databases")
-  private List<ContainerDto> databases = null;
-
-  @SerializedName("identifiers")
-  private List<ContainerDto> identifiers = null;
-
-  @SerializedName("email")
-  private String email = null;
-
-  @SerializedName("titles_before")
-  private String titlesBefore = null;
-
-  @SerializedName("titles_after")
-  private String titlesAfter = null;
-
-  @SerializedName("theme_dark")
-  private Boolean themeDark = null;
-
-  @SerializedName("email_verified")
-  private Boolean emailVerified = null;
-
-  public UserDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public UserDto authorities(List<GrantedAuthorityDto> authorities) {
-    this.authorities = authorities;
-    return this;
-  }
-
-  public UserDto addAuthoritiesItem(GrantedAuthorityDto authoritiesItem) {
-    if (this.authorities == null) {
-      this.authorities = new ArrayList<GrantedAuthorityDto>();
-    }
-    this.authorities.add(authoritiesItem);
-    return this;
-  }
-
-   /**
-   * Get authorities
-   * @return authorities
-  **/
-  @Schema(description = "")
-  public List<GrantedAuthorityDto> getAuthorities() {
-    return authorities;
-  }
-
-  public void setAuthorities(List<GrantedAuthorityDto> authorities) {
-    this.authorities = authorities;
-  }
-
-  public UserDto username(String username) {
-    this.username = username;
-    return this;
-  }
-
-   /**
-   * Only contains lowercase characters
-   * @return username
-  **/
-  @Schema(example = "jcarberry", required = true, description = "Only contains lowercase characters")
-  public String getUsername() {
-    return username;
-  }
-
-  public void setUsername(String username) {
-    this.username = username;
-  }
-
-  public UserDto firstname(String firstname) {
-    this.firstname = firstname;
-    return this;
-  }
-
-   /**
-   * Get firstname
-   * @return firstname
-  **/
-  @Schema(example = "Josiah", description = "")
-  public String getFirstname() {
-    return firstname;
-  }
-
-  public void setFirstname(String firstname) {
-    this.firstname = firstname;
-  }
-
-  public UserDto lastname(String lastname) {
-    this.lastname = lastname;
-    return this;
-  }
-
-   /**
-   * Get lastname
-   * @return lastname
-  **/
-  @Schema(example = "Carberry", description = "")
-  public String getLastname() {
-    return lastname;
-  }
-
-  public void setLastname(String lastname) {
-    this.lastname = lastname;
-  }
-
-  public UserDto affiliation(String affiliation) {
-    this.affiliation = affiliation;
-    return this;
-  }
-
-   /**
-   * Get affiliation
-   * @return affiliation
-  **/
-  @Schema(example = "Brown University", description = "")
-  public String getAffiliation() {
-    return affiliation;
-  }
-
-  public void setAffiliation(String affiliation) {
-    this.affiliation = affiliation;
-  }
-
-  public UserDto orcid(String orcid) {
-    this.orcid = orcid;
-    return this;
-  }
-
-   /**
-   * Get orcid
-   * @return orcid
-  **/
-  @Schema(example = "0000-0002-1825-0097", description = "")
-  public String getOrcid() {
-    return orcid;
-  }
-
-  public void setOrcid(String orcid) {
-    this.orcid = orcid;
-  }
-
-  public UserDto roles(List<String> roles) {
-    this.roles = roles;
-    return this;
-  }
-
-  public UserDto addRolesItem(String rolesItem) {
-    this.roles.add(rolesItem);
-    return this;
-  }
-
-   /**
-   * Roles of the user
-   * @return roles
-  **/
-  @Schema(example = "[ROLE_RESEARCHER]", required = true, description = "Roles of the user")
-  public List<String> getRoles() {
-    return roles;
-  }
-
-  public void setRoles(List<String> roles) {
-    this.roles = roles;
-  }
-
-  public UserDto containers(List<ContainerDto> containers) {
-    this.containers = containers;
-    return this;
-  }
-
-  public UserDto addContainersItem(ContainerDto containersItem) {
-    if (this.containers == null) {
-      this.containers = new ArrayList<ContainerDto>();
-    }
-    this.containers.add(containersItem);
-    return this;
-  }
-
-   /**
-   * Get containers
-   * @return containers
-  **/
-  @Schema(description = "")
-  public List<ContainerDto> getContainers() {
-    return containers;
-  }
-
-  public void setContainers(List<ContainerDto> containers) {
-    this.containers = containers;
-  }
-
-  public UserDto databases(List<ContainerDto> databases) {
-    this.databases = databases;
-    return this;
-  }
-
-  public UserDto addDatabasesItem(ContainerDto databasesItem) {
-    if (this.databases == null) {
-      this.databases = new ArrayList<ContainerDto>();
-    }
-    this.databases.add(databasesItem);
-    return this;
-  }
-
-   /**
-   * Get databases
-   * @return databases
-  **/
-  @Schema(description = "")
-  public List<ContainerDto> getDatabases() {
-    return databases;
-  }
-
-  public void setDatabases(List<ContainerDto> databases) {
-    this.databases = databases;
-  }
-
-  public UserDto identifiers(List<ContainerDto> identifiers) {
-    this.identifiers = identifiers;
-    return this;
-  }
-
-  public UserDto addIdentifiersItem(ContainerDto identifiersItem) {
-    if (this.identifiers == null) {
-      this.identifiers = new ArrayList<ContainerDto>();
-    }
-    this.identifiers.add(identifiersItem);
-    return this;
-  }
-
-   /**
-   * Get identifiers
-   * @return identifiers
-  **/
-  @Schema(description = "")
-  public List<ContainerDto> getIdentifiers() {
-    return identifiers;
-  }
-
-  public void setIdentifiers(List<ContainerDto> identifiers) {
-    this.identifiers = identifiers;
-  }
-
-  public UserDto email(String email) {
-    this.email = email;
-    return this;
-  }
-
-   /**
-   * Get email
-   * @return email
-  **/
-  @Schema(example = "jcarberry@brown.edu", required = true, description = "")
-  public String getEmail() {
-    return email;
-  }
-
-  public void setEmail(String email) {
-    this.email = email;
-  }
-
-  public UserDto titlesBefore(String titlesBefore) {
-    this.titlesBefore = titlesBefore;
-    return this;
-  }
-
-   /**
-   * Get titlesBefore
-   * @return titlesBefore
-  **/
-  @Schema(example = "Prof.", description = "")
-  public String getTitlesBefore() {
-    return titlesBefore;
-  }
-
-  public void setTitlesBefore(String titlesBefore) {
-    this.titlesBefore = titlesBefore;
-  }
-
-  public UserDto titlesAfter(String titlesAfter) {
-    this.titlesAfter = titlesAfter;
-    return this;
-  }
-
-   /**
-   * Get titlesAfter
-   * @return titlesAfter
-  **/
-  @Schema(description = "")
-  public String getTitlesAfter() {
-    return titlesAfter;
-  }
-
-  public void setTitlesAfter(String titlesAfter) {
-    this.titlesAfter = titlesAfter;
-  }
-
-  public UserDto themeDark(Boolean themeDark) {
-    this.themeDark = themeDark;
-    return this;
-  }
-
-   /**
-   * Get themeDark
-   * @return themeDark
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isThemeDark() {
-    return themeDark;
-  }
-
-  public void setThemeDark(Boolean themeDark) {
-    this.themeDark = themeDark;
-  }
-
-  public UserDto emailVerified(Boolean emailVerified) {
-    this.emailVerified = emailVerified;
-    return this;
-  }
-
-   /**
-   * Get emailVerified
-   * @return emailVerified
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isEmailVerified() {
-    return emailVerified;
-  }
-
-  public void setEmailVerified(Boolean emailVerified) {
-    this.emailVerified = emailVerified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    UserDto userDto = (UserDto) o;
-    return Objects.equals(this.id, userDto.id) &&
-        Objects.equals(this.authorities, userDto.authorities) &&
-        Objects.equals(this.username, userDto.username) &&
-        Objects.equals(this.firstname, userDto.firstname) &&
-        Objects.equals(this.lastname, userDto.lastname) &&
-        Objects.equals(this.affiliation, userDto.affiliation) &&
-        Objects.equals(this.orcid, userDto.orcid) &&
-        Objects.equals(this.roles, userDto.roles) &&
-        Objects.equals(this.containers, userDto.containers) &&
-        Objects.equals(this.databases, userDto.databases) &&
-        Objects.equals(this.identifiers, userDto.identifiers) &&
-        Objects.equals(this.email, userDto.email) &&
-        Objects.equals(this.titlesBefore, userDto.titlesBefore) &&
-        Objects.equals(this.titlesAfter, userDto.titlesAfter) &&
-        Objects.equals(this.themeDark, userDto.themeDark) &&
-        Objects.equals(this.emailVerified, userDto.emailVerified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, authorities, username, firstname, lastname, affiliation, orcid, roles, containers, databases, identifiers, email, titlesBefore, titlesAfter, themeDark, emailVerified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class UserDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    authorities: ").append(toIndentedString(authorities)).append("\n");
-    sb.append("    username: ").append(toIndentedString(username)).append("\n");
-    sb.append("    firstname: ").append(toIndentedString(firstname)).append("\n");
-    sb.append("    lastname: ").append(toIndentedString(lastname)).append("\n");
-    sb.append("    affiliation: ").append(toIndentedString(affiliation)).append("\n");
-    sb.append("    orcid: ").append(toIndentedString(orcid)).append("\n");
-    sb.append("    roles: ").append(toIndentedString(roles)).append("\n");
-    sb.append("    containers: ").append(toIndentedString(containers)).append("\n");
-    sb.append("    databases: ").append(toIndentedString(databases)).append("\n");
-    sb.append("    identifiers: ").append(toIndentedString(identifiers)).append("\n");
-    sb.append("    email: ").append(toIndentedString(email)).append("\n");
-    sb.append("    titlesBefore: ").append(toIndentedString(titlesBefore)).append("\n");
-    sb.append("    titlesAfter: ").append(toIndentedString(titlesAfter)).append("\n");
-    sb.append("    themeDark: ").append(toIndentedString(themeDark)).append("\n");
-    sb.append("    emailVerified: ").append(toIndentedString(emailVerified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ViewBriefDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ViewBriefDto.java
deleted file mode 100644
index 40840c85979fa86acdf142b590ff47a6237a508e..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ViewBriefDto.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ViewBriefDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class ViewBriefDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("vdbid")
-  private Long vdbid = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("internalName")
-  private String internalName = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  @SerializedName("initial_view")
-  private Boolean initialView = null;
-
-  @SerializedName("created_by")
-  private Long createdBy = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public ViewBriefDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ViewBriefDto vdbid(Long vdbid) {
-    this.vdbid = vdbid;
-    return this;
-  }
-
-   /**
-   * Get vdbid
-   * @return vdbid
-  **/
-  @Schema(required = true, description = "")
-  public Long getVdbid() {
-    return vdbid;
-  }
-
-  public void setVdbid(Long vdbid) {
-    this.vdbid = vdbid;
-  }
-
-  public ViewBriefDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ViewBriefDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air_quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public ViewBriefDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality` ORDER BY `value` DESC", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public ViewBriefDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public ViewBriefDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-  public ViewBriefDto initialView(Boolean initialView) {
-    this.initialView = initialView;
-    return this;
-  }
-
-   /**
-   * True if it is the default view for the database
-   * @return initialView
-  **/
-  @Schema(example = "true", description = "True if it is the default view for the database")
-  public Boolean isInitialView() {
-    return initialView;
-  }
-
-  public void setInitialView(Boolean initialView) {
-    this.initialView = initialView;
-  }
-
-  public ViewBriefDto createdBy(Long createdBy) {
-    this.createdBy = createdBy;
-    return this;
-  }
-
-   /**
-   * Get createdBy
-   * @return createdBy
-  **/
-  @Schema(required = true, description = "")
-  public Long getCreatedBy() {
-    return createdBy;
-  }
-
-  public void setCreatedBy(Long createdBy) {
-    this.createdBy = createdBy;
-  }
-
-  public ViewBriefDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ViewBriefDto viewBriefDto = (ViewBriefDto) o;
-    return Objects.equals(this.id, viewBriefDto.id) &&
-        Objects.equals(this.vdbid, viewBriefDto.vdbid) &&
-        Objects.equals(this.name, viewBriefDto.name) &&
-        Objects.equals(this.internalName, viewBriefDto.internalName) &&
-        Objects.equals(this.query, viewBriefDto.query) &&
-        Objects.equals(this.created, viewBriefDto.created) &&
-        Objects.equals(this.isPublic, viewBriefDto.isPublic) &&
-        Objects.equals(this.initialView, viewBriefDto.initialView) &&
-        Objects.equals(this.createdBy, viewBriefDto.createdBy) &&
-        Objects.equals(this.lastModified, viewBriefDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, vdbid, name, internalName, query, created, isPublic, initialView, createdBy, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ViewBriefDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    vdbid: ").append(toIndentedString(vdbid)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("    initialView: ").append(toIndentedString(initialView)).append("\n");
-    sb.append("    createdBy: ").append(toIndentedString(createdBy)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ViewCreateDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ViewCreateDto.java
deleted file mode 100644
index 0f4c66a5d10680f68b467b6d6457f720cd63677b..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ViewCreateDto.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-/**
- * ViewCreateDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class ViewCreateDto {
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  public ViewCreateDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ViewCreateDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality`", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public ViewCreateDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", required = true, description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ViewCreateDto viewCreateDto = (ViewCreateDto) o;
-    return Objects.equals(this.name, viewCreateDto.name) &&
-        Objects.equals(this.query, viewCreateDto.query) &&
-        Objects.equals(this.isPublic, viewCreateDto.isPublic);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(name, query, isPublic);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ViewCreateDto {\n");
-    
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.java-stubs/src/main/java/io/swagger/client/model/ViewDto.java b/.java-stubs/src/main/java/io/swagger/client/model/ViewDto.java
deleted file mode 100644
index 436e36e86f50019796f20f20d1130262463dd129..0000000000000000000000000000000000000000
--- a/.java-stubs/src/main/java/io/swagger/client/model/ViewDto.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Database Repository Query Service API
- * Service that manages the queries
- *
- * OpenAPI spec version: 1.1.0-alpha
- * Contact: andreas.rauber@tuwien.ac.at
- *
- * NOTE: This class is auto generated by the swagger code generator program.
- * https://github.com/swagger-api/swagger-codegen.git
- * Do not edit the class manually.
- */
-
-package io.swagger.client.model;
-
-import java.util.Objects;
-import java.util.Arrays;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import io.swagger.client.model.DatabaseDto;
-import io.swagger.client.model.UserDto;
-import io.swagger.v3.oas.annotations.media.Schema;
-import java.io.IOException;
-import org.threeten.bp.OffsetDateTime;
-/**
- * ViewDto
- */
-
-@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2023-02-12T12:27:08.557443+01:00[Europe/Vienna]")
-public class ViewDto {
-  @SerializedName("id")
-  private Long id = null;
-
-  @SerializedName("vdbid")
-  private Long vdbid = null;
-
-  @SerializedName("creator")
-  private UserDto creator = null;
-
-  @SerializedName("database")
-  private DatabaseDto database = null;
-
-  @SerializedName("name")
-  private String name = null;
-
-  @SerializedName("internalName")
-  private String internalName = null;
-
-  @SerializedName("query")
-  private String query = null;
-
-  @SerializedName("created")
-  private OffsetDateTime created = null;
-
-  @SerializedName("is_public")
-  private Boolean isPublic = null;
-
-  @SerializedName("initial_view")
-  private Boolean initialView = null;
-
-  @SerializedName("last_modified")
-  private OffsetDateTime lastModified = null;
-
-  public ViewDto id(Long id) {
-    this.id = id;
-    return this;
-  }
-
-   /**
-   * Get id
-   * @return id
-  **/
-  @Schema(required = true, description = "")
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public ViewDto vdbid(Long vdbid) {
-    this.vdbid = vdbid;
-    return this;
-  }
-
-   /**
-   * Get vdbid
-   * @return vdbid
-  **/
-  @Schema(required = true, description = "")
-  public Long getVdbid() {
-    return vdbid;
-  }
-
-  public void setVdbid(Long vdbid) {
-    this.vdbid = vdbid;
-  }
-
-  public ViewDto creator(UserDto creator) {
-    this.creator = creator;
-    return this;
-  }
-
-   /**
-   * Get creator
-   * @return creator
-  **/
-  @Schema(required = true, description = "")
-  public UserDto getCreator() {
-    return creator;
-  }
-
-  public void setCreator(UserDto creator) {
-    this.creator = creator;
-  }
-
-  public ViewDto database(DatabaseDto database) {
-    this.database = database;
-    return this;
-  }
-
-   /**
-   * Get database
-   * @return database
-  **/
-  @Schema(required = true, description = "")
-  public DatabaseDto getDatabase() {
-    return database;
-  }
-
-  public void setDatabase(DatabaseDto database) {
-    this.database = database;
-  }
-
-  public ViewDto name(String name) {
-    this.name = name;
-    return this;
-  }
-
-   /**
-   * Get name
-   * @return name
-  **/
-  @Schema(example = "Air Quality", required = true, description = "")
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public ViewDto internalName(String internalName) {
-    this.internalName = internalName;
-    return this;
-  }
-
-   /**
-   * Get internalName
-   * @return internalName
-  **/
-  @Schema(example = "air_quality", required = true, description = "")
-  public String getInternalName() {
-    return internalName;
-  }
-
-  public void setInternalName(String internalName) {
-    this.internalName = internalName;
-  }
-
-  public ViewDto query(String query) {
-    this.query = query;
-    return this;
-  }
-
-   /**
-   * Get query
-   * @return query
-  **/
-  @Schema(example = "SELECT `id` FROM `air_quality` ORDER BY `value` DESC", required = true, description = "")
-  public String getQuery() {
-    return query;
-  }
-
-  public void setQuery(String query) {
-    this.query = query;
-  }
-
-  public ViewDto created(OffsetDateTime created) {
-    this.created = created;
-    return this;
-  }
-
-   /**
-   * Get created
-   * @return created
-  **/
-  @Schema(required = true, description = "")
-  public OffsetDateTime getCreated() {
-    return created;
-  }
-
-  public void setCreated(OffsetDateTime created) {
-    this.created = created;
-  }
-
-  public ViewDto isPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-    return this;
-  }
-
-   /**
-   * Get isPublic
-   * @return isPublic
-  **/
-  @Schema(example = "true", description = "")
-  public Boolean isIsPublic() {
-    return isPublic;
-  }
-
-  public void setIsPublic(Boolean isPublic) {
-    this.isPublic = isPublic;
-  }
-
-  public ViewDto initialView(Boolean initialView) {
-    this.initialView = initialView;
-    return this;
-  }
-
-   /**
-   * True if it is the default view for the database
-   * @return initialView
-  **/
-  @Schema(example = "true", description = "True if it is the default view for the database")
-  public Boolean isInitialView() {
-    return initialView;
-  }
-
-  public void setInitialView(Boolean initialView) {
-    this.initialView = initialView;
-  }
-
-  public ViewDto lastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-    return this;
-  }
-
-   /**
-   * Get lastModified
-   * @return lastModified
-  **/
-  @Schema(description = "")
-  public OffsetDateTime getLastModified() {
-    return lastModified;
-  }
-
-  public void setLastModified(OffsetDateTime lastModified) {
-    this.lastModified = lastModified;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    ViewDto viewDto = (ViewDto) o;
-    return Objects.equals(this.id, viewDto.id) &&
-        Objects.equals(this.vdbid, viewDto.vdbid) &&
-        Objects.equals(this.creator, viewDto.creator) &&
-        Objects.equals(this.database, viewDto.database) &&
-        Objects.equals(this.name, viewDto.name) &&
-        Objects.equals(this.internalName, viewDto.internalName) &&
-        Objects.equals(this.query, viewDto.query) &&
-        Objects.equals(this.created, viewDto.created) &&
-        Objects.equals(this.isPublic, viewDto.isPublic) &&
-        Objects.equals(this.initialView, viewDto.initialView) &&
-        Objects.equals(this.lastModified, viewDto.lastModified);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id, vdbid, creator, database, name, internalName, query, created, isPublic, initialView, lastModified);
-  }
-
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("class ViewDto {\n");
-    
-    sb.append("    id: ").append(toIndentedString(id)).append("\n");
-    sb.append("    vdbid: ").append(toIndentedString(vdbid)).append("\n");
-    sb.append("    creator: ").append(toIndentedString(creator)).append("\n");
-    sb.append("    database: ").append(toIndentedString(database)).append("\n");
-    sb.append("    name: ").append(toIndentedString(name)).append("\n");
-    sb.append("    internalName: ").append(toIndentedString(internalName)).append("\n");
-    sb.append("    query: ").append(toIndentedString(query)).append("\n");
-    sb.append("    created: ").append(toIndentedString(created)).append("\n");
-    sb.append("    isPublic: ").append(toIndentedString(isPublic)).append("\n");
-    sb.append("    initialView: ").append(toIndentedString(initialView)).append("\n");
-    sb.append("    lastModified: ").append(toIndentedString(lastModified)).append("\n");
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /**
-   * Convert the given object to string with each line indented by 4 spaces
-   * (except the first line).
-   */
-  private String toIndentedString(Object o) {
-    if (o == null) {
-      return "null";
-    }
-    return o.toString().replace("\n", "\n    ");
-  }
-
-}
diff --git a/.python-stubs/.gitkeep b/.python-stubs/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/.python-stubs/auth_access.py b/.python-stubs/auth_access.py
deleted file mode 100644
index 27db7c351eb559518505db9e2c5763ea4c5c1319..0000000000000000000000000000000000000000
--- a/.python-stubs/auth_access.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import requests
-
-auth = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", data={
-    "username": "foo",
-    "password": "bar",
-    "grant_type": "password",
-    "client_id": "dbrepo-client",
-    "scope": "openid",
-    "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG"
-})
-print(auth.json()["access_token"])
diff --git a/.python-stubs/auth_refresh.py b/.python-stubs/auth_refresh.py
deleted file mode 100644
index 8375ed4999061e7bf9acfdbcd4ef5dd8a727550f..0000000000000000000000000000000000000000
--- a/.python-stubs/auth_refresh.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import requests
-
-auth = requests.post("http://localhost/api/auth/realms/dbrepo/protocol/openid-connect/token", data={
-    "grant_type": "refresh_token",
-    "client_id": "dbrepo-client",
-    "client_secret": "MUwRc7yfXSJwX8AdRMWaQC3Nep1VjwgG",
-    "refresh_token": "THE_REFRESH_TOKEN"
-})
-print(auth.json()["access_token"])
diff --git a/.python-stubs/publish_oauth2.py b/.python-stubs/publish_oauth2.py
deleted file mode 100644
index e67920773544aa31039aff29ee8b34de6ce6e576..0000000000000000000000000000000000000000
--- a/.python-stubs/publish_oauth2.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import pika
-
-credentials = pika.credentials.PlainCredentials("", "THE_ACCESS_TOKEN")
-parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)
-connection = pika.BlockingConnection(parameters)
-channel = connection.channel()
-channel.queue_declare(queue='test', durable=True)
-channel.basic_publish(exchange='',
-                      routing_key='test',
-                      body=b'Hello World!')
-print(" [x] Sent 'Hello World!'")
-connection.close()
diff --git a/.python-stubs/publish_plain.py b/.python-stubs/publish_plain.py
deleted file mode 100644
index 71b7f3811b0c179d6645dbabdb05005fe08f1afc..0000000000000000000000000000000000000000
--- a/.python-stubs/publish_plain.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import pika
-
-credentials = pika.credentials.PlainCredentials("foo", "bar")
-parameters = pika.ConnectionParameters('localhost', 5672, '/', credentials)
-connection = pika.BlockingConnection(parameters)
-channel = connection.channel()
-channel.queue_declare(queue='test', durable=True)
-channel.basic_publish(exchange='',
-                      routing_key='test',
-                      body=b'Hello World!')
-print(" [x] Sent 'Hello World!'")
-connection.close()
diff --git a/.python-stubs/publish_tuple.py b/.python-stubs/publish_tuple.py
deleted file mode 100644
index f2c14262eae4ae6d6588f1f0bf72f2cd672ce869..0000000000000000000000000000000000000000
--- a/.python-stubs/publish_tuple.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/env python3
-from api_table.api.table_endpoint_api import TableEndpointApi
-from api_query.api.table_data_endpoint_api import TableDataEndpointApi
-import time
-import os
-import shutil
-import uuid
-
-table = TableEndpointApi()
-data = TableDataEndpointApi()
-
-def create_table(container_id, database_id, columns=None):
-    if columns is None:
-        columns = [
-            {"name": "UUID", "type": "string", "dfid": None, "unique": True, "primary_key": True, "null_allowed": False},
-            {"name": "Point", "type": "string", "dfid": None, "unique": False, "primary_key": False, "null_allowed": True},
-            {"name": "Value", "type": "decimal", "dfid": None, "unique": False, "primary_key": False, "null_allowed": True},
-            {"name": "Unit", "type": "string", "dfid": None, "unique": False, "primary_key": False, "null_allowed": True},
-            {"name": "Timestamp", "type": "timestamp", "dfid": 1, "unique": False, "primary_key": False, "null_allowed": True}
-        ]
-    response = table.create({
-        "name": "Power",
-        "description": "Power consumption in the Pilot Factory",
-        "columns": columns
-    }, "Bearer token", container_id, database_id)
-    print("created table with id %d" % response.id)
-    return response
-
-
-def fill_table(container_id, database_id, table_id):
-    response = data.import_csv({
-        "location": "/path/to/data.csv",
-        "quote": "\"",
-        "null_element": "NA",
-        "separator": ",",
-    }, container_id, database_id, table_id)
-    print("filled table with id %d" % table_id)
-    return response
-
diff --git a/.python-stubs/query_data.py b/.python-stubs/query_data.py
deleted file mode 100644
index ba74549075f0f48235453546a9b6ac841cb3bd0b..0000000000000000000000000000000000000000
--- a/.python-stubs/query_data.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/env python3
-from api_query.api.query_endpoint_api import QueryEndpointApi
-
-query = QueryEndpointApi()
-
-
-def create_query(container_id, database_id, statement, page=0, size=3):
-    response = query.execute({
-        "statement": statement
-    }, container_id, database_id, page=page, size=size)
-    print("executed query with id %d" % response.id)
-    return response
diff --git a/.python-stubs/requirements.txt b/.python-stubs/requirements.txt
deleted file mode 100644
index 4053c0f69310255281766257eb440fd937b9a453..0000000000000000000000000000000000000000
--- a/.python-stubs/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pika==1.3.1
-python-dotenv==1.0.0
-requests==2.28.2
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ed25b07c2bbba6ed0c21d9c5deb1514775dbddd..b139a2be883971afbbd6188e78877b2cf7274e06 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,43 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [[1.3]()] - 2023-06-01
+## [[1.4.0]()] - 2024-01-19
+
+### Added
+
+- Increased DOI system support: tables, views, subsets and databases. Also allowing multiple identifiers per object.
+- Extensive documentation directly in the repository with 
+  usage [examples](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.4.0/usage-overview/).
+- Identifier can now be crawled in the UI via JSON-LD (Google Datasets).
+- OpenAIRE Graph protocol for OAI-PMH.
+- Added a data service that inserts data from the Broker Service.
+- Added search service for searching the search-db.
+- Added storage service for S3-compatible file uploads and downloads.
+
+### Changed
+
+- Changed the model to one isolated database within a single database container (by default), additional containers
+  can still be created and registered.
+- Refactored the Hibernate mappings extensively, simplifying the save operations.
+- Using only one OpenSearch index `database` containing all metadata mirrored from the metadata database.
+- Broker service has only one exchange `dbrepo` (topic) and one queue `dbrepo` (quorum), the delivery of tuples is
+  managed via routing keys according to the hierarchy, e.g. `dbrepo.database_name_rand.table_name`.
+
+### Fixed
+
+- Runtime dependencies for creating the OpenSearch index.
+- Using Testcontainer fixtures where possible for integration tests.
+- Fixed the wildcard search with own search service that can do faceted browsing.
+
+### Removed
+
+- The container service, merged into metadata service.
+- The database service, merged into metadata service.
+- The identifier service, merged into metadata service.
+- The query service, merged into metadata service.
+- The table service, merged into metadata service.
+
+## [[1.3.0](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags/v1.3.0)] - 2023-06-01
 
 ### Added
 
diff --git a/Makefile b/Makefile
index 5fa0ce31d340b3a85eda0d869b555b9c575b292a..5f39f77cc78a3c4fd1c84119d3c474cf65adf61d 100644
--- a/Makefile
+++ b/Makefile
@@ -30,17 +30,16 @@ build-analyse-service:
 build-docker:
 	docker build --network=host -t dbrepo-metadata-service:build --target build dbrepo-metadata-service
 	docker build --network=host -t dbrepo-data-service:build --target build dbrepo-data-service
-	docker build --network=host ./dbrepo-log-service -t dbrepo-log-service
 	docker compose build --parallel
 
 build-frontend:
 	yarn --cwd ./dbrepo-ui install --legacy-peer-deps
 	yarn --cwd ./dbrepo-ui run build
 
-build-clients:
-	bash ./.gitlab/swagger/generate.sh
+build-swagger:
+	bash ./.docs/generate.sh
 
-tag: tag-analyse-service tag-authentication-service tag-metadata-db tag-ui tag-metadata-service tag-data-service tag-log-service tag-search-db tag-search-db-init tag-search-service tag-data-db-sidecar
+tag: tag-analyse-service tag-authentication-service tag-metadata-db tag-ui tag-metadata-service tag-data-service tag-search-db tag-search-db-init tag-search-service tag-data-db-sidecar
 
 tag-analyse-service:
 	docker tag dbrepo-analyse-service:latest "${REPOSITORY_1_URL}/analyse-service:${TAG}"
@@ -78,10 +77,6 @@ tag-search-db-init:
 	docker tag dbrepo-search-db-init:latest "${REPOSITORY_1_URL}/search-db-init:${TAG}"
 	docker tag dbrepo-search-db-init:latest "${REPOSITORY_2_URL}/search-db-init:${TAG}"
 
-tag-log-service:
-	docker tag dbrepo-log-service:latest "${REPOSITORY_1_URL}/log-service:${TAG}"
-	docker tag dbrepo-log-service:latest "${REPOSITORY_2_URL}/log-service:${TAG}"
-
 tag-search-service:
 	docker tag dbrepo-search-service:latest "${REPOSITORY_1_URL}/search-service:${TAG}"
 	docker tag dbrepo-search-service:latest "${REPOSITORY_2_URL}/search-service:${TAG}"
@@ -90,7 +85,7 @@ tag-storage-service-init:
 	docker tag dbrepo-storage-service-init:latest "${REPOSITORY_1_URL}/storage-service-init:${TAG}"
 	docker tag dbrepo-storage-service-init:latest "${REPOSITORY_2_URL}/storage-service-init:${TAG}"
 
-release: build-docker tag release-analyse-service release-authentication-service release-metadata-db release-ui release-metadata-service release-data-service release-log-service release-search-db release-search-db-init release-search-service release-data-db-sidecar
+release: build-docker tag release-analyse-service release-authentication-service release-metadata-db release-ui release-metadata-service release-data-service release-search-db release-search-db-init release-search-service release-data-db-sidecar
 
 release-analyse-service: tag-analyse-service
 	docker push "${REPOSITORY_1_URL}/analyse-service:${TAG}"
@@ -128,10 +123,6 @@ release-metadata-service: tag-metadata-service
 	docker push "${REPOSITORY_1_URL}/metadata-service:${TAG}"
 	docker push "${REPOSITORY_2_URL}/metadata-service:${TAG}"
 
-release-log-service: tag-log-service
-	docker push "${REPOSITORY_1_URL}/log-service:${TAG}"
-	docker push "${REPOSITORY_2_URL}/log-service:${TAG}"
-
 release-search-service: tag-search-service
 	docker push "${REPOSITORY_1_URL}/search-service:${TAG}"
 	docker push "${REPOSITORY_2_URL}/search-service:${TAG}"
@@ -151,7 +142,7 @@ test-metadata-service: build-metadata-service
 test-analyse-service: build-analyse-service
 	bash ./dbrepo-analyse-service/test.sh
 
-scan: scan-analyse-service scan-authentication-service scan-broker-service scan-gateway-service scan-metadata-db scan-metadata-service scan-search-db scan-ui scan-data-service scan-data-db scan-log-service scan-search-dashboard scan-search-service
+scan: scan-analyse-service scan-authentication-service scan-broker-service scan-gateway-service scan-metadata-db scan-metadata-service scan-search-db scan-ui scan-data-service scan-data-db scan-search-dashboard scan-search-service
 
 scan-analyse-service:
 	trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-analyse-service-report.json dbrepo-analyse-service:latest
@@ -210,13 +201,8 @@ scan-ui:
 	trivy image --insecure --exit-code 0 dbrepo-ui:latest
 	trivy image --insecure --exit-code 1 --severity CRITICAL dbrepo-ui:latest
 
-scan-log-service:
-	trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-log-service-report.json dbrepo-log-service:latest
-	trivy image --insecure --exit-code 0 dbrepo-log-service:latest
-	trivy image --insecure --exit-code 1 --severity CRITICAL dbrepo-log-service:latest
-
 scan-search-service:
-	trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-log-service-report.json dbrepo-search-service:latest
+	trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-service-report.json dbrepo-search-service:latest
 	trivy image --insecure --exit-code 0 dbrepo-search-service:latest
 	trivy image --insecure --exit-code 1 --severity CRITICAL dbrepo-search-service:latest
 
diff --git a/README.md b/README.md
index db0bc5baee3ed02bb5e984e0845d2f9d62179c0b..4b38972edd9b06e8acf2e9d2aff3157c68caa8de 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,28 @@
 [![pipeline status](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/badges/master/pipeline.svg)](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/commits/master)
 [![coverage report](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/badges/master/coverage.svg)](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/commits/master)
 [![license](.gitlab/license.svg)](https://opensource.org/licenses/Apache-2.0)
+[![release](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/badges/release.svg)](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/tags)
 
-![DBREPO &mdash; Repository for Data in Databases](./dbrepo-ui/static/logo.png)
+<img src="./dbrepo-ui/static/logo.png" alt="DBREPO &mdash; Repository for Data in Databases" width="200" />
+
+## tl;dr
+
+If you have [Docker](https://docs.docker.com/engine/install/) already installed on your system, you can install DBRepo
+with:
+
+```bash
+curl -sSL https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/install.sh | bash
+```
 
 ## Documentation
 
-More documentation can be found online: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/
+Find a system description, component documentation and endpoint documentation 
+online: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/.
 
 ## Contribute
 
 Contributions are always welcome and encouraged, please read the [contribution overview](./CONTRIBUTING.md) and
-contact [Andreas Rauber](http://www.ifs.tuwien.ac.at/~andi/).
+contact [Prof. Andreas Rauber](http://www.ifs.tuwien.ac.at/~andi/) or [Martin Weise](https://ec.tuwien.ac.at/~weise/).
 
 ## Acknowledgements
 
@@ -20,10 +31,10 @@ We want to thank the following organizations:
 * Bundesministerium für Bildung, Wissenschaft und Forschung (BMBWF) for funding during
   the [call](https://www.bmbwf.gv.at/Themen/HS-Uni/Aktuelles/Ausschreibung--Digitale-und-soziale-Transformation-in-der-Hochschulbildung-.html)
   "Digitale und soziale Transformation in der Hochschulbildung".
-* [TU.it](https://www.it.tuwien.ac.at/en/) for their continuous support in project work, funding and compute resources
-  provided in-kind.
+* [TU.it &amp; .digital office](https://www.it.tuwien.ac.at/en/) for their continuous support in project 
+  work, [funding](https://www.tuwien.at/tu-wien/organisation/zentrale-bereiche/digital-office/projekte/dcall-2023-projekte)
+  and compute resources provided in-kind.
 
 ## License
 
-This work is licensed under
-a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/)
\ No newline at end of file
+The source code is licensed under [Apache 2.0](https://opensource.org/licenses/Apache-2.0).
\ No newline at end of file
diff --git a/dbrepo-analyse-service/Dockerfile b/dbrepo-analyse-service/Dockerfile
index 50d56f60e22eb354ac003b821148c2ab0313ef3c..714cfc9e8580741f3dc9e24f3cae048001db95ba 100644
--- a/dbrepo-analyse-service/Dockerfile
+++ b/dbrepo-analyse-service/Dockerfile
@@ -1,7 +1,7 @@
 FROM python:3.9-slim
 MAINTAINER Martin Weise <martin.weise@tuwien.ac.at>
 
-RUN apt update && apt install -y curl
+RUN apt update && apt install -y curl gcc libmariadb-dev
 
 WORKDIR /app
 
diff --git a/dbrepo-analyse-service/Pipfile b/dbrepo-analyse-service/Pipfile
index 29d57acc66b8dab57afb21b1a9922439e753af5a..99ab9195d0612621ea6fa0bd535b880e51807896 100644
--- a/dbrepo-analyse-service/Pipfile
+++ b/dbrepo-analyse-service/Pipfile
@@ -16,11 +16,16 @@ numpy = "*"
 pandas = "*"
 messytables = "*"
 minio = "*"
+flask-sqlalchemy = "*"
+opensearch-py = "*"
+pymysql = "*"
 
 [dev-packages]
 coverage = "*"
 pytest = "*"
 testcontainers-minio = "*"
+testcontainers-mysql = "*"
+testcontainers-opensearch = "*"
 
 [requires]
 python_version = "3.9"
diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock
index 1000eddec96027aff2f5400389a7d6fa52842157..776c27c79292e25b1ef041eaf9e7cc4c136f17ed 100644
--- a/dbrepo-analyse-service/Pipfile.lock
+++ b/dbrepo-analyse-service/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "fe382056038fea58538a52ab9f8ac7bd80659537f8336a534cb79a71e515bceb"
+            "sha256": "593bb7bb2fab9041c4da489021bb7fe2f857624e18f484d53f1c4f3958b04837"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -69,19 +69,19 @@
         },
         "boto3": {
             "hashes": [
-                "sha256:1f94042f4efb5133b6b9b8b3243afc01143a81d21b3197a3afadf5780f97b05d",
-                "sha256:5c1bb487c68120aae236354d81b8a1a55d0aa3395d30748a01825ef90891921e"
+                "sha256:1efc02be786884034d503d59c018cf7650d0cff9fcb37cd2eb49b802a6fe6111",
+                "sha256:8ca248cc84e7e859e4e276eb9c4309fa01a3e58473bf48d6c33448be870c2bb8"
             ],
             "index": "pypi",
-            "version": "==1.34.14"
+            "version": "==1.34.17"
         },
         "botocore": {
             "hashes": [
-                "sha256:041bed0852649cab7e4dcd4d87f9d1cc084467fb846e5b60015e014761d96414",
-                "sha256:3b592f50f0406e236782a3a0a9ad1c3976060fdb2e04a23d18c3df5b7dfad3e0"
+                "sha256:7272c39032c6f1d62781e4c8445d9a1d9140c2bf52ba7ee66bf6db559c4b2427",
+                "sha256:e48a662f3a6919219276b55085e8f73c3347966675f55e9d448be30cf79678ee"
             ],
             "markers": "python_version >= '3.8'",
-            "version": "==1.34.14"
+            "version": "==1.34.17"
         },
         "certifi": {
             "hashes": [
@@ -250,7 +250,7 @@
                 "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
                 "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
             ],
-            "markers": "python_full_version >= '3.7.0'",
+            "markers": "python_version >= '3.7'",
             "version": "==3.3.2"
         },
         "click": {
@@ -284,6 +284,14 @@
             "index": "pypi",
             "version": "==3.0.0"
         },
+        "flask-sqlalchemy": {
+            "hashes": [
+                "sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0",
+                "sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312"
+            ],
+            "index": "pypi",
+            "version": "==3.1.1"
+        },
         "gevent": {
             "hashes": [
                 "sha256:272cffdf535978d59c38ed837916dfd2b5d193be1e9e5dcc60a5f4d5025dd98a",
@@ -391,7 +399,7 @@
                 "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
                 "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
             ],
-            "markers": "python_version >= '3.11' and platform_python_implementation == 'CPython'",
+            "index": "pypi",
             "version": "==3.0.3"
         },
         "gunicorn": {
@@ -418,6 +426,14 @@
             "markers": "python_version >= '3.5'",
             "version": "==3.6"
         },
+        "importlib-metadata": {
+            "hashes": [
+                "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e",
+                "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"
+            ],
+            "markers": "python_version < '3.10'",
+            "version": "==7.0.1"
+        },
         "itsdangerous": {
             "hashes": [
                 "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
@@ -428,11 +444,11 @@
         },
         "jinja2": {
             "hashes": [
-                "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
-                "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
+                "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa",
+                "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"
             ],
             "markers": "python_version >= '3.7'",
-            "version": "==3.1.2"
+            "version": "==3.1.3"
         },
         "jmespath": {
             "hashes": [
@@ -466,97 +482,87 @@
         },
         "lxml": {
             "hashes": [
-                "sha256:00bfccab28f710bb13f7f644c980ad50ce3e5b6a412b5bb9a6c30136b298fb2c",
-                "sha256:03c977ffc9a4bf17b3e0f8db0451dc38e9f4ec92cfdb5df462d38fbe6e6e0825",
-                "sha256:0499310df9afc0ce634ce14cacbb333d62f561038ea4db640494e4a22ac4f2e9",
-                "sha256:070469a23f2ef3a9e72165af7e0b12eca9a6e47c3a8ec1cad60d14fb2f2c3aa8",
-                "sha256:0963de4fe463caff48e6ce4d83d19a3c099126874185d10cf490c29057ca518d",
-                "sha256:0a79eca2ef5e032c8ed9da07f84a07a29105f220b777613dfe7fc31445691ee3",
-                "sha256:0dc36ec06514fe8848c4733d47f96a0636f82d9ca3eaa2132373426bc03f178f",
-                "sha256:0ecc0f1e1d901b66f2f68edff85b8ff421fa9683d02eaea6742a42c145d741b6",
-                "sha256:0f70e5de6b3e24ababeca597f776e5f37973f05d28a4d9f467aa5b45745af762",
-                "sha256:0fb55d77e685def5218701d5d296fca62f595752c88402404da685864b06b67e",
-                "sha256:1215c8e57a25ad68488abb83a36734f6c6b3f0ccd880f0c68da98682d463ef09",
-                "sha256:1546fa25a6dde5698271e19787062446f433c98ca7eab35545f665dde2c1bd34",
-                "sha256:18b456f1bfb338be94a916166ac5507e73b9eb9f6e1f0fbd1c8caff2f3fa5535",
-                "sha256:18caa0d3925902949cb060fe5f2da70c953d60bd9ef78657bd389f6db30533cc",
-                "sha256:19251f782ea51a4841e747158195312ef63e06b47889e159dc5f1b2e5d668465",
-                "sha256:1d78e91cbffe733ff325e0d258bb64702c8d91f8f652db088bd2989c6a8f90cc",
-                "sha256:2ec9fa65e0638551a5ad31cb9fa160b321f19632e5ec517fe68d7b4110133e69",
-                "sha256:3013823b0069cb4bd9b558e87076a18142703c6d2ac3a5d5521dd35734d23a72",
-                "sha256:31362b900b8fd2a026b9d24695ebe5449ea8f0c948af2445d7880b738d9fc368",
-                "sha256:32a135d4ef8f966bc087d450d641df73fc6874f04cf6608111541b50090e6f13",
-                "sha256:331237209fe76951450c1119af0879f04f32d1b07b21e83a34ba439520492feb",
-                "sha256:3714f339449d2738b4fadd078a6022704a2af3cab06bec9627b19eaa4205090d",
-                "sha256:387c5416b8bb4b8ad7306797cb2719a841f5f3836b3c39fcaa56b9af5448dd2a",
-                "sha256:39a3cf581e9040e66aaa719b2f338b2b7eb43ce1db059089c82ae72e0fd48b47",
-                "sha256:3ffc56d68b9782919d69ae9a6fac99efd7547f2666ccb7ecfd12871564d16133",
-                "sha256:42069ce16dab9755b381b90defd846ca407b9ead05dc20732fd5502b5cc49b87",
-                "sha256:430780608d16b3bb96ef99a67a1a0626c8a295193af53ce9c4d5ec3fef2fbc79",
-                "sha256:4432a1d89a9b340bc6bd1201aef3ba03112f151d3f340d9218247dc0c85028ab",
-                "sha256:45e747b4e82390ffd802528b9e7b39333c1ce71423057bf5961b30ec0d52f76f",
-                "sha256:473f2d0511dd84697326ee9362b0c0c2e9f99a433dcb1fbb5aa8df3d1b2185db",
-                "sha256:47f46a2ebade07f3afa47695882e7725440c49bf77cba39c3762a42597e5aad3",
-                "sha256:49dc4dcf14a08f160bb3f5f571f63514d918b8933a25c221536571a5fc010271",
-                "sha256:4ae66b6b0f82e7839b6b8d009182c652d48e7d2ea21a6709f3033ce5fbf199c4",
-                "sha256:4b49a1569ed6d05808f4d163a316e7bf4a230e0c36855b59f56020ae27ae586a",
-                "sha256:4d58af4ebd711dad40f1c024a779950d9918d04d74f49230edf5d271dcd33c28",
-                "sha256:4df6be79be4d7574e9e4002aeb6aa03d3f3809582db07abb166df7fc6e7438af",
-                "sha256:57f5c362cbd9d688fb1fa07c8955cec26d5c066fbcb4163aa341ff751eba7587",
-                "sha256:5892cff0a6817743fe470b7402677310ffc8514a74de14d4e591cecdc457ff61",
-                "sha256:60974986aa80a8bb883da5663f90bc632bd4ce0d0508e66a9132412facec65f6",
-                "sha256:62a3c0fdf70f785cd29824666d1dcea88c207f0b73ddbc28fb7a6a1a5bbb1af7",
-                "sha256:67ddff0272905a0b78a2c3ea01487e0551cc38094cd5994f73af370f355ecb47",
-                "sha256:6af86081c888ce81ca7e361ed7fa2ba1678e2a86eb5a059c96d5a719364d319e",
-                "sha256:6cdd0fb749c80ffcf408f659b209e82333f10b517786083a3dd3c3b5adc60111",
-                "sha256:737a4dba9f7ee842c6597f719dda2eabeeaefe42443f7f24de20c262f88527cd",
-                "sha256:73e71b95c5215310a92e560369ac1f0e2cd018d5a36be182da88958f3d6084f5",
-                "sha256:745383c124f096cc03fb942c8a05ea1e8cb4f44c5b28887adce6224e4540808e",
-                "sha256:7febf50135363e981097eeada84781eeae92bfc3c203495f63d6b542a7132ba7",
-                "sha256:821fb791565536617b058c2cd5b8d28a1285b3375eecc5bd6b5c6d87add0d3dd",
-                "sha256:83ff41e1bc0666f31acda52407d869ea257f232c2d9394806647a0e7454de73e",
-                "sha256:8991837fdf8086486f1c300d936bacd757e2e5398be84cd54a1fba0e6b6d5591",
-                "sha256:8a70c47c14f89b8bfb430f85b608aa460204fe7c005545d79afd31b925cc6669",
-                "sha256:8ba56c3686fa60cc04191d22d1733aad484c9cbc153cdc3e8eb9bdfcad30f704",
-                "sha256:8de180f748a17382dd695b3999be03a647d09af16ae589c4e9c37138ddb6d4c6",
-                "sha256:96c2abcbcb24f850f00f279c4660ce6498cae16ff1659845838d752c26890748",
-                "sha256:99b5ca5775435aa296d32ea711e194aaae871b21dbf0d57cb7d4431e5d3ad699",
-                "sha256:9a4eff4d8ad0bbc9f470a9be19c5e718af4baf47111d7c2d9b036b9986107e7c",
-                "sha256:9a99dae826c80cf0a21dd21eb66db16310d1f58ac4c27c804da980212fbcabe2",
-                "sha256:9e8a4782ecaaacf8e9355f39179b1f00e7f27b774306eccbe80f6215724be4cd",
-                "sha256:a28eab2d9ea79b830be50e3350d827ae8abf5b23e278e14929824d5ab2069008",
-                "sha256:ae3a0ec0f1b6cf1e8bca41bc86cd64ba02e31c71716efbf149a0f7ebc168cf0b",
-                "sha256:b005101a257c494e84d36ecb62b02ba195b02b7f8892f57b1f5aaa352ed44467",
-                "sha256:b4eef43c5dc5c579d0804e55a32dd1bacbd008c8191ed4d65be278bbb11ddc61",
-                "sha256:b6bb5a0a87ab1e01f086cbb418be9e409719cd216954aa38b1cceee36a561ce1",
-                "sha256:b7bb0010c2969c23bf3d2b3892e638a7cb83e7daeb749e3db5f3c002fd191e11",
-                "sha256:b889c0b9be774466308c3590e093ce9a6f9115c78fc8624aa6ba8dfeaf5188ab",
-                "sha256:bcded868b05583d41ab0b024f39f90a04e486a2349a9b493d8d17024f1433aa6",
-                "sha256:c21e60c017cab3a7e7786185cc8853b8614b01ccd69cc8b24608e5356784631b",
-                "sha256:c32a4fbae218b336d547bc626897325202e4e9f1794ac5f4d0bb3caacf41df21",
-                "sha256:c4eaa83b610595ef9f20aa69b96053d5b7f3f70c67c7a3af8f433136a9d315ab",
-                "sha256:c5b23f63fcec652bf1e775eca5e03a713a4994d2a7ce2e70a91e964a26220e0d",
-                "sha256:cfdac95815d3025e4c9edce2ef2ebe4e034edc35a2c44a606dd846554387ae38",
-                "sha256:d0047c90e0ebd0d8f3c1e6636e10f597b8f25e4ef9e6416dd2e5c4c0960270cc",
-                "sha256:d05cf827f160340f67c25ce6f271689a844605aa123849f1a80e21c9bd21f00b",
-                "sha256:d64e543b07964ff73b4eb994bee894803a80e19fd3b29a5ffbe3c637fe43e788",
-                "sha256:d6d3ce5638cd4ed3fa684507f164e7039e1b07475bc8f37ba6e12271c1a2e9e0",
-                "sha256:d80d9f4d986bb6ad65bae86f07391152f7b6c65cfc63d118616b18b0be2e79da",
-                "sha256:dbff288e1869db78f8731ca257553dd699edef07e173b35e71b1122b630d6008",
-                "sha256:dcb25128c9e7f01c00ad116d2c762c3942724981a35c6e5c551ab55d4c2bfcfe",
-                "sha256:dcc7dc4b9b65f185aa8533abc78f0a3b2ac38fe075bb23d3c1590ba0990f6c80",
-                "sha256:e2388a792f9c239510d62a9e615662b8202e4ca275aafcc9c4af154654462a14",
-                "sha256:e2bd8faf6a9682ca385e4bca1a38a057be716dc303f16ddec9e4c9cf01b7d722",
-                "sha256:e97c74725e86d84a477df081eef69b70f048128afee841dbd8c690a9e3d2e8e0",
-                "sha256:ea5e4b3eff9029a02fe7736540675ab8fca44277232f0027397b0d7111d04b1c",
-                "sha256:f36c3103a6f2641777b64f1da860f37cbaa718ce3feea621583627269e68eb03",
-                "sha256:f56e6a38c64a79e228d48344bb3bec265ac035fc1277ce8c049445bb18e4cd41",
-                "sha256:f9464ff2fd1f2ba4d0d246a560d369ee7e7213c556a30db9ae9426850ce1baf9",
-                "sha256:feb1102d9e5de08120d46a1011110c43b2547ecb3ae80030801e0e2dacd1ee18",
-                "sha256:ff29353c12f0abc9cb3395899b7192a970d5a63f80ac1e7f0c3247ed83f5dcd4"
+                "sha256:13521a321a25c641b9ea127ef478b580b5ec82aa2e9fc076c86169d161798b01",
+                "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f",
+                "sha256:16018f7099245157564d7148165132c70adb272fb5a17c048ba70d9cc542a1a1",
+                "sha256:16dd953fb719f0ffc5bc067428fc9e88f599e15723a85618c45847c96f11f431",
+                "sha256:19a1bc898ae9f06bccb7c3e1dfd73897ecbbd2c96afe9095a6026016e5ca97b8",
+                "sha256:1ad17c20e3666c035db502c78b86e58ff6b5991906e55bdbef94977700c72623",
+                "sha256:22b7ee4c35f374e2c20337a95502057964d7e35b996b1c667b5c65c567d2252a",
+                "sha256:24ef5a4631c0b6cceaf2dbca21687e29725b7c4e171f33a8f8ce23c12558ded1",
+                "sha256:25663d6e99659544ee8fe1b89b1a8c0aaa5e34b103fab124b17fa958c4a324a6",
+                "sha256:262bc5f512a66b527d026518507e78c2f9c2bd9eb5c8aeeb9f0eb43fcb69dc67",
+                "sha256:280f3edf15c2a967d923bcfb1f8f15337ad36f93525828b40a0f9d6c2ad24890",
+                "sha256:2ad3a8ce9e8a767131061a22cd28fdffa3cd2dc193f399ff7b81777f3520e372",
+                "sha256:2befa20a13f1a75c751f47e00929fb3433d67eb9923c2c0b364de449121f447c",
+                "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb",
+                "sha256:304128394c9c22b6569eba2a6d98392b56fbdfbad58f83ea702530be80d0f9df",
+                "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84",
+                "sha256:3aeca824b38ca78d9ee2ab82bd9883083d0492d9d17df065ba3b94e88e4d7ee6",
+                "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45",
+                "sha256:3e3898ae2b58eeafedfe99e542a17859017d72d7f6a63de0f04f99c2cb125936",
+                "sha256:3eea6ed6e6c918e468e693c41ef07f3c3acc310b70ddd9cc72d9ef84bc9564ca",
+                "sha256:3f14a4fb1c1c402a22e6a341a24c1341b4a3def81b41cd354386dcb795f83897",
+                "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a",
+                "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d",
+                "sha256:49a9b4af45e8b925e1cd6f3b15bbba2c81e7dba6dce170c677c9cda547411e14",
+                "sha256:4f8b0c78e7aac24979ef09b7f50da871c2de2def043d468c4b41f512d831e912",
+                "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354",
+                "sha256:5e53d7e6a98b64fe54775d23a7c669763451340c3d44ad5e3a3b48a1efbdc96f",
+                "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c",
+                "sha256:601f4a75797d7a770daed8b42b97cd1bb1ba18bd51a9382077a6a247a12aa38d",
+                "sha256:61c5a7edbd7c695e54fca029ceb351fc45cd8860119a0f83e48be44e1c464862",
+                "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969",
+                "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e",
+                "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8",
+                "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e",
+                "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa",
+                "sha256:7cfced4a069003d8913408e10ca8ed092c49a7f6cefee9bb74b6b3e860683b45",
+                "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a",
+                "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147",
+                "sha256:82cd34f1081ae4ea2ede3d52f71b7be313756e99b4b5f829f89b12da552d3aa3",
+                "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3",
+                "sha256:877efb968c3d7eb2dad540b6cabf2f1d3c0fbf4b2d309a3c141f79c7e0061324",
+                "sha256:8b9f19df998761babaa7f09e6bc169294eefafd6149aaa272081cbddc7ba4ca3",
+                "sha256:8cf5877f7ed384dabfdcc37922c3191bf27e55b498fecece9fd5c2c7aaa34c33",
+                "sha256:8d2900b7f5318bc7ad8631d3d40190b95ef2aa8cc59473b73b294e4a55e9f30f",
+                "sha256:8d7b4beebb178e9183138f552238f7e6613162a42164233e2bda00cb3afac58f",
+                "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764",
+                "sha256:98f3f020a2b736566c707c8e034945c02aa94e124c24f77ca097c446f81b01f1",
+                "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114",
+                "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581",
+                "sha256:9bcf86dfc8ff3e992fed847c077bd875d9e0ba2fa25d859c3a0f0f76f07f0c8d",
+                "sha256:9bd0ae7cc2b85320abd5e0abad5ccee5564ed5f0cc90245d2f9a8ef330a8deae",
+                "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da",
+                "sha256:9e5ac3437746189a9b4121db2a7b86056ac8786b12e88838696899328fc44bb2",
+                "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e",
+                "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda",
+                "sha256:a96f02ba1bcd330807fc060ed91d1f7a20853da6dd449e5da4b09bfcc08fdcf5",
+                "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa",
+                "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1",
+                "sha256:af8920ce4a55ff41167ddbc20077f5698c2e710ad3353d32a07d3264f3a2021e",
+                "sha256:afd825e30f8d1f521713a5669b63657bcfe5980a916c95855060048b88e1adb7",
+                "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1",
+                "sha256:b4b68c961b5cc402cbd99cca5eb2547e46ce77260eb705f4d117fd9c3f932b95",
+                "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93",
+                "sha256:b9e240ae0ba96477682aa87899d94ddec1cc7926f9df29b1dd57b39e797d5ab5",
+                "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b",
+                "sha256:bf8443781533b8d37b295016a4b53c1494fa9a03573c09ca5104550c138d5c05",
+                "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5",
+                "sha256:c3cd1fc1dc7c376c54440aeaaa0dcc803d2126732ff5c6b68ccd619f2e64be4f",
+                "sha256:c7257171bb8d4432fe9d6fdde4d55fdbe663a63636a17f7f9aaba9bcb3153ad7",
+                "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8",
+                "sha256:d74fcaf87132ffc0447b3c685a9f862ffb5b43e70ea6beec2fb8057d5d2a1fea",
+                "sha256:d8c1d679df4361408b628f42b26a5d62bd3e9ba7f0c0e7969f925021554755aa",
+                "sha256:e856c1c7255c739434489ec9c8aa9cdf5179785d10ff20add308b5d673bed5cd",
+                "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b",
+                "sha256:ed7326563024b6e91fef6b6c7a1a2ff0a71b97793ac33dbbcf38f6005e51ff6e",
+                "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4",
+                "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204",
+                "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"
             ],
-            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
-            "version": "==5.0.1"
+            "markers": "python_version >= '3.6'",
+            "version": "==5.1.0"
         },
         "markupsafe": {
             "hashes": [
@@ -689,6 +695,14 @@
             "index": "pypi",
             "version": "==1.26.3"
         },
+        "opensearch-py": {
+            "hashes": [
+                "sha256:564f175af134aa885f4ced6846eb4532e08b414fff0a7976f76b276fe0e69158",
+                "sha256:7867319132133e2974c09f76a54eb1d502b989229be52da583d93ddc743ea111"
+            ],
+            "index": "pypi",
+            "version": "==2.4.2"
+        },
         "packaging": {
             "hashes": [
                 "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
@@ -753,41 +767,49 @@
         },
         "pycryptodome": {
             "hashes": [
-                "sha256:08b445799d571041765e7d5c9ca09c5d3866c2f22eeb0dd4394a4169285184f4",
-                "sha256:11ddf6c9b52116b62223b6a9f4741bc4f62bb265392a4463282f7f34bb287180",
-                "sha256:1c6273ca5a03b672e504995529b8bae56da0ebb691d8ef141c4aa68f60765700",
-                "sha256:27e1efcb68993b7ce5d1d047a46a601d41281bba9f1971e6be4aa27c69ab8065",
-                "sha256:2c16426ef49d9cba018be2340ea986837e1dfa25c2ea181787971654dd49aadd",
-                "sha256:37e531bf896b70fe302f003d3be5a0a8697737a8d177967da7e23eff60d6483c",
-                "sha256:420972f9c62978e852c74055d81c354079ce3c3a2213a92c9d7e37bbc63a26e2",
-                "sha256:4464b0e8fd5508bff9baf18e6fd4c6548b1ac2ce9862d6965ff6a84ec9cb302a",
-                "sha256:4805e053571140cb37cf153b5c72cd324bb1e3e837cbe590a19f69b6cf85fd03",
-                "sha256:67939a3adbe637281c611596e44500ff309d547e932c449337649921b17b6297",
-                "sha256:694020d2ff985cd714381b9da949a21028c24b86f562526186f6af7c7547e986",
-                "sha256:6c3df3613592ea6afaec900fd7189d23c8c28b75b550254f4bd33fe94acb84b9",
-                "sha256:6d0d2b97758ebf2f36c39060520447c26455acb3bcff309c28b1c816173a6ff5",
-                "sha256:7c9e222d0976f68d0cf6409cfea896676ddc1d98485d601e9508f90f60e2b0a2",
-                "sha256:81e9d23c0316fc1b45d984a44881b220062336bbdc340aa9218e8d0656587934",
-                "sha256:8ae0dd1bcfada451c35f9e29a3e5db385caabc190f98e4a80ad02a61098fb776",
-                "sha256:8cf5d3d6cf921fa81acd1f632f6cedcc03f5f68fc50c364cd39490ba01d17c49",
-                "sha256:954d156cd50130afd53f8d77f830fe6d5801bd23e97a69d358fed068f433fbfe",
-                "sha256:a470237ee71a1efd63f9becebc0ad84b88ec28e6784a2047684b693f458f41b7",
-                "sha256:a991f8ffe8dfe708f86690948ae46442eebdd0fff07dc1b605987939a34ec979",
-                "sha256:b0bfe61506795877ff974f994397f0c862d037f6f1c0bfc3572195fc00833b96",
-                "sha256:b7efd46b0b4ac869046e814d83244aeab14ef787f4850644119b1c8b0ec2d637",
-                "sha256:b8b80ff92049fd042177282917d994d344365ab7e8ec2bc03e853d93d2401786",
-                "sha256:c1bc0c49d986a1491d66d2a56570f12e960b12508b7e71f2423f532e28857f36",
-                "sha256:c22c80246c3c880c6950d2a8addf156cee74ec0dc5757d01e8e7067a3c7da015",
-                "sha256:cd4e7e8bf0fc1ada854688b9b309ee607e2aa85a8b44180f91021a4dd330a928",
-                "sha256:cd4e95b0eb4b28251c825fe7aa941fe077f993e5ca9b855665935b86fbb1cc08",
-                "sha256:e038ab77fec0956d7aa989a3c647652937fc142ef41c9382c2ebd13c127d5b4a",
-                "sha256:e3e6f89480616781d2a7f981472d0cdb09b9da9e8196f43c1234eff45c915766",
-                "sha256:e70f5c839c7798743a948efa2a65d1fe96bb397fe6d7f2bde93d869fe4f0ad69",
-                "sha256:ed932eb6c2b1c4391e166e1a562c9d2f020bfff44a0e1b108f67af38b390ea89",
-                "sha256:f34976c5c8eb79e14c7d970fb097482835be8d410a4220f86260695ede4c3e17"
+                "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690",
+                "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7",
+                "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4",
+                "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd",
+                "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5",
+                "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc",
+                "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818",
+                "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab",
+                "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d",
+                "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a",
+                "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25",
+                "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091",
+                "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea",
+                "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a",
+                "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c",
+                "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72",
+                "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9",
+                "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6",
+                "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044",
+                "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04",
+                "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c",
+                "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e",
+                "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f",
+                "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b",
+                "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4",
+                "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33",
+                "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f",
+                "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e",
+                "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a",
+                "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2",
+                "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3",
+                "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"
             ],
             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
-            "version": "==3.19.1"
+            "version": "==3.20.0"
+        },
+        "pymysql": {
+            "hashes": [
+                "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
+                "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
+            ],
+            "index": "pypi",
+            "version": "==1.1.0"
         },
         "python-dateutil": {
             "hashes": [
@@ -1013,6 +1035,61 @@
             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
             "version": "==1.16.0"
         },
+        "sqlalchemy": {
+            "hashes": [
+                "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9",
+                "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d",
+                "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e",
+                "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669",
+                "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d",
+                "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5",
+                "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002",
+                "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e",
+                "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd",
+                "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215",
+                "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24",
+                "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39",
+                "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62",
+                "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900",
+                "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf",
+                "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735",
+                "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4",
+                "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23",
+                "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9",
+                "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c",
+                "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de",
+                "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7",
+                "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625",
+                "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f",
+                "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a",
+                "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4",
+                "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643",
+                "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018",
+                "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9",
+                "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5",
+                "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08",
+                "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3",
+                "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3",
+                "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed",
+                "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95",
+                "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6",
+                "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0",
+                "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84",
+                "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f",
+                "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d",
+                "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2",
+                "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5",
+                "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570",
+                "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7",
+                "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c",
+                "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf",
+                "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3",
+                "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed",
+                "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"
+            ],
+            "markers": "python_version >= '3.7'",
+            "version": "==2.0.25"
+        },
         "typing-extensions": {
             "hashes": [
                 "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783",
@@ -1031,11 +1108,11 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84",
-                "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"
+                "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07",
+                "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"
             ],
-            "markers": "python_version >= '3.7'",
-            "version": "==2.0.7"
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
+            "version": "==1.26.18"
         },
         "webencodings": {
             "hashes": [
@@ -1060,6 +1137,14 @@
             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
             "version": "==2.0.1"
         },
+        "zipp": {
+            "hashes": [
+                "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31",
+                "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"
+            ],
+            "markers": "python_version >= '3.8'",
+            "version": "==3.17.0"
+        },
         "zope.event": {
             "hashes": [
                 "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26",
@@ -1306,7 +1391,7 @@
                 "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
                 "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
             ],
-            "markers": "python_full_version >= '3.7.0'",
+            "markers": "python_version >= '3.7'",
             "version": "==3.3.2"
         },
         "coverage": {
@@ -1375,6 +1460,78 @@
             "markers": "python_version >= '3.8'",
             "version": "==7.0.0"
         },
+        "exceptiongroup": {
+            "hashes": [
+                "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14",
+                "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"
+            ],
+            "index": "pypi",
+            "version": "==1.2.0"
+        },
+        "greenlet": {
+            "hashes": [
+                "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67",
+                "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6",
+                "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257",
+                "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4",
+                "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676",
+                "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61",
+                "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc",
+                "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca",
+                "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7",
+                "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728",
+                "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305",
+                "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6",
+                "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379",
+                "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414",
+                "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04",
+                "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a",
+                "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf",
+                "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491",
+                "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559",
+                "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e",
+                "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274",
+                "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb",
+                "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b",
+                "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9",
+                "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b",
+                "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be",
+                "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506",
+                "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405",
+                "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113",
+                "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f",
+                "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5",
+                "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230",
+                "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d",
+                "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f",
+                "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a",
+                "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e",
+                "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61",
+                "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6",
+                "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d",
+                "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71",
+                "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22",
+                "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2",
+                "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3",
+                "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067",
+                "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc",
+                "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881",
+                "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3",
+                "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e",
+                "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac",
+                "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53",
+                "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0",
+                "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b",
+                "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83",
+                "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41",
+                "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c",
+                "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf",
+                "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
+                "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
+            ],
+            "index": "pypi",
+            "version": "==3.0.3"
+        },
         "idna": {
             "hashes": [
                 "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca",
@@ -1399,6 +1556,14 @@
             "index": "pypi",
             "version": "==7.2.3"
         },
+        "opensearch-py": {
+            "hashes": [
+                "sha256:564f175af134aa885f4ced6846eb4532e08b414fff0a7976f76b276fe0e69158",
+                "sha256:7867319132133e2974c09f76a54eb1d502b989229be52da583d93ddc743ea111"
+            ],
+            "index": "pypi",
+            "version": "==2.4.2"
+        },
         "packaging": {
             "hashes": [
                 "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
@@ -1424,41 +1589,49 @@
         },
         "pycryptodome": {
             "hashes": [
-                "sha256:08b445799d571041765e7d5c9ca09c5d3866c2f22eeb0dd4394a4169285184f4",
-                "sha256:11ddf6c9b52116b62223b6a9f4741bc4f62bb265392a4463282f7f34bb287180",
-                "sha256:1c6273ca5a03b672e504995529b8bae56da0ebb691d8ef141c4aa68f60765700",
-                "sha256:27e1efcb68993b7ce5d1d047a46a601d41281bba9f1971e6be4aa27c69ab8065",
-                "sha256:2c16426ef49d9cba018be2340ea986837e1dfa25c2ea181787971654dd49aadd",
-                "sha256:37e531bf896b70fe302f003d3be5a0a8697737a8d177967da7e23eff60d6483c",
-                "sha256:420972f9c62978e852c74055d81c354079ce3c3a2213a92c9d7e37bbc63a26e2",
-                "sha256:4464b0e8fd5508bff9baf18e6fd4c6548b1ac2ce9862d6965ff6a84ec9cb302a",
-                "sha256:4805e053571140cb37cf153b5c72cd324bb1e3e837cbe590a19f69b6cf85fd03",
-                "sha256:67939a3adbe637281c611596e44500ff309d547e932c449337649921b17b6297",
-                "sha256:694020d2ff985cd714381b9da949a21028c24b86f562526186f6af7c7547e986",
-                "sha256:6c3df3613592ea6afaec900fd7189d23c8c28b75b550254f4bd33fe94acb84b9",
-                "sha256:6d0d2b97758ebf2f36c39060520447c26455acb3bcff309c28b1c816173a6ff5",
-                "sha256:7c9e222d0976f68d0cf6409cfea896676ddc1d98485d601e9508f90f60e2b0a2",
-                "sha256:81e9d23c0316fc1b45d984a44881b220062336bbdc340aa9218e8d0656587934",
-                "sha256:8ae0dd1bcfada451c35f9e29a3e5db385caabc190f98e4a80ad02a61098fb776",
-                "sha256:8cf5d3d6cf921fa81acd1f632f6cedcc03f5f68fc50c364cd39490ba01d17c49",
-                "sha256:954d156cd50130afd53f8d77f830fe6d5801bd23e97a69d358fed068f433fbfe",
-                "sha256:a470237ee71a1efd63f9becebc0ad84b88ec28e6784a2047684b693f458f41b7",
-                "sha256:a991f8ffe8dfe708f86690948ae46442eebdd0fff07dc1b605987939a34ec979",
-                "sha256:b0bfe61506795877ff974f994397f0c862d037f6f1c0bfc3572195fc00833b96",
-                "sha256:b7efd46b0b4ac869046e814d83244aeab14ef787f4850644119b1c8b0ec2d637",
-                "sha256:b8b80ff92049fd042177282917d994d344365ab7e8ec2bc03e853d93d2401786",
-                "sha256:c1bc0c49d986a1491d66d2a56570f12e960b12508b7e71f2423f532e28857f36",
-                "sha256:c22c80246c3c880c6950d2a8addf156cee74ec0dc5757d01e8e7067a3c7da015",
-                "sha256:cd4e7e8bf0fc1ada854688b9b309ee607e2aa85a8b44180f91021a4dd330a928",
-                "sha256:cd4e95b0eb4b28251c825fe7aa941fe077f993e5ca9b855665935b86fbb1cc08",
-                "sha256:e038ab77fec0956d7aa989a3c647652937fc142ef41c9382c2ebd13c127d5b4a",
-                "sha256:e3e6f89480616781d2a7f981472d0cdb09b9da9e8196f43c1234eff45c915766",
-                "sha256:e70f5c839c7798743a948efa2a65d1fe96bb397fe6d7f2bde93d869fe4f0ad69",
-                "sha256:ed932eb6c2b1c4391e166e1a562c9d2f020bfff44a0e1b108f67af38b390ea89",
-                "sha256:f34976c5c8eb79e14c7d970fb097482835be8d410a4220f86260695ede4c3e17"
+                "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690",
+                "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7",
+                "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4",
+                "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd",
+                "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5",
+                "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc",
+                "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818",
+                "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab",
+                "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d",
+                "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a",
+                "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25",
+                "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091",
+                "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea",
+                "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a",
+                "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c",
+                "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72",
+                "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9",
+                "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6",
+                "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044",
+                "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04",
+                "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c",
+                "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e",
+                "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f",
+                "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b",
+                "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4",
+                "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33",
+                "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f",
+                "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e",
+                "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a",
+                "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2",
+                "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3",
+                "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"
             ],
             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
-            "version": "==3.19.1"
+            "version": "==3.20.0"
+        },
+        "pymysql": {
+            "hashes": [
+                "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
+                "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
+            ],
+            "index": "pypi",
+            "version": "==1.1.0"
         },
         "pytest": {
             "hashes": [
@@ -1468,6 +1641,14 @@
             "index": "pypi",
             "version": "==7.4.4"
         },
+        "python-dateutil": {
+            "hashes": [
+                "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
+                "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+            "version": "==2.8.2"
+        },
         "requests": {
             "hashes": [
                 "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
@@ -1476,6 +1657,69 @@
             "markers": "python_version >= '3.7'",
             "version": "==2.31.0"
         },
+        "six": {
+            "hashes": [
+                "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
+                "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+            "version": "==1.16.0"
+        },
+        "sqlalchemy": {
+            "hashes": [
+                "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9",
+                "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d",
+                "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e",
+                "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669",
+                "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d",
+                "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5",
+                "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002",
+                "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e",
+                "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd",
+                "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215",
+                "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24",
+                "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39",
+                "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62",
+                "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900",
+                "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf",
+                "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735",
+                "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4",
+                "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23",
+                "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9",
+                "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c",
+                "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de",
+                "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7",
+                "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625",
+                "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f",
+                "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a",
+                "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4",
+                "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643",
+                "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018",
+                "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9",
+                "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5",
+                "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08",
+                "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3",
+                "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3",
+                "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed",
+                "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95",
+                "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6",
+                "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0",
+                "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84",
+                "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f",
+                "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d",
+                "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2",
+                "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5",
+                "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570",
+                "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7",
+                "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c",
+                "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf",
+                "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3",
+                "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed",
+                "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"
+            ],
+            "markers": "python_version >= '3.7'",
+            "version": "==2.0.25"
+        },
         "testcontainers-core": {
             "hashes": [
                 "sha256:69a8bf2ddb52ac2d03c26401b12c70db0453cced40372ad783d6dce417e52095"
@@ -1490,6 +1734,28 @@
             "index": "pypi",
             "version": "==0.0.1rc1"
         },
+        "testcontainers-mysql": {
+            "hashes": [
+                "sha256:d22894e0d8c7b4f7424afef99f713aa7e7a19ff987b7723aed863b9c478a2c91"
+            ],
+            "index": "pypi",
+            "version": "==0.0.1rc1"
+        },
+        "testcontainers-opensearch": {
+            "hashes": [
+                "sha256:0bdf270b5b7f53915832f7c31dd2bd3ffdc20b534ea6b32231cc7003049bd0e1"
+            ],
+            "index": "pypi",
+            "version": "==0.0.1rc1"
+        },
+        "tomli": {
+            "hashes": [
+                "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
+                "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
+            ],
+            "markers": "python_version < '3.11'",
+            "version": "==2.0.1"
+        },
         "typing-extensions": {
             "hashes": [
                 "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783",
@@ -1500,11 +1766,11 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84",
-                "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"
+                "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07",
+                "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"
             ],
-            "markers": "python_version >= '3.7'",
-            "version": "==2.0.7"
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
+            "version": "==1.26.18"
         },
         "wrapt": {
             "hashes": [
diff --git a/dbrepo-analyse-service/app.py b/dbrepo-analyse-service/app.py
index e917b10cfe0d292d7a98240406cddaec05581b6b..4d4c5cda88d2e5fe6c4a1c18551d4124d69c0ec8 100644
--- a/dbrepo-analyse-service/app.py
+++ b/dbrepo-analyse-service/app.py
@@ -1,59 +1,74 @@
-import os
+import logging
 from _csv import Error
 
-from flask import Flask, request, Response
 from json import dumps
-from determine_dt import determine_datatypes
-from determine_pk import determine_pk
-import logging
-from flasgger import Swagger
+from logging.config import dictConfig
+
+from flasgger import LazyJSONEncoder, Swagger
 from flasgger.utils import swag_from
-from flasgger import LazyJSONEncoder
+from flask import Flask, Response, abort, request
+from flask_sqlalchemy import SQLAlchemy
 from gevent.pywsgi import WSGIServer
+from opensearchpy import OpenSearch
 from prometheus_flask_exporter import PrometheusMetrics
+from requests import get
 
-log_level = os.getenv('LOG_LEVEL', 'INFO')
-
-logging.basicConfig(level=logging.getLevelName(log_level))
+from determine_dt import determine_datatypes
+from determine_pk import determine_pk
+from determine_stats import determine_stats
 
-from logging.config import dictConfig
+logging.basicConfig(level=logging.DEBUG)
 
-dictConfig({
-    'version': 1,
-    'formatters': {'default': {
-        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
-    }},
-    'handlers': {'wsgi': {
-        'class': 'logging.StreamHandler',
-        'stream': 'ext://flask.logging.wsgi_errors_stream',
-        'formatter': 'default'
-    }},
-    'root': {
-        'level': log_level,
-        'handlers': ['wsgi']
+dictConfig(
+    {
+        "version": 1,
+        "formatters": {
+            "default": {
+                "format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
+            }
+        },
+        "handlers": {
+            "wsgi": {
+                "class": "logging.StreamHandler",
+                "stream": "ext://flask.logging.wsgi_errors_stream",
+                "formatter": "default",
+            }
+        },
+        "root": {"level": "INFO", "handlers": ["wsgi"]},
     }
-})
+)
 
 app = Flask(__name__)
+
 metrics = PrometheusMetrics(app)
-metrics.info('app_info', 'Application info', version='1.3.0')
+metrics.info("app_info", "Application info", version="1.3.0")
 app.config["SWAGGER"] = {"openapi": "3.0.1", "title": "Swagger UI", "uiversion": 3}
 
+# ========================= DB Config  ========================= #
+app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
+app.config[
+    "SQLALCHEMY_DATABASE_URI"
+] = "mysql+pymysql://root:dbrepo@metadata-db:3306/fda"
+db = SQLAlchemy(app)
+
+# ========================= OS Config  ========================= #
+opensearch_client = OpenSearch(
+    hosts=["search-db"],
+    port=9200,
+    http_auth=("admin", "admin"),
+    use_ssl=False,
+)
+
+
 swagger_config = {
     "headers": [],
     "specs": [
         {
             "endpoint": "api-analyse",
             "route": "/api-analyse.json",
-            "rule_filter": lambda rule: rule.endpoint.startswith('analyze'),
-            "model_filter": lambda tag: True,  # all in
-        },
-        {
-            "endpoint": "api-mdb",
-            "route": "/api-mdb.json",
-            "rule_filter": lambda rule: rule.endpoint.startswith('mdb'),
+            "rule_filter": lambda rule: True,
             "model_filter": lambda tag: True,  # all in
-        },
+        }
     ],
     "static_url_path": "/flasgger_static",
     "swagger_ui": True,
@@ -65,100 +80,134 @@ template = {
     "info": {
         "title": "Database Repository Analyse Service API",
         "description": "Service that analyses data structures",
-        "version": "1.3.0",
+        "version": "$TAG",
         "contact": {
             "name": "Prof. Andreas Rauber",
-            "email": "andreas.rauber@tuwien.ac.at"
+            "email": "andreas.rauber@tuwien.ac.at",
         },
         "license": {
             "name": "Apache 2.0",
-            "url": "https://www.apache.org/licenses/LICENSE-2.0"
+            "url": "https://www.apache.org/licenses/LICENSE-2.0",
         },
     },
     "externalDocs": {
         "description": "Sourcecode Documentation",
-        "url": "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services"
+        "url": "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services",
     },
     "servers": [
-        {
-            "url": "http://localhost:5000",
-            "description": "Generated server url"
-        },
-        {
-            "url": "https://dbrepo2.tuwien.ac.at",
-            "description": "Sandbox"
-        }
-    ]
+        {"url": "http://localhost:5000", "description": "Generated server url"},
+        {"url": "https://test.dbrepo.tuwien.ac.at", "description": "Sandbox"},
+    ],
 }
 
 app.json_encoder = LazyJSONEncoder
 swagger = Swagger(app, config=swagger_config, template=template)
 
-@app.route('/health', methods=["GET"], endpoint='analyze_health')
-@swag_from('as-yml/health.yml')
+
+@app.route("/health", methods=["GET"], endpoint="analyze_health")
+@swag_from("as-yml/health.yml")
 def health():
-    logging.debug('endpoint health, body=%s', request)
+    logging.debug("endpoint health, body=%s", request)
     res = dumps({"status": "UP", "message": "Application is up and running"})
     return Response(res, mimetype="application/json"), 200
 
 
-@app.route('/api/analyse/determinedt', methods=["POST"], endpoint='analyze_determinedt')
-@swag_from('as-yml/determinedt.yml')
+@app.route("/api/analyse/determinedt", methods=["POST"], endpoint="analyze_determinedt")
+@swag_from("as-yml/determinedt.yml")
 def determinedt():
-    logging.debug('endpoint determine datatype, body=%s', request)
+    logging.debug("endpoint determine datatype, body=%s", request)
     input_json = request.get_json()
     try:
-        filename = str(input_json['filename'])
+        filename = str(input_json["filename"])
         enum = False
-        if 'enum' in input_json:
-            enum = bool(input_json['enum'])
+        if "enum" in input_json:
+            enum = bool(input_json["enum"])
             logging.info("Enum is present in payload and set to %s", enum)
         enum_tol = 0.001
-        if 'enum_tol' in input_json:
-            enum_tol = float(input_json['enum_tol'])
-            logging.info("Enum toleration is present in payload and set to %s", enum_tol)
+        if "enum_tol" in input_json:
+            enum_tol = float(input_json["enum_tol"])
+            logging.info(
+                "Enum toleration is present in payload and set to %s", enum_tol
+            )
         separator = None
-        if 'separator' in input_json:
-            separator = str(input_json['separator'])
+        if "separator" in input_json:
+            separator = str(input_json["separator"])
             logging.info("Seperator is present in payload and set to %s", separator)
         res = determine_datatypes(filename, enum, enum_tol, separator)
-        logging.debug('determine datatype resulted in datatypes %s', res)
+        logging.debug("determine datatype resulted in datatypes %s", res)
         return Response(res, mimetype="application/json"), 200
     except OSError as e:
-        logging.error('Failed to determine data types: %s', e)
+        logging.error("Failed to determine data types: %s", e)
         res = dumps({"success": False, "message": str(e)})
         return Response(res, mimetype="application/json"), 409
     except Error as e:
-        logging.error('Failed to determine separator %s', e)
+        logging.error("Failed to determine separator %s", e)
         res = dumps({"success": False, "message": str(e)})
         return Response(res, mimetype="application/json"), 422
     except Exception as e:
-        logging.error('Failed to determine data types: %s', e)
+        logging.error("Failed to determine data types: %s", e)
         res = dumps({"success": False, "message": str(e)})
         return Response(res, mimetype="application/json"), 500
 
 
-@app.route('/api/analyse/determinepk', methods=["POST"], endpoint='analyze_determinepk')
-@swag_from('as-yml/determinepk.yml')
+@app.route("/api/analyse/determinepk", methods=["POST"], endpoint="analyze_determinepk")
+@swag_from("as-yml/determinepk.yml")
 def determinepk():
-    logging.debug('endpoint determine primary key, body=%s', request)
+    logging.debug("endpoint determine primary key, body=%s", request)
     input_json = request.get_json()
     try:
-        filepath = str(input_json['filepath'])
-        seperator = ','
-        if 'seperator' in input_json:
-            seperator = str(input_json['seperator'])
+        filepath = str(input_json["filepath"])
+        seperator = ","
+        if "seperator" in input_json:
+            seperator = str(input_json["seperator"])
         res = determine_pk(filepath, seperator)
-        logging.debug('determined list of primary keys: %s', res)
+        logging.debug("determined list of primary keys: %s", res)
         return Response(res, mimetype="application/json"), 200
     except Exception as e:
-        logging.error('Failed to determine primary key: %s', e)
+        logging.error("Failed to determine primary key: %s", e)
         res = dumps({"success": False, "message": str(e)})
         return Response(res, mimetype="application/json"), 500
 
 
+@app.route("/api/analyse/determinestats", methods=["POST"], endpoint="analyse_determinestats")
+@swag_from("as-yml/determine_stats.yml")
+def determinestats():
+    logging.debug(
+        "endpoint to determine the statistical properties, body = %s", request
+    )
+    input_json = request.get_json()
+    if "filepath" not in input_json:
+        return {"message": "Missing 'filepath'", "status": 400}, 400
+
+    filepath = str(input_json["filepath"])
+    separator = str(input_json.get("separator", ","))
+    return determine_stats(filepath, separator)
+
+
+@app.route("/api/analyse/determinestat", methods=["POST"], endpoint="analyse_determinestat")
+@swag_from("as-yml/determine_stat.yml")
+def determinestat():
+    input_json = request.get_json()
+
+    if "database_id" not in input_json:
+        return {"message": "Missing 'database_id'", "status": 400}, 400
+    if "table_id" not in input_json:
+        return {"message": "Missing 'table_id'", "status": 400}, 400
+
+    res = determine_stats(
+        db,
+        opensearch_client,
+        database_id=input_json["database_id"],
+        table_id=input_json["table_id"],
+    )
+    if res:
+        return {"message": "Analysed statistical properties.", "status": 200}
+    else:
+        return {"message": "Database or table does not exist.", "status": 400}, 400
+
+
 rest_server_port = 5000
 
-if __name__ == '__main__':
-    http_server = WSGIServer(('', 5000), app)
+if __name__ == "__main__":
+    http_server = WSGIServer(("", 5000), app)
     http_server.serve_forever()
diff --git a/dbrepo-analyse-service/as-yml/determine_stat.yml b/dbrepo-analyse-service/as-yml/determine_stat.yml
new file mode 100644
index 0000000000000000000000000000000000000000..658e8af2b8cee2eb9b5b59239038b26f71e5f837
--- /dev/null
+++ b/dbrepo-analyse-service/as-yml/determine_stat.yml
@@ -0,0 +1,52 @@
+tags:
+  - analyse-endpoint
+summary: Determine statistics
+operationId: determinestat
+requestBody:
+  content:
+    application/json:
+      schema:
+        required:
+          - database_id
+          - table_id
+        type: object
+        properties:
+          database_id:
+            type: "integer"
+            example: 1
+          table_id:
+            type: "integer"
+            example: 1
+responses:
+  "200":
+    description: Determined statistics
+    content:
+      application/json:
+        schema:
+          required:
+            - message
+            - status
+          type: object
+          properties:
+            message:
+              type: "string"
+              example: "Analysed statistical properties"
+            status:
+              type: "integer"
+              example: "200"
+  400:
+    description: "Invalid input"
+    ontent:
+      application/json:
+        schema:
+          required:
+            - message
+            - status
+          type: object
+          properties:
+            message:
+              type: "string"
+              example: "Analysed statistical properties"
+            status:
+              type: "integer"
+              example: "200"
diff --git a/dbrepo-analyse-service/as-yml/determine_stats.yml b/dbrepo-analyse-service/as-yml/determine_stats.yml
new file mode 100644
index 0000000000000000000000000000000000000000..68b71dd527908c2920feffe6b584baad639cf01d
--- /dev/null
+++ b/dbrepo-analyse-service/as-yml/determine_stats.yml
@@ -0,0 +1,24 @@
+tags:
+  - analyse-endpoint
+summary: Determine statistics
+operationId: determinestats
+requestBody:
+  content:
+    application/json:
+      schema:
+        required:
+          - filepath
+          - separator
+        type: object
+        properties:
+          filepath:
+            type: "string"
+            example: "file.csv"
+          separator:
+            type: "string"
+            example: ","
+responses:
+  "200":
+    description: Determined statistics
+  "400":
+    description: "Invalid input"
diff --git a/dbrepo-analyse-service/as-yml/determinedt.yml b/dbrepo-analyse-service/as-yml/determinedt.yml
index 0c41bcead8eb2803deaa30be70514daa2d023b80..b7d554d23157f20c656461289d7d9858e7160506 100644
--- a/dbrepo-analyse-service/as-yml/determinedt.yml
+++ b/dbrepo-analyse-service/as-yml/determinedt.yml
@@ -1,30 +1,32 @@
+tags:
+  - analyse-endpoint
 summary: "Determine datatypes"
 description: "This is a simple API which returns the datatypes of a (path) csv file"
 consumes:
-- "application/json"
+  - "application/json"
 produces:
-- "application/json"
+  - "application/json"
 parameters:
-- in: "body"
-  name: "body"
-  description: "to-do description"
-  required: true
-  schema:
-    type: "object"
-    properties:
-      filename:
-        type: "string"
-        example : "sample.csv"
-      enum: 
-        type: "boolean"
-        example: true 
-      enum_tol: 
-        example: 0.1
-      separator: 
-        type: "string"
-        example: ","
+  - in: "body"
+    name: "body"
+    description: "to-do description"
+    required: true
+    schema:
+      type: "object"
+      properties:
+        filename:
+          type: "string"
+          example: "sample.csv"
+        enum:
+          type: "boolean"
+          example: true
+        enum_tol:
+          example: 0.1
+        separator:
+          type: "string"
+          example: ","
 responses:
-  200: 
+  200:
     description: "OK"
   405:
     description: "Invalid input"
\ No newline at end of file
diff --git a/dbrepo-analyse-service/as-yml/determinepk.yml b/dbrepo-analyse-service/as-yml/determinepk.yml
index 24446e939aa973472da7fc970adfbabc53dbe144..ca7253844dc37e197d7208094c0740a49a2340f6 100644
--- a/dbrepo-analyse-service/as-yml/determinepk.yml
+++ b/dbrepo-analyse-service/as-yml/determinepk.yml
@@ -1,25 +1,27 @@
+tags:
+  - analyse-endpoint
 summary: "Determine primary keys"
 description: "This is a simple API which returns the primary keys + ranking of a (path) csv file"
 consumes:
-- "application/json"
+  - "application/json"
 produces:
-- "application/json"
+  - "application/json"
 parameters:
-- in: "body"
-  name: "body"
-  description: "to-do description"
-  required: true
-  schema:
-    type: "object"
-    properties:
-      filepath:
-        type: "string"
-        example : "/data/testdt08.csv"
-      seperator: 
-        type: "string"
-        example: ","
+  - in: "body"
+    name: "body"
+    description: "to-do description"
+    required: true
+    schema:
+      type: "object"
+      properties:
+        filepath:
+          type: "string"
+          example: "/data/testdt08.csv"
+        seperator:
+          type: "string"
+          example: ","
 responses:
-  200: 
+  200:
     description: "OK"
   405:
     description: "Invalid input"
\ No newline at end of file
diff --git a/dbrepo-analyse-service/as-yml/health.yml b/dbrepo-analyse-service/as-yml/health.yml
index 9b34f955d1fb16158fce7c90525a269cf9a30355..a0f7ebcbacbd06a4dcaf262298456cf5b713cce8 100644
--- a/dbrepo-analyse-service/as-yml/health.yml
+++ b/dbrepo-analyse-service/as-yml/health.yml
@@ -1,21 +1,18 @@
+tags:
+  - health-endpoint
 summary: "Check if application is running"
 description: "This is a simple API which checks if the application is healthy"
 consumes:
-- "application/json"
+  - "application/json"
 produces:
-- "application/json"
-parameters:
-- in: "body"
-  name: "body"
-  description: "to-do description"
-  required: true
-  schema:
-    type: "object"
-    properties:
-      status:
-        type: "string" 
-        example : "UP"
+  - "application/json"
 responses:
-  200: 
+  200:
     description: "OK"
+    schema:
+      type: "object"
+      properties:
+        status:
+          type: "string"
+          example: "UP"
     
\ No newline at end of file
diff --git a/dbrepo-analyse-service/build.sh b/dbrepo-analyse-service/build.sh
index 4a0889a662ba1e9d3b704a86c85555c867dfecb9..8460f7b7f5d906a14a2f127ed1c86c3a5637a6de 100755
--- a/dbrepo-analyse-service/build.sh
+++ b/dbrepo-analyse-service/build.sh
@@ -1,4 +1,8 @@
 #!/bin/bash
+
+# needed for MariaDB Connector/C 
+apt update && apt install -y curl gcc libmariadb3 libmariadb-dev
+
 python3 -m venv ./dbrepo-analyse-service/venv
 source ./dbrepo-analyse-service/venv/bin/activate
 PIPENV_PIPFILE=./dbrepo-analyse-service/Pipfile pipenv install --dev
\ No newline at end of file
diff --git a/dbrepo-analyse-service/config.py b/dbrepo-analyse-service/config.py
index 5eb6e77b5dd5046130938348190b1d778e06d2cd..136153e23f736e0b3b21b523de4db274e3d63833 100644
--- a/dbrepo-analyse-service/config.py
+++ b/dbrepo-analyse-service/config.py
@@ -1,2 +1,2 @@
 class Config:
-    EUREKA_SERVER = os.environ.get('EUREKA_SERVER')
+    EUREKA_SERVER = os.environ.get("EUREKA_SERVER")
diff --git a/dbrepo-analyse-service/data/test_stats/test_stats_01.csv b/dbrepo-analyse-service/data/test_stats/test_stats_01.csv
new file mode 100644
index 0000000000000000000000000000000000000000..558d3c7e6d0cfe5f794f0bf76d842ebb948b9b66
--- /dev/null
+++ b/dbrepo-analyse-service/data/test_stats/test_stats_01.csv
@@ -0,0 +1,10 @@
+"col1","col2","col3","col4","col5"
+"2021-02-01 00:00:00","Zch_Stampfenbachstrasse",0.44,"150.25","10"
+"2021-04-13 00:00:00","Zch_Stampfenbachstrasse",4.88,"201.5","11"
+"2021-04-01 00:00:00","Zch_Stampfenbachstrasse",29.46,"180.75","12"
+"2021-01-01 00:00:00","Zch_Stampfenbachstrasse",9.85,"170.15","13"
+"2016-06-01 00:00:00","Zch_Stampfenbachstrasse",41.24,"160.35","14"
+"2015-01-01 00:00:00","Zch_Stampfenbachstrasse",8.51,"140.14","15"
+"2022-07-01 00:00:00","Zch_Stampfenbachstrasse",88.34,"130.45","16"
+"2022-01-01 00:00:00","Zch_Stampfenbachstrasse",75.72,"120.55","17"
+"2023-09-01 00:00:00","Zch_Schimmelstrasse",41.66,"110.295","18"
diff --git a/dbrepo-analyse-service/determine_dt.py b/dbrepo-analyse-service/determine_dt.py
index 76d8c850032a71b5c199081584dca4d440fa15dc..75d8c2290f8095b7ce1cd3368e3e003b16e15f20 100644
--- a/dbrepo-analyse-service/determine_dt.py
+++ b/dbrepo-analyse-service/determine_dt.py
@@ -9,8 +9,13 @@ import io
 from clients.s3_client import S3Client
 
 import messytables, pandas as pd
-from messytables import CSVTableSet, type_guess, \
-    headers_guess, headers_processor, offset_processor
+from messytables import (
+    CSVTableSet,
+    type_guess,
+    headers_guess,
+    headers_processor,
+    offset_processor,
+)
 
 
 def determine_datatypes(filename, enum=False, enum_tol=0.0001, separator=None) -> {}:
@@ -25,16 +30,16 @@ def determine_datatypes(filename, enum=False, enum_tol=0.0001, separator=None) -
         logging.warning(f'Failed to determine data types: file {filename} has empty body')
         return json.dumps({'columns': [], 'separator': ','})
     if separator is None:
-        logging.info('Attempt to guess separator for from first line')
+        logging.info("Attempt to guess separator for from first line")
         with io.BytesIO(stream.read()) as fh:
             line = next(fh)
-            dialect = csv.Sniffer().sniff(line.decode('utf-8'))
+            dialect = csv.Sniffer().sniff(line.decode("utf-8"))
             separator = dialect.delimiter
-            logging.info('determined separator: %s', separator)
+            logging.info("determined separator: %s", separator)
 
     # Load a file object:
     with io.BytesIO(stream.read()) as fh:
-        logging.info('Analysing corpus with separator: %s', separator)
+        logging.info("Analysing corpus with separator: %s", separator)
         table_set = CSVTableSet(fh, delimiter=separator)
 
         # A table set is a collection of tables:
@@ -58,18 +63,27 @@ def determine_datatypes(filename, enum=False, enum_tol=0.0001, separator=None) -
             elif type(types[i]) == messytables.types.IntegerType:
                 r[headers[i]] = "bigint"
             elif type(types[i]) == messytables.types.DateType:
-                if "%H" in types[i].format or "%M" in types[i].format or "%S" in types[i].format or "%Z" in types[
-                    i].format:
-                    r[headers[i]] = "timestamp"  # todo: guesses date format too, return it
+                if (
+                    "%H" in types[i].format
+                    or "%M" in types[i].format
+                    or "%S" in types[i].format
+                    or "%Z" in types[i].format
+                ):
+                    r[
+                        headers[i]
+                    ] = "timestamp"  # todo: guesses date format too, return it
                 else:
                     r[headers[i]] = "date"
-            elif type(types[i]) == messytables.types.DecimalType or type(types[i]) == messytables.types.FloatType:
+            elif (
+                type(types[i]) == messytables.types.DecimalType
+                or type(types[i]) == messytables.types.FloatType
+            ):
                 r[headers[i]] = "decimal"
             elif type(types[i]) == messytables.types.StringType:
                 r[headers[i]] = "varchar"
             else:
                 r[headers[i]] = "text"
         fh.close()
-        s = {'columns': r, 'separator': separator}
-        logging.info('Determined data types %s', s)
+        s = {"columns": r, "separator": separator}
+        logging.info("Determined data types %s", s)
     return json.dumps(s)
diff --git a/dbrepo-analyse-service/determine_pk.py b/dbrepo-analyse-service/determine_pk.py
index cc182052891d8bae34c5e8a57217f0843c5dfa1f..6187e0e913fe3338e22c32a7dfd9670c3c1bb16d 100644
--- a/dbrepo-analyse-service/determine_pk.py
+++ b/dbrepo-analyse-service/determine_pk.py
@@ -8,9 +8,9 @@ from determine_dt import determine_datatypes
 from clients.s3_client import S3Client
 
 
-def determine_pk(filename, separator=','):
+def determine_pk(filename, separator=","):
     dt = json.loads(determine_datatypes(filename=filename, separator=separator))
-    dt = {k.lower(): v for k, v in dt['columns'].items()}
+    dt = {k.lower(): v for k, v in dt["columns"].items()}
     # {k.lower(): v for k, v in dt['columns'].items() if v != 'Numeric'}
     colnames = dt.keys()
     colindex = list(range(0, len(colnames)))
@@ -27,35 +27,49 @@ def determine_pk(filename, separator=','):
         pk = {}
         j = 0
         k = 0
-        logging.info(f'File is {sizeInKb}kb, detection is precise')
+        logging.info(f"File is {sizeInKb}kb, detection is precise")
         for item in colnames:
-            if item == 'id':
+            if item == "id":
                 j = j + 1
                 pk.update({item: j})
                 colindex.remove(k)
             k = k + 1
         csvdata = pd.read_csv(stream, sep=separator)
         for i in colindex:
-            if pd.Series(csvdata.iloc[:, i]).is_unique and pd.Series(csvdata.iloc[:, i]).notnull().values.any():
+            if (
+                pd.Series(csvdata.iloc[:, i]).is_unique
+                and pd.Series(csvdata.iloc[:, i]).notnull().values.any()
+            ):
                 j = j + 1
                 pk.update({list(colnames)[i]: j})
     else:  # stochastic pk determination
         pk = {}
         j = 0
         k = 0
-        logging.info(f'File is {sizeInKb}kB (larger than threshold of 400kB), detection is stochastic')
+        logging.info(
+            f"File is {sizeInKb}kB (larger than threshold of 400kB), detection is stochastic"
+        )
         for item in colnames:
-            if item == 'id':
+            if item == "id":
                 j = j + 1
                 pk.update({item: j})
                 colindex.remove(k)
             k = k + 1
-        p = np.log10(int(response['ContentLength']))  # logarithmic scaled percentage of random inspected rows
-        csvdata = pd.read_csv(filepath_or_buffer=stream, sep=separator, header=0,
-                              skiprows=lambda k: k > 0 and random.random() > p)
+        p = np.log10(
+            int(response["ContentLength"])
+        )  # logarithmic scaled percentage of random inspected rows
+        csvdata = pd.read_csv(
+            filepath_or_buffer=stream,
+            sep=separator,
+            header=0,
+            skiprows=lambda k: k > 0 and random.random() > p,
+        )
         for i in colindex:
-            if pd.Series(csvdata.iloc[:, i]).is_unique and pd.Series(csvdata.iloc[:, i]).notnull().values.any():
+            if (
+                pd.Series(csvdata.iloc[:, i]).is_unique
+                and pd.Series(csvdata.iloc[:, i]).notnull().values.any()
+            ):
                 j = j + 1
                 pk.update({list(colnames)[i]: j})
-        logging.info(f'Determined primary key {pk}')
+        logging.info(f"Determined primary key {pk}")
     return json.dumps(pk)
diff --git a/dbrepo-analyse-service/determine_stats.py b/dbrepo-analyse-service/determine_stats.py
new file mode 100644
index 0000000000000000000000000000000000000000..50642ca52b3f3459df47b9a5f18ad473e4bc25fe
--- /dev/null
+++ b/dbrepo-analyse-service/determine_stats.py
@@ -0,0 +1,96 @@
+from pandas import DataFrame
+from sqlalchemy import create_engine, text
+
+
+def determine_stats(db, os, **kwargs):
+    database_id = kwargs.get("database_id")
+    table_id = kwargs.get("table_id")
+
+    with db.engine.connect() as connection:
+        database_name = connection.execute(
+            text(f"SELECT internal_name FROM mdb_databases WHERE id={database_id}")
+        ).fetchone()[0]
+        table_name = connection.execute(
+            text(f"SELECT internal_name FROM mdb_tables WHERE id={table_id}")
+        ).fetchone()[0]
+
+    if not database_name or not table_name:
+        return False
+
+    data_db_host = kwargs.get("data_db_host", "data-db")
+    data_db_port = kwargs.get("data_db_port", 3306)
+    # Generate data db connection on the fly: database name is varying according to the id given
+    data_db_uri = (
+        f"mysql+pymysql://root:dbrepo@{data_db_host}:{data_db_port}/{database_name}"
+    )
+    data_db_engine = create_engine(data_db_uri)
+
+    with data_db_engine.connect() as connection:
+        result = connection.execute(text(f"SELECT * FROM {table_name}"))
+        rows = result.fetchall()
+
+    df = DataFrame(rows, columns=result.keys())
+    for column, dtype in df.dtypes.items():
+        # Check if the column has a numeric data type
+        if dtype.kind in "fi":
+            # Calculate the statistics for the current column
+            column_stats = {
+                "val_min": df[column].min(),
+                "val_max": df[column].max(),
+                "mean": df[column].mean(),
+                "median": df[column].median(),
+                "std_dev": df[column].std(),
+            }
+
+            # Store statistical properties to the metadata db and index to OS
+            # TODO: use prepared statements to eliminate SQL injection
+            update_query = text(
+                f"""
+                UPDATE mdb_columns
+                SET
+                    val_min = '{column_stats["val_min"]}',
+                    val_max = '{column_stats["val_max"]}',
+                    mean    = '{column_stats["mean"]}',
+                    median  = '{column_stats["median"]}',
+                    std_dev = '{column_stats["std_dev"]}'
+                WHERE
+                    tID = '{table_id}' AND internal_name = '{column}'
+            """
+            )
+            # We need an extra select query to fetch the column ID for OpenSearch
+            select_query = text(
+                f"""
+                SELECT id
+                FROM mdb_columns
+                WHERE tID = '{table_id}' AND internal_name = '{column}'
+            """
+            )
+            with db.engine.begin() as connection:
+                connection.execute(update_query)
+                result = connection.execute(select_query)
+                column_id = result.fetchone()[0]
+                connection.commit()
+
+            # Fetch the existing document
+            existing_document = os.get(index="database", id=database_id)["_source"]
+
+            # Loop over OS response and append the statistics for each column
+            for tidx, table in enumerate(existing_document["tables"]):
+                if table["id"] == table_id:
+                    for cidx, column in enumerate(table["columns"]):
+                        if column["id"] == column_id:
+                            existing_document["tables"][tidx]["columns"][cidx].update(
+                                column_stats
+                            )
+                            # No need to keep searching if column id matches
+                            break
+
+            # Index and force refresh
+            os.index(
+                index="database",
+                id=database_id,
+                body=existing_document,
+                refresh=True,
+            )
+
+    return True
diff --git a/dbrepo-analyse-service/pywsgi.py b/dbrepo-analyse-service/pywsgi.py
index fb981f98d5c1a0a3ecb7fe54e370be61d0cdba87..7ef0e4b63ad98d080ea2169e08359a6bc2647213 100644
--- a/dbrepo-analyse-service/pywsgi.py
+++ b/dbrepo-analyse-service/pywsgi.py
@@ -1,9 +1,10 @@
 from gevent import monkey
+
 monkey.patch_all()
 
 import os
 from gevent.pywsgi import WSGIServer
 from app import app
 
-http_server = WSGIServer(('0.0.0.0', int(os.environ['PORT_APP'])), app)
+http_server = WSGIServer(("0.0.0.0", int(os.environ["PORT_APP"])), app)
 http_server.serve_forever()
diff --git a/dbrepo-analyse-service/test/conftest.py b/dbrepo-analyse-service/test/conftest.py
index c062a1b9d4a57c1eeb9da77faae0a023fe2a419c..50a2e3ab832e01d1cad63629f3b381677a295c71 100644
--- a/dbrepo-analyse-service/test/conftest.py
+++ b/dbrepo-analyse-service/test/conftest.py
@@ -2,9 +2,12 @@ import os
 
 import pytest
 import logging
+import json
 
 from minio.deleteobjects import DeleteObject
 from testcontainers.minio import MinioContainer
+from testcontainers.mysql import MySqlContainer
+from testcontainers.opensearch import OpenSearchContainer
 
 
 @pytest.fixture(scope="session")
@@ -19,13 +22,18 @@ def session(request):
     logging.debug("[fixture] starting container")
     container.start()
     # set the environment for the client
-    endpoint = 'http://' + container.get_container_host_ip() + ':' + container.get_exposed_port(9000)
-    os.environ['S3_STORAGE_ENDPOINT'] = endpoint
+    endpoint = (
+        "http://"
+        + container.get_container_host_ip()
+        + ":"
+        + container.get_exposed_port(9000)
+    )
+    os.environ["S3_STORAGE_ENDPOINT"] = endpoint
     client = container.get_client()
     # create buckets
-    logging.debug('[fixture] make buckets dbrepo-upload, dbrepo-download')
-    client.make_bucket('dbrepo-upload')
-    client.make_bucket('dbrepo-download')
+    logging.debug("[fixture] make buckets dbrepo-upload, dbrepo-download")
+    client.make_bucket("dbrepo-upload")
+    client.make_bucket("dbrepo-download")
 
     # destructor
     def stop_minio():
@@ -48,7 +56,92 @@ def cleanup(request, session):
         objects = []
         for obj in session.get_client().list_objects(bucket):
             objects.append(DeleteObject(obj.object_name))
-        logging.info(f'request to remove objects {objects}')
+        logging.info(f"request to remove objects {objects}")
         errors = session.get_client().remove_objects(bucket, objects)
         for error in errors:
-            raise ConnectionError(f'Failed to delete object with key {error.object_name} of bucket {bucket}')
+            raise ConnectionError(
+                f"Failed to delete object with key {error.object_name} of bucket {bucket}"
+            )
+
+
+@pytest.fixture(scope="function")
+def metadata_db_container():
+    metadata_db = MySqlContainer(
+        "bitnami/mariadb:10.5",
+        MYSQL_USER="root",
+        MYSQL_PASSWORD="dbrepo",
+        MYSQL_DATABASE="fda",
+    )
+    metadata_db._name = "metadata-db-test"
+    metadata_db.ports = {"3306": 33060}
+    metadata_db.env = {
+        "MYSQL_USER": metadata_db.MYSQL_USER,
+        "MARIADB_ROOT_PASSWORD": metadata_db.MYSQL_ROOT_PASSWORD,
+        "MARIADB_DATABASE": metadata_db.MYSQL_DATABASE,
+    }
+    # volume that mounts db schema from metadata-db
+    metadata_db.with_volume_mapping(
+        os.path.abspath("../dbrepo-metadata-db/setup-schema.sql"), "/schema.sql"
+    )
+    # volume for script that initializes schema and inserts test values
+    metadata_db.with_volume_mapping(
+        os.path.abspath("./test/init-db.sh"),
+        "/docker-entrypoint-initdb.d/init-db.sh",
+    )
+
+    # validate creation of schema and data
+    with metadata_db:
+        print(
+            metadata_db.exec(
+                f"mariadb -u{metadata_db.MYSQL_USER} -p{metadata_db.MYSQL_ROOT_PASSWORD} fda -e 'SELECT * FROM mdb_databases;'"
+            )
+        )
+        yield metadata_db
+
+
+@pytest.fixture(scope="function")
+def data_db_container():
+    data_db = MySqlContainer(
+        "bitnami/mariadb:10.5",
+        MYSQL_USER="root",
+        MYSQL_PASSWORD="dbrepo",
+    )
+    data_db._name = "data-db-test"
+    data_db.ports = {"3306": 33061}
+    data_db.env = {
+        "MYSQL_USER": data_db.MYSQL_USER,
+        "MARIADB_ROOT_PASSWORD": data_db.MYSQL_ROOT_PASSWORD,
+    }
+    # volume that mounts csv for data import
+    data_db.with_volume_mapping(
+        os.path.abspath("./data/test_stats/test_stats_01.csv"), "/test_stats_01.csv"
+    )
+    # volume for script to create a test data db and import values from a csv
+    data_db.with_volume_mapping(
+        os.path.abspath("./test/init-data-db.sh"),
+        "/docker-entrypoint-initdb.d/init-data-db.sh",
+    )
+
+    with data_db:
+        yield data_db
+
+
+@pytest.fixture(scope="function")
+def opensearch_container():
+    os_container = OpenSearchContainer("opensearchproject/opensearch:2.10.0")
+
+    with os_container:
+        client = os_container.get_client()
+        index_mapping_path = os.path.join(
+            "..", "dbrepo-search-db", "init", "indices", "database.json"
+        )
+        with open(index_mapping_path, "r") as file:
+            mapping = json.load(file)
+            client.indices.create(index="database", body=mapping)
+
+        yield os_container
+
+
+@pytest.fixture(scope="function")
+def all_containers(opensearch_container, metadata_db_container, data_db_container):
+    yield opensearch_container, metadata_db_container, data_db_container
diff --git a/dbrepo-analyse-service/test/init-data-db.sh b/dbrepo-analyse-service/test/init-data-db.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2ba035d6ed3bf3f07cc01935016d18d142841bb4
--- /dev/null
+++ b/dbrepo-analyse-service/test/init-data-db.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Script to initialize a test data db according to a csv file
+# Intented to be run from pytest inside a mysql/mariadb container
+
+mysql -u"$MYSQL_USER" -p"$MYSQL_ROOT_PASSWORD" <<EOSQL
+CREATE DATABASE internal1;
+
+USE internal1;
+
+CREATE TABLE table1 (
+    col1 DATETIME,
+    col2 VARCHAR(255),
+    col3 FLOAT,
+    col4 FLOAT,
+    col5 INT
+);
+
+LOAD DATA INFILE '/test_stats_01.csv'
+INTO TABLE table1
+FIELDS TERMINATED BY ',' ENCLOSED BY '"'
+LINES TERMINATED BY '\\n'
+IGNORE 1 LINES
+(col1, col2, col3, col4, col5);
+EOSQL
diff --git a/dbrepo-analyse-service/test/init-db.sh b/dbrepo-analyse-service/test/init-db.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c8a8411357f3d6dc83a228c6cd81aa88dad162b7
--- /dev/null
+++ b/dbrepo-analyse-service/test/init-db.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Script to initialize db schema and insert test values
+# Intented to be run from pytest inside a mysql/mariadb docker container
+
+mysql -u"$MYSQL_USER" -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" <<EOSQL
+source /schema.sql
+
+INSERT INTO mdb_users (id, username, firstname, lastname, email, orcid, affiliation, mariadb_password, theme_dark)
+VALUES
+    ('1', 'user1', 'John', 'Doe', 'user1@example.com', '0000-0001-1234-5678', 'University A', 'password1', TRUE);
+
+INSERT INTO mdb_images (name, version, default_port, dialect, driver_class, jdbc_method, created, last_modified)
+VALUES
+    ('Image1', '1.0', 5432, 'postgresql', 'org.postgresql.Driver', 'jdbc:postgresql', NOW(), NOW()),
+    ('Image2', '2.0', 3306, 'mysql', 'com.mysql.jdbc.Driver', 'jdbc:mysql', NOW(), NOW());
+
+INSERT INTO mdb_containers (internal_name, name, host, port, ui_host, ui_port, ui_additional_flags, sidecar_host, sidecar_port, image_id, created, last_modified, privileged_username, privileged_password)
+VALUES
+    ('container1', 'Container1', 'localhost', 3306, 'localhost', 3306, NULL, 'localhost', 3305, 1, NOW(), NOW(), 'admin', 'admin'),
+    ('container2', 'Container2', 'localhost', 3307, 'localhost', 3307, NULL, 'localhost', 3306, 2, NOW(), NOW(), 'admin', 'admin');
+
+INSERT INTO mdb_databases (cid, name, internal_name, exchange_name, description, engine, is_public, created_by, owned_by, contact_person, created, last_modified)
+VALUES
+    (1, 'Database1', 'internal1', 'Exchange1', 'Description1', 'InnoDB', TRUE, NULL, NULL, NULL, NOW(), NOW()),
+    (2, 'Database2', 'internal2', 'Exchange2', 'Description2', 'MyISAM', FALSE, NULL, NULL, NULL, NOW(), NOW());
+
+INSERT INTO mdb_tables (tDBID, internal_name, queue_name, routing_key, tName, tDescription, num_rows, data_length, max_data_length, avg_row_length, \`separator\`, quote, element_null, skip_lines, element_true, element_false, Version, created, versioned, created_by, owned_by, last_modified)
+VALUES
+    (1, 'table1', 'Queue1', 'RoutingKey1', 'TableName1', 'TableDescription1', 5, 9, 15, 3, ',', '"', NULL, 2, TRUE, FALSE, '1.0', NOW(), TRUE, '1', '1', NOW()),
+    (1, 'table2', 'Queue2', 'RoutingKey2', 'TableName2', 'TableDescription2', 0, 0, 0, 0, ',', "'", 'NA', 0, '1', '0', '2.0', NOW(), TRUE, '1', '1', NOW()),
+    (2, 'table3', 'Queue3', 'RoutingKey3', 'TableName3', 'TableDescription3', 0, 0, 0, 0, ',', '"', 'EMPTY', 5, 'yes', 'no', '1.0', NOW(), TRUE, '1', '1', NOW());
+
+INSERT INTO mdb_columns (tID, dfID, cName, internal_name, alias, Datatype, length, ordinal_position, is_primary_key, index_length, size, d, auto_generated, is_null_allowed, val_min, val_max, mean, median, std_dev, created, last_modified)
+VALUES
+    (1, NULL, 'Column1', 'col1', 'Alias1', 'DATETIME', 255, 1, TRUE, NULL, NULL, NULL, FALSE, TRUE, NULL, NULL, NULL, NULL, NULL, NOW(), NOW()),
+    (1, NULL, 'Column2', 'col2', 'Alias2', 'VARCHAR', NULL, 2, FALSE, NULL, NULL, NULL, FALSE, TRUE, NULL, NULL, NULL, NULL, NULL, NOW(), NOW()),
+    (1, NULL, 'Column3', 'col3', 'Alias3', 'FLOAT', 10, 3, FALSE, NULL, NULL, 2, FALSE, TRUE, 0, 100, NULL, NULL, NULL, NOW(), NOW()),
+    (1, NULL, 'Column4', 'col4', 'Alias4', 'FLOAT', 10, 3, FALSE, NULL, NULL, 2, FALSE, TRUE, 0, 100, NULL, NULL, NULL, NOW(), NOW()),
+    (1, NULL, 'Column5', 'col5', 'Alias5', 'INT', 10, 3, FALSE, NULL, NULL, 2, FALSE, TRUE, 0, 100, NULL, NULL, NULL, NOW(), NOW());
+EOSQL
diff --git a/dbrepo-analyse-service/test/test_determine_dt.py b/dbrepo-analyse-service/test/test_determine_dt.py
index 2acf97aacd300b57bf6e9a5a6a214b7ed9b4bd75..199c94fe91186d44b1cd81e0375d1cf8dc84224d 100644
--- a/dbrepo-analyse-service/test/test_determine_dt.py
+++ b/dbrepo-analyse-service/test/test_determine_dt.py
@@ -15,20 +15,19 @@ from determine_dt import determine_datatypes
 
 
 class DetermineDatatypesTest(unittest.TestCase):
-
     # @Test
     def test_determine_datatypesDateTime_succeeds(self):
         exp = {
-            'columns': {
-                'Datum': 'timestamp',
-                'Standort': 'varchar',
-                'Parameter': 'varchar',
-                'Intervall': 'varchar',
-                'Einheit': 'varchar',
-                'Wert': 'decimal',
-                'Status': 'varchar'
+            "columns": {
+                "Datum": "timestamp",
+                "Standort": "varchar",
+                "Parameter": "varchar",
+                "Intervall": "varchar",
+                "Einheit": "varchar",
+                "Wert": "decimal",
+                "Status": "varchar",
             },
-            'separator': ','
+            "separator": ",",
         }
 
         # mock
@@ -41,16 +40,16 @@ class DetermineDatatypesTest(unittest.TestCase):
     # @Test
     def test_determine_datatypesDateTimeWithTimezone_succeeds(self):
         exp = {
-            'columns': {
-                'Datum': 'varchar',
-                'Standort': 'varchar',
-                'Parameter': 'varchar',
-                'Intervall': 'varchar',
-                'Einheit': 'varchar',
-                'Wert': 'decimal',
-                'Status': 'varchar'
+            "columns": {
+                "Datum": "varchar",
+                "Standort": "varchar",
+                "Parameter": "varchar",
+                "Intervall": "varchar",
+                "Einheit": "varchar",
+                "Wert": "decimal",
+                "Status": "varchar",
             },
-            'separator': ','
+            "separator": ",",
         }
 
         # mock
@@ -63,16 +62,16 @@ class DetermineDatatypesTest(unittest.TestCase):
     # @Test
     def test_determine_datatypesDateTimeWithT_succeeds(self):
         exp = {
-            'columns': {
-                'Datum': 'timestamp',
-                'Standort': 'varchar',
-                'Parameter': 'varchar',
-                'Intervall': 'varchar',
-                'Einheit': 'varchar',
-                'Wert': 'decimal',
-                'Status': 'varchar'
+            "columns": {
+                "Datum": "timestamp",
+                "Standort": "varchar",
+                "Parameter": "varchar",
+                "Intervall": "varchar",
+                "Einheit": "varchar",
+                "Wert": "decimal",
+                "Status": "varchar",
             },
-            'separator': ','
+            "separator": ",",
         }
 
         # mock
@@ -85,16 +84,16 @@ class DetermineDatatypesTest(unittest.TestCase):
     # @Test
     def test_determine_datatypes_succeeds(self):
         exp = {
-            'columns': {
-                'int': 'bigint',
-                'float': 'decimal',
-                'string': 'varchar',
-                'boolean': 'bool',
-                'date': 'date',
-                'time': 'timestamp',
-                'enum': 'varchar'  # currently not used
+            "columns": {
+                "int": "bigint",
+                "float": "decimal",
+                "string": "varchar",
+                "boolean": "bool",
+                "date": "date",
+                "time": "timestamp",
+                "enum": "varchar",  # currently not used
             },
-            'separator': ','
+            "separator": ",",
         }
 
         # mock
@@ -106,62 +105,57 @@ class DetermineDatatypesTest(unittest.TestCase):
 
     # @Test
     def test_determine_datatypes_fileDoesNotExist_fails(self):
-
         # test
         try:
             response = determine_datatypes("i_do_not_exist.csv")
         except ClientError as e:
             pass  # s3.head operation
         except Exception:
-            self.fail('unexpected exception raised')
+            self.fail("unexpected exception raised")
         else:
-            self.fail('ExpectedException not raised')
+            self.fail("ExpectedException not raised")
 
     # @Test
     def test_determine_datatypes_fileEmpty_succeeds(self):
-
         # mock
         S3Client().upload_file("empty.csv", './data/test_dt/', 'dbrepo-upload')
 
         # test
         response = determine_datatypes("empty.csv")
         data = json.loads(response)
-        self.assertEqual(data['columns'], [])
-        self.assertEqual(data['separator'], ',')
+        self.assertEqual(data["columns"], [])
+        self.assertEqual(data["separator"], ",")
 
     # @Test
     def test_determine_datatypes_separatorSemicolon_succeeds(self):
-
         # mock
         S3Client().upload_file("separator.csv", './data/test_dt/', 'dbrepo-upload')
 
         # test
         response = determine_datatypes(filename="separator.csv", separator=";")
         data = json.loads(response)
-        self.assertEqual(data['separator'], ';')
+        self.assertEqual(data["separator"], ";")
 
     # @Test
     def test_determine_datatypes_separatorGuess_succeeds(self):
-
         # mock
         S3Client().upload_file("separator.csv", './data/test_dt/', 'dbrepo-upload')
 
         # test
         response = determine_datatypes(filename="separator.csv")
         data = json.loads(response)
-        self.assertEqual(data['separator'], ';')
+        self.assertEqual(data["separator"], ";")
 
     # @Test
     def test_determine_datatypes_separatorGuessLargeDataset_succeeds(self):
-
         # mock
         S3Client().upload_file("large.csv", './data/test_dt/', 'dbrepo-upload')
 
         # test
         response = determine_datatypes(filename="large.csv")
         data = json.loads(response)
-        self.assertEqual(data['separator'], ',')
+        self.assertEqual(data["separator"], ",")
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     unittest.main()
diff --git a/dbrepo-analyse-service/test/test_determine_pk.py b/dbrepo-analyse-service/test/test_determine_pk.py
index 4fffda96c524d551efe3d8728713547fa7179a8f..d6f1314a2bb1b56bed76a56aa4d18eff3a514a6e 100644
--- a/dbrepo-analyse-service/test/test_determine_pk.py
+++ b/dbrepo-analyse-service/test/test_determine_pk.py
@@ -14,7 +14,6 @@ from clients.s3_client import S3Client
 from determine_pk import determine_pk
 
 class DeterminePrimaryKeyTest(unittest.TestCase):
-
     # @Test
     def test_determine_pk_largeFileIdFirst_succeeds(self):
 
diff --git a/dbrepo-analyse-service/test/test_determine_stats.py b/dbrepo-analyse-service/test/test_determine_stats.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d82ffedbe65f2f366feac4c317c4b3863f5aa79
--- /dev/null
+++ b/dbrepo-analyse-service/test/test_determine_stats.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Jan 17 17:13:25 2024
+
+@author: Sotiris Tsepelakis
+"""
+
+from opensearchpy import OpenSearch
+from sqlalchemy import create_engine
+
+from determine_stats import determine_stats
+
+
+class TestDetermineStatisticalProperties:
+    # @Test
+    def test_determine_statistical_properties_succeeds(self, all_containers):
+        # mock request
+        payload = {
+            "database_id": 1,
+            "table_id": 1,
+            "data_db_host": "localhost",
+            "data_db_port": 33061,
+        }
+
+        os_host = all_containers[0].get_container_host_ip()
+        os_port = all_containers[0].get_exposed_port("9200/tcp")
+        os = OpenSearch([{"host": os_host, "port": os_port}])
+
+        metadata_db_host = all_containers[1].get_container_host_ip()
+        metadata_db_port = all_containers[1].get_exposed_port(3306)
+        db = create_engine(
+            f"mysql+pymysql://root:dbrepo@{metadata_db_host}:{metadata_db_port}/fda"
+        )
+
+        # index a test document
+        all_containers[0].get_client().index(
+            index="database",
+            id="1",
+            body={
+                "id": 1,
+                "name": "testdb",
+                "exchange_name": "dbrepo",
+                "internal_name": "testdb_ygvq",
+                "tables": [
+                    {
+                        "id": 1,
+                        "database_id": 1,
+                        "name": "mytable",
+                        "internal_name": "mytable",
+                        "queue_name": "dbrepo",
+                        "routing_key": "dbrepo.testdb_ygvq.mytable",
+                        "columns": [
+                            {
+                                "id": 1,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "id",
+                                "internal_name": "id",
+                                "auto_generated": True,
+                                "is_primary_key": True,
+                                "column_type": "BIGINT",
+                                "is_public": True,
+                                "is_null_allowed": False,
+                                "enums": [],
+                                "sets": [],
+                            },
+                            {
+                                "id": 2,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "col1",
+                                "internal_name": "col1",
+                                "date_format": {
+                                    "id": 2,
+                                    "database_format": "%Y-%c-%d %H:%i:%S",
+                                    "unix_format": "yyyy-MM-dd HH:mm:ss",
+                                    "has_time": True,
+                                    "created_at": "2024-01-17T13:22:26.000Z",
+                                },
+                                "auto_generated": False,
+                                "is_primary_key": False,
+                                "column_type": "DATETIME",
+                                "is_public": True,
+                                "is_null_allowed": True,
+                                "enums": [],
+                                "sets": [],
+                            },
+                            {
+                                "id": 3,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "col2",
+                                "internal_name": "col2",
+                                "auto_generated": False,
+                                "is_primary_key": False,
+                                "column_type": "VARCHAR",
+                                "size": 255,
+                                "is_public": True,
+                                "is_null_allowed": True,
+                                "enums": [],
+                                "sets": [],
+                            },
+                            {
+                                "id": 4,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "col3",
+                                "internal_name": "col3",
+                                "auto_generated": True,
+                                "is_primary_key": True,
+                                "column_type": "FLOAT",
+                                "size": 24,
+                                "is_public": True,
+                                "is_null_allowed": True,
+                                "enums": [],
+                                "sets": [],
+                            },
+                            {
+                                "id": 5,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "col4",
+                                "internal_name": "col4",
+                                "auto_generated": False,
+                                "is_primary_key": False,
+                                "column_type": "FLOAT",
+                                "size": 24,
+                                "is_public": True,
+                                "is_null_allowed": True,
+                                "enums": [],
+                                "sets": [],
+                            },
+                            {
+                                "id": 6,
+                                "database_id": 1,
+                                "table_id": 1,
+                                "name": "col5",
+                                "internal_name": "col5",
+                                "auto_generated": False,
+                                "is_primary_key": False,
+                                "column_type": "INT",
+                                "size": 255,
+                                "is_public": True,
+                                "is_null_allowed": True,
+                                "enums": [],
+                                "sets": [],
+                            },
+                        ],
+                        "constraints": {"uniques": [], "foreign_keys": []},
+                    }
+                ],
+            },
+        )
+        # test
+        response = determine_stats(db, os, **payload)
+        assert response
diff --git a/dbrepo-authentication-service/dbrepo-realm.json b/dbrepo-authentication-service/dbrepo-realm.json
index d3cadb4e7168edaff547f13e7437be41155a7a2d..c861fbd662986b4363f6a08dbe48bdc5333592d0 100644
--- a/dbrepo-authentication-service/dbrepo-realm.json
+++ b/dbrepo-authentication-service/dbrepo-realm.json
@@ -5,10 +5,10 @@
   "defaultSignatureAlgorithm" : "RS256",
   "revokeRefreshToken" : false,
   "refreshTokenMaxReuse" : 1,
-  "accessTokenLifespan" : 86400,
+  "accessTokenLifespan" : 900,
   "accessTokenLifespanForImplicitFlow" : 900,
-  "ssoSessionIdleTimeout" : 1800,
-  "ssoSessionMaxLifespan" : 36000,
+  "ssoSessionIdleTimeout" : 864000,
+  "ssoSessionMaxLifespan" : 2592000,
   "ssoSessionIdleTimeoutRememberMe" : 0,
   "ssoSessionMaxLifespanRememberMe" : 0,
   "offlineSessionIdleTimeout" : 2592000,
@@ -1059,7 +1059,7 @@
   "otpPolicyLookAheadWindow" : 1,
   "otpPolicyPeriod" : 30,
   "otpPolicyCodeReusable" : false,
-  "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName" ],
+  "otpSupportedApplications" : [ "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName", "totpAppFreeOTPName" ],
   "webAuthnPolicyRpEntityName" : "keycloak",
   "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
   "webAuthnPolicyRpId" : "",
@@ -2009,6 +2009,23 @@
       "config" : {
         "allow-default-scopes" : [ "true" ]
       }
+    }, {
+      "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1",
+      "name" : "Trusted Hosts",
+      "providerId" : "trusted-hosts",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "host-sending-registration-request-must-match" : [ "true" ],
+        "client-uris-must-match" : [ "true" ]
+      }
+    }, {
+      "id" : "f565cb47-3bcf-4078-8f94-eb4179c375b8",
+      "name" : "Full Scope Disabled",
+      "providerId" : "scope",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
     }, {
       "id" : "0efa669d-1017-4b4a-82e1-c2eaf72de2c9",
       "name" : "Allowed Client Scopes",
@@ -2026,60 +2043,25 @@
       "subComponents" : { },
       "config" : { }
     }, {
-      "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979",
+      "id" : "104ec5a9-025b-4c44-8ac0-82d22887ca3e",
       "name" : "Allowed Protocol Mapper Types",
       "providerId" : "allowed-protocol-mappers",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : {
-        "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper" ]
-      }
-    }, {
-      "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1",
-      "name" : "Trusted Hosts",
-      "providerId" : "trusted-hosts",
-      "subType" : "anonymous",
+      "subType" : "authenticated",
       "subComponents" : { },
       "config" : {
-        "host-sending-registration-request-must-match" : [ "true" ],
-        "client-uris-must-match" : [ "true" ]
+        "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper" ]
       }
     }, {
-      "id" : "f565cb47-3bcf-4078-8f94-eb4179c375b8",
-      "name" : "Full Scope Disabled",
-      "providerId" : "scope",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : { }
-    }, {
-      "id" : "104ec5a9-025b-4c44-8ac0-82d22887ca3e",
+      "id" : "3ab11d74-5e76-408a-b85a-26bf8950f979",
       "name" : "Allowed Protocol Mapper Types",
       "providerId" : "allowed-protocol-mappers",
-      "subType" : "authenticated",
+      "subType" : "anonymous",
       "subComponents" : { },
       "config" : {
-        "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ]
+        "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper" ]
       }
     } ],
-    "org.keycloak.userprofile.UserProfileProvider" : [ {
-      "id" : "7970b87f-f28b-4085-8612-43281968f118",
-      "providerId" : "declarative-user-profile",
-      "subComponents" : { },
-      "config" : { }
-    } ],
     "org.keycloak.keys.KeyProvider" : [ {
-      "id" : "2f53ccf3-37b0-4d34-83e7-ed497499ee51",
-      "name" : "rsa-enc-generated",
-      "providerId" : "rsa-enc-generated",
-      "subComponents" : { },
-      "config" : {
-        "privateKey" : [ "MIIEowIBAAKCAQEA3b1tNLfcjFLUw9UShVDNf+ZD8sQqb4YBaIXcSJTX/zDQUPiCp176BBGI3s4VplDArnOW+LumozmKogeoHEnGEIDW8ovgK5uMU9tSA2p0qqGBUMOdR8YATTIfCJe7qGiiuGa3WZy3sQLM70SuRzx02YU8gvUcvl2Js4KyqAziOUX/w3Wa59H9jjGNUXYyqaPWJp73eHzbVYWySzyLG22mVlcUtBx5siL5T2/Xu0p9z4l7/bapwwmOVi1ZrcHjbEAwdGEiSMGI/uWqAF+r1BRpmJLR7HNXcL3eK4/56VYLaiwSejfyYeRFMITEn/UxGYhcXZ5xMUUCG0TxjBhLYpTBuwIDAQABAoIBAA4dwebcxkrH99Poa8+WkiE7JgaS9sahx9OBI2xwJANoIU2TpzGuNLQZ76uLgB+rPWZTD9Xm5a1iJjwOyQ9/937TzPCk91D0tpgcusRikb8jx/6TGB9acL4kBjYUVCCHr3BA2G75MKKGtJ2OMvAbCQSosZj+r2VDwYFEPUkV2jheE5JHSBkwyIRrus3JCwu8gu5fyCg9z8ljcxJxI5HIsi4v8Z21aCw/cLj7h5cMt44wCjQz4rOfYNBEFeHDtlfR1QtWKgjm4ZHHJbKrzf9b2kQXclziceEbSM0tYbROEXKi+s0Zc+z3HEG89vv0vfN400clmzzIAijKY6gg3pPRWdECgYEA+lnWYbSlXDMNYx6RBXm1RnlMUYIm4oy4/9ljgnoGJ6WCn3SjFkgaDtiKfGIG1BSB85r04pAPANgcWHf5tWDnq0ARvBVG0BX2bKd++7B3D4d3CRYKCwm88SslJXv9dfHVhq4+zViFPiUWwT20A72jCuUCvL88y5fh/YBecfdh+jECgYEA4r5RD0NB9dMaeg5/jk/GEHIo4Z9KLc6FrSoOFo2xFkPOy1sgDpDOiNtypuWvniO7k7Ose3DS3hlfTMsKzIW/CgQJ20+Y4cvBWDaOsRxfjj7w3d+jH5OSJdKKSzTrgLKc9ZhlRzVXy0J0hipIA6HG5kdVdLXmh85ITmf1CbJhE6sCgYBjPVeBNbXTHZ2x6/z62aslO5IoQVqetb/kE82hfDOSZcao5Ph9Lam+ttH2ynkAevykj4mBgi+gWwqpey2uW7KaLPSaxShj9kDQA3mP1fzsV/u0y1rB02Nlin/YIxVvOqU1FT9p8SwoXVVu1sHUNck62VtDbN9xqUx5S/ikXrclEQKBgQCoTssOwEcK+Vty9KYcdfy4onTUHZBLdjxl8Iyqkxy7QTQUYRznkvesQPDXEDGO+kk3dyx2KKZt9Hl4IFNww2quPZcvcuMx4DQxjbXXpA8OIIxcta95NepLJwA+mRai3nKCH1A2TlNP7pFeMa5o+8IPly3Ix2lKr4Wepa4PN5i1pwKBgCZ1QP6XAOERl9NznNmU0rXVcvYNP4PIIfQWfvGsldZ4QKkmjjAGiS0/oYqdWs+UDRZyCRChaVjDXO9fk0PEG5OGKAj9nyiYCT/M8xtJ3UeP5ffZZvJ/vnye3QdDIo1e38ZzsWwJHmLYw7fRqY9W5Vxo0Vsy22U3CJY70KTxVdTy" ],
-        "keyUse" : [ "ENC" ],
-        "certificate" : [ "MIICmzCCAYMCBgGG3GWycDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdvW00t9yMUtTD1RKFUM1/5kPyxCpvhgFohdxIlNf/MNBQ+IKnXvoEEYjezhWmUMCuc5b4u6ajOYqiB6gcScYQgNbyi+Arm4xT21IDanSqoYFQw51HxgBNMh8Il7uoaKK4ZrdZnLexAszvRK5HPHTZhTyC9Ry+XYmzgrKoDOI5Rf/DdZrn0f2OMY1RdjKpo9Ymnvd4fNtVhbJLPIsbbaZWVxS0HHmyIvlPb9e7Sn3PiXv9tqnDCY5WLVmtweNsQDB0YSJIwYj+5aoAX6vUFGmYktHsc1dwvd4rj/npVgtqLBJ6N/Jh5EUwhMSf9TEZiFxdnnExRQIbRPGMGEtilMG7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK3kQ1VkQrzvSWvmXmazmNoA1ZiPzRDs1XhGUWxgsxzgPylr3dGBuqQbKvgnLUBQLSqlJHpI4fZflHswu1qrvVZYtekPcGef4WhcKAu2i1RwxrKa6RJQ1tRbrLuVYCzPv5p/DWgltWVn88aoLnqQn0SK/0PB/o4a4Cm7Kq2ZzCr1dACBr06LvOHsc7249OySmbG4HH+pLK6jVURhZ9VaObqAHe2FJBVVoIzURbdiRRURqumrIvbnpeaU1aFyg6ED5wTnXvmMPmVPt9F79mcB33bASO5wyu00X8t1hyN2Show2l2vxLACGUzVkTQt15s7uDLKE7qLmKSR3EuSGXWv3wA=" ],
-        "priority" : [ "100" ],
-        "algorithm" : [ "RSA-OAEP" ]
-      }
-    }, {
       "id" : "28ca0b6d-b2e2-4785-b04b-2391e6344e30",
       "name" : "aes-generated",
       "providerId" : "aes-generated",
@@ -2100,6 +2082,18 @@
         "priority" : [ "100" ],
         "algorithm" : [ "HS256" ]
       }
+    }, {
+      "id" : "2f53ccf3-37b0-4d34-83e7-ed497499ee51",
+      "name" : "rsa-enc-generated",
+      "providerId" : "rsa-enc-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEowIBAAKCAQEA3b1tNLfcjFLUw9UShVDNf+ZD8sQqb4YBaIXcSJTX/zDQUPiCp176BBGI3s4VplDArnOW+LumozmKogeoHEnGEIDW8ovgK5uMU9tSA2p0qqGBUMOdR8YATTIfCJe7qGiiuGa3WZy3sQLM70SuRzx02YU8gvUcvl2Js4KyqAziOUX/w3Wa59H9jjGNUXYyqaPWJp73eHzbVYWySzyLG22mVlcUtBx5siL5T2/Xu0p9z4l7/bapwwmOVi1ZrcHjbEAwdGEiSMGI/uWqAF+r1BRpmJLR7HNXcL3eK4/56VYLaiwSejfyYeRFMITEn/UxGYhcXZ5xMUUCG0TxjBhLYpTBuwIDAQABAoIBAA4dwebcxkrH99Poa8+WkiE7JgaS9sahx9OBI2xwJANoIU2TpzGuNLQZ76uLgB+rPWZTD9Xm5a1iJjwOyQ9/937TzPCk91D0tpgcusRikb8jx/6TGB9acL4kBjYUVCCHr3BA2G75MKKGtJ2OMvAbCQSosZj+r2VDwYFEPUkV2jheE5JHSBkwyIRrus3JCwu8gu5fyCg9z8ljcxJxI5HIsi4v8Z21aCw/cLj7h5cMt44wCjQz4rOfYNBEFeHDtlfR1QtWKgjm4ZHHJbKrzf9b2kQXclziceEbSM0tYbROEXKi+s0Zc+z3HEG89vv0vfN400clmzzIAijKY6gg3pPRWdECgYEA+lnWYbSlXDMNYx6RBXm1RnlMUYIm4oy4/9ljgnoGJ6WCn3SjFkgaDtiKfGIG1BSB85r04pAPANgcWHf5tWDnq0ARvBVG0BX2bKd++7B3D4d3CRYKCwm88SslJXv9dfHVhq4+zViFPiUWwT20A72jCuUCvL88y5fh/YBecfdh+jECgYEA4r5RD0NB9dMaeg5/jk/GEHIo4Z9KLc6FrSoOFo2xFkPOy1sgDpDOiNtypuWvniO7k7Ose3DS3hlfTMsKzIW/CgQJ20+Y4cvBWDaOsRxfjj7w3d+jH5OSJdKKSzTrgLKc9ZhlRzVXy0J0hipIA6HG5kdVdLXmh85ITmf1CbJhE6sCgYBjPVeBNbXTHZ2x6/z62aslO5IoQVqetb/kE82hfDOSZcao5Ph9Lam+ttH2ynkAevykj4mBgi+gWwqpey2uW7KaLPSaxShj9kDQA3mP1fzsV/u0y1rB02Nlin/YIxVvOqU1FT9p8SwoXVVu1sHUNck62VtDbN9xqUx5S/ikXrclEQKBgQCoTssOwEcK+Vty9KYcdfy4onTUHZBLdjxl8Iyqkxy7QTQUYRznkvesQPDXEDGO+kk3dyx2KKZt9Hl4IFNww2quPZcvcuMx4DQxjbXXpA8OIIxcta95NepLJwA+mRai3nKCH1A2TlNP7pFeMa5o+8IPly3Ix2lKr4Wepa4PN5i1pwKBgCZ1QP6XAOERl9NznNmU0rXVcvYNP4PIIfQWfvGsldZ4QKkmjjAGiS0/oYqdWs+UDRZyCRChaVjDXO9fk0PEG5OGKAj9nyiYCT/M8xtJ3UeP5ffZZvJ/vnye3QdDIo1e38ZzsWwJHmLYw7fRqY9W5Vxo0Vsy22U3CJY70KTxVdTy" ],
+        "keyUse" : [ "ENC" ],
+        "certificate" : [ "MIICmzCCAYMCBgGG3GWycDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZkYnJlcG8wHhcNMjMwMzEzMTkxMzE3WhcNMzMwMzEzMTkxNDU3WjARMQ8wDQYDVQQDDAZkYnJlcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdvW00t9yMUtTD1RKFUM1/5kPyxCpvhgFohdxIlNf/MNBQ+IKnXvoEEYjezhWmUMCuc5b4u6ajOYqiB6gcScYQgNbyi+Arm4xT21IDanSqoYFQw51HxgBNMh8Il7uoaKK4ZrdZnLexAszvRK5HPHTZhTyC9Ry+XYmzgrKoDOI5Rf/DdZrn0f2OMY1RdjKpo9Ymnvd4fNtVhbJLPIsbbaZWVxS0HHmyIvlPb9e7Sn3PiXv9tqnDCY5WLVmtweNsQDB0YSJIwYj+5aoAX6vUFGmYktHsc1dwvd4rj/npVgtqLBJ6N/Jh5EUwhMSf9TEZiFxdnnExRQIbRPGMGEtilMG7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK3kQ1VkQrzvSWvmXmazmNoA1ZiPzRDs1XhGUWxgsxzgPylr3dGBuqQbKvgnLUBQLSqlJHpI4fZflHswu1qrvVZYtekPcGef4WhcKAu2i1RwxrKa6RJQ1tRbrLuVYCzPv5p/DWgltWVn88aoLnqQn0SK/0PB/o4a4Cm7Kq2ZzCr1dACBr06LvOHsc7249OySmbG4HH+pLK6jVURhZ9VaObqAHe2FJBVVoIzURbdiRRURqumrIvbnpeaU1aFyg6ED5wTnXvmMPmVPt9F79mcB33bASO5wyu00X8t1hyN2Show2l2vxLACGUzVkTQt15s7uDLKE7qLmKSR3EuSGXWv3wA=" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "RSA-OAEP" ]
+      }
     }, {
       "id" : "2293ff99-3c6d-46d1-8635-5e679d5b134a",
       "name" : "rsa-generated",
@@ -2116,7 +2110,7 @@
   "internationalizationEnabled" : false,
   "supportedLocales" : [ ],
   "authenticationFlows" : [ {
-    "id" : "7b272faa-5cbf-4783-8bca-cabe292e80cc",
+    "id" : "b8378805-a082-46a0-9e28-a1e5d4db7e41",
     "alias" : "Account verification options",
     "description" : "Method with which to verity the existing account",
     "providerId" : "basic-flow",
@@ -2138,7 +2132,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "9d570708-d15a-4063-a3b1-d742c9c85529",
+    "id" : "2652bbd9-bd49-465c-8595-690099333bf7",
     "alias" : "Authentication Options",
     "description" : "Authentication options.",
     "providerId" : "basic-flow",
@@ -2167,7 +2161,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "2579048c-e648-4e95-9bd9-fb1fe776a64b",
+    "id" : "967c3248-c2e9-45a9-b770-b02e965b958a",
     "alias" : "Browser - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -2189,7 +2183,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "76197fdc-44e0-470c-b84f-7e666edda852",
+    "id" : "f78ad348-c3e1-476e-a916-fce0c383376a",
     "alias" : "Direct Grant - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -2211,7 +2205,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "1c163e76-4872-4996-b7a2-937fd9827f4a",
+    "id" : "788cf02b-5744-4ea6-940a-96bc762da4bd",
     "alias" : "First broker login - Conditional OTP",
     "description" : "Flow to determine if the OTP is required for the authentication",
     "providerId" : "basic-flow",
@@ -2233,7 +2227,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "fac05c8f-328f-4bb6-ac68-e5cf0dbaf768",
+    "id" : "273e61b7-9cc3-464e-a7b8-27c71aca4014",
     "alias" : "Handle Existing Account",
     "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
     "providerId" : "basic-flow",
@@ -2255,7 +2249,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "e9478687-f9bd-4854-83a2-768903dd06a7",
+    "id" : "00f41bfc-8513-466d-8c6a-366b7f2f36ca",
     "alias" : "Reset - Conditional OTP",
     "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
     "providerId" : "basic-flow",
@@ -2277,7 +2271,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "a6a6064c-91e3-455d-a8f7-8530f0d9f932",
+    "id" : "980ebf01-fe0a-4cfa-880e-dd86ce8e190e",
     "alias" : "User creation or linking",
     "description" : "Flow for the existing/non-existing user alternatives",
     "providerId" : "basic-flow",
@@ -2300,7 +2294,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "bf274d56-ea30-450d-9ba7-1d4206f8b9ae",
+    "id" : "5e6a7a10-4be8-4038-8fc5-0588b452328d",
     "alias" : "Verify Existing Account by Re-authentication",
     "description" : "Reauthentication of existing account",
     "providerId" : "basic-flow",
@@ -2322,7 +2316,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "38133f86-344b-497e-9402-87c454d7128c",
+    "id" : "024e07f8-f975-41ef-b755-d2b089b5567c",
     "alias" : "browser",
     "description" : "browser based authentication",
     "providerId" : "basic-flow",
@@ -2358,7 +2352,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "f644f101-4f4a-458a-990d-6ced0d1353fe",
+    "id" : "324da9be-755e-4556-a1d3-58569b9df47c",
     "alias" : "clients",
     "description" : "Base authentication for clients",
     "providerId" : "client-flow",
@@ -2394,7 +2388,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "a12de1f9-53eb-4563-8aa8-051e583bb144",
+    "id" : "bced47d4-5d04-4bb9-8605-94041185c0f3",
     "alias" : "direct grant",
     "description" : "OpenID Connect Resource Owner Grant",
     "providerId" : "basic-flow",
@@ -2423,7 +2417,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "edc782a3-5dee-41a2-ab0d-715fc55b01c9",
+    "id" : "6b301d9d-68c0-44c3-9a57-92669d08b2f3",
     "alias" : "docker auth",
     "description" : "Used by Docker clients to authenticate against the IDP",
     "providerId" : "basic-flow",
@@ -2438,7 +2432,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "358c0c7d-832d-477c-b9d0-258a786325d5",
+    "id" : "9c9ddfeb-37a2-4186-a58f-cf90dca8e191",
     "alias" : "first broker login",
     "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
     "providerId" : "basic-flow",
@@ -2461,7 +2455,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "891b4eb9-3a7f-4556-8cb8-f6a07c637dae",
+    "id" : "a9ef5094-93bf-49fc-9d0f-dcfc551cac5a",
     "alias" : "forms",
     "description" : "Username, password, otp and other auth forms.",
     "providerId" : "basic-flow",
@@ -2483,7 +2477,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "b74eeba1-2096-41d4-bafb-940ad65ecd42",
+    "id" : "fae6e2e4-a071-458b-ac03-41dda3456f5a",
     "alias" : "http challenge",
     "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
     "providerId" : "basic-flow",
@@ -2505,7 +2499,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "37ca760b-2b9f-491f-aa1c-a9896923ab61",
+    "id" : "ae5bcac5-8867-42e1-887f-fc67418b0c4b",
     "alias" : "registration",
     "description" : "registration flow",
     "providerId" : "basic-flow",
@@ -2521,7 +2515,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "1cf97e2c-9063-4b0e-8b99-56c463a6effc",
+    "id" : "72524b5d-1cfc-41b0-b29b-6f6890d2dc7f",
     "alias" : "registration form",
     "description" : "registration form",
     "providerId" : "form-flow",
@@ -2557,7 +2551,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "01499d7a-b0a1-4dd0-a866-62e6a28d5119",
+    "id" : "834c96b8-790d-4869-8c66-d42cd35e4873",
     "alias" : "reset credentials",
     "description" : "Reset credentials for a user if they forgot their password or something",
     "providerId" : "basic-flow",
@@ -2593,7 +2587,7 @@
       "userSetupAllowed" : false
     } ]
   }, {
-    "id" : "579397ef-7c1f-4a24-93c4-7e9ea2514783",
+    "id" : "7f131501-e3ff-48f2-98e6-e34e4c5d6f9e",
     "alias" : "saml ecp",
     "description" : "SAML ECP Profile Authentication Flow",
     "providerId" : "basic-flow",
@@ -2609,13 +2603,13 @@
     } ]
   } ],
   "authenticatorConfig" : [ {
-    "id" : "8f778718-7e1d-417a-b6e6-fc4788b45c44",
+    "id" : "638341f1-94ba-4042-a3ee-41a0f41718f6",
     "alias" : "create unique user config",
     "config" : {
       "require.password.update.after.registration" : "false"
     }
   }, {
-    "id" : "fdf2fe79-06e9-4bea-b361-dab88bd38680",
+    "id" : "3c355b8c-8a51-4346-88f2-1ff81856b55c",
     "alias" : "review profile config",
     "config" : {
       "update.profile.on.first.login" : "missing"
diff --git a/dbrepo-data-db/sidecar/app.py b/dbrepo-data-db/sidecar/app.py
index 1bcf3a4a0f041d70d796d2c89319b40201583e13..931f18d85566fdd8f37affa9dc9ee17ec7453164 100644
--- a/dbrepo-data-db/sidecar/app.py
+++ b/dbrepo-data-db/sidecar/app.py
@@ -61,7 +61,7 @@ template = {
     "info": {
         "title": "Database Repository Data Database sidecar API",
         "description": "Sidecar that downloads the import .csv file",
-        "version": "1.3.0",
+        "version": "$TAG",
         "contact": {
             "name": "Prof. Andreas Rauber",
             "email": "andreas.rauber@tuwien.ac.at"
diff --git a/dbrepo-data-service/pom.xml b/dbrepo-data-service/pom.xml
index 114544101a3a50d8ccf0aa9c932271bf2988820b..f71aeaff4a27420f3c1faff1941ca7cd6dd089b9 100644
--- a/dbrepo-data-service/pom.xml
+++ b/dbrepo-data-service/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>at.tuwien</groupId>
     <artifactId>dbrepo-data-service</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-data-service</name>
     <description>
         This service is responsible for the database-specific CRUD operations.
diff --git a/dbrepo-data-service/report/pom.xml b/dbrepo-data-service/report/pom.xml
index a26aa7a50a65977599c864ba6e55190906210e5d..5d55e85d8dc20199f33ffd22d3f01d92e9cf0b47 100644
--- a/dbrepo-data-service/report/pom.xml
+++ b/dbrepo-data-service/report/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>report</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-data-service-report</name>
     <description>
         This module is only intended for the pipeline coverage report. See the detailed report in the
diff --git a/dbrepo-data-service/rest-service/pom.xml b/dbrepo-data-service/rest-service/pom.xml
index b7bd40744085f5ad0f69a7a30d3be8fd342346a6..b4cf918e7796fe268089ae956ae86494d0f37903 100644
--- a/dbrepo-data-service/rest-service/pom.xml
+++ b/dbrepo-data-service/rest-service/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>rest-service</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-data-service-rest-service</name>
 
     <properties>
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
index cc2a45a4a37d2947a70fb63a9e08d99cb48820b9..d19efa07842120d19b5cb91dbeb7a59461febe04 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
@@ -7,7 +7,6 @@ import io.swagger.v3.oas.models.info.Info;
 import io.swagger.v3.oas.models.info.License;
 import io.swagger.v3.oas.models.servers.Server;
 import org.springdoc.core.models.GroupedOpenApi;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -16,9 +15,6 @@ import java.util.List;
 @Configuration
 public class SwaggerConfig {
 
-    @Value("${app.version:unknown}")
-    private String version;
-
     @Bean
     public OpenAPI springShopOpenAPI() {
         return new OpenAPI()
@@ -28,7 +24,7 @@ public class SwaggerConfig {
                                 .name("Prof. Andreas Rauber")
                                 .email("andreas.rauber@tuwien.ac.at"))
                         .description("Service that manages the data")
-                        .version(version)
+                        .version("$TAG")
                         .license(new License()
                                 .name("Apache 2.0")
                                 .url("https://www.apache.org/licenses/LICENSE-2.0")))
diff --git a/dbrepo-data-service/services/pom.xml b/dbrepo-data-service/services/pom.xml
index dbb1b898d04e0fbd1a507cf6b8b33240c9f15be3..c448fb01ebdf9a3508fd4a85180c532d187a3532 100644
--- a/dbrepo-data-service/services/pom.xml
+++ b/dbrepo-data-service/services/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-data-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>services</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-data-service-services</name>
 
     <build>
diff --git a/dbrepo-metadata-db/setup-schema.sql b/dbrepo-metadata-db/setup-schema.sql
index 3165796d3dd1a263ef031f98b64300889c385f21..2981117119cc6fbba19a9ca80752695925ff1f63 100644
--- a/dbrepo-metadata-db/setup-schema.sql
+++ b/dbrepo-metadata-db/setup-schema.sql
@@ -178,7 +178,7 @@ CREATE TABLE IF NOT EXISTS `mdb_columns_enums`
     id        bigint                 NOT NULL AUTO_INCREMENT,
     column_id bigint                 NOT NULL,
     value     CHARACTER VARYING(255) NOT NULL,
-    FOREIGN KEY (column_id) REFERENCES mdb_columns (ID),
+    FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE,
     PRIMARY KEY (id)
 ) WITH SYSTEM VERSIONING;
 
@@ -187,7 +187,7 @@ CREATE TABLE IF NOT EXISTS `mdb_columns_sets`
     id        bigint                 NOT NULL AUTO_INCREMENT,
     column_id bigint                 NOT NULL,
     value     CHARACTER VARYING(255) NOT NULL,
-    FOREIGN KEY (column_id) REFERENCES mdb_columns (ID),
+    FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE,
     PRIMARY KEY (id)
 ) WITH SYSTEM VERSIONING;
 
diff --git a/dbrepo-metadata-db/setup-schema_local.sql b/dbrepo-metadata-db/setup-schema_local.sql
index 4b35338875b707d7a951461bd54314017e573d16..426acf93fa6eaa2f0d5b0ceea942a060adebca65 100644
--- a/dbrepo-metadata-db/setup-schema_local.sql
+++ b/dbrepo-metadata-db/setup-schema_local.sql
@@ -1,7 +1,8 @@
 BEGIN;
 
-INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, sidecar_host, sidecar_port,
+INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, ui_host, ui_port, sidecar_host, sidecar_port,
                               privileged_username, privileged_password)
-VALUES ('MariaDB Galera 11.1.3', 'mariadb_11_1_3', 1, 'data-db', 3306, 'data-db-sidecar', 3305, 'root', 'dbrepo');
+VALUES ('MariaDB Galera 11.1.3', 'mariadb_11_1_3', 1, 'data-db', 3306, 'localhost', 3306, 'data-db-sidecar', 3305,
+        'root', 'dbrepo');
 
 COMMIT;
diff --git a/dbrepo-metadata-service/api/pom.xml b/dbrepo-metadata-service/api/pom.xml
index 63e76bec78e78ce227edd5f1abe767eeb0b098af..207d7dab8df6f3217709ed6e5859d5b95f42d1d7 100644
--- a/dbrepo-metadata-service/api/pom.xml
+++ b/dbrepo-metadata-service/api/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-api</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-api</name>
 
     <dependencies/>
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java
index 3cab9d49ff6f1779200ddb0a5ced317e8c9fa2e8..792d4f7756d1286ea757d2f37f1315fdb7168ab6 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/container/ContainerDto.java
@@ -1,6 +1,7 @@
 package at.tuwien.api.container;
 
 import at.tuwien.api.container.image.ImageBriefDto;
+import at.tuwien.api.container.image.ImageDto;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -61,8 +62,7 @@ public class ContainerDto {
     @Field(name = "ui_port", type = FieldType.Integer)
     private Integer uiPort;
 
-    @Field(name = "image", type = FieldType.Nested)
-    private ImageBriefDto image;
+    private ImageDto image;
 
     @NotNull
     @Field(type = FieldType.Date)
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java
index e1b4298cc30d959b7d6c2e23dfe287b3cbe8382d..e6db0c9736efc00906c9ea3a8cedf36bd669f164 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/DatabaseDto.java
@@ -62,10 +62,10 @@ public class DatabaseDto {
     @Field(name = "description", type = FieldType.Text)
     private String description;
 
-    @Field(name = "tables", type = FieldType.Nested)
+    @Field(name = "tables", type = FieldType.Object)
     private List<TableDto> tables;
 
-    @Field(name = "views", type = FieldType.Nested)
+    @Field(name = "views", type = FieldType.Object)
     private List<ViewDto> views;
 
     @JsonProperty("is_public")
@@ -73,26 +73,28 @@ public class DatabaseDto {
     @Field(name = "is_public", type = FieldType.Boolean)
     private Boolean isPublic;
 
-    @Field(name = "container", type = FieldType.Nested)
+    @Field(name = "container", type = FieldType.Object)
     private ContainerDto container;
 
+    @org.springframework.data.annotation.Transient
     private List<DatabaseAccessDto> accesses;
 
-    @Field(name = "identifiers", type = FieldType.Nested)
+    @Field(name = "identifiers", type = FieldType.Object)
     private List<IdentifierDto> identifiers;
 
-    @Field(name = "subsets", type = FieldType.Nested)
+    @Field(name = "subsets", type = FieldType.Object)
     private List<IdentifierDto> subsets;
 
     @NotNull
+    @org.springframework.data.annotation.Transient
     private UserDto creator;
 
     @NotNull
-    @Field(name = "contact", type = FieldType.Nested)
+    @Field(name = "contact", type = FieldType.Object)
     private UserDto contact;
 
     @NotNull
-    @Field(name = "owner", type = FieldType.Nested)
+    @Field(name = "owner", type = FieldType.Object)
     private UserDto owner;
 
     @NotNull
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/LicenseDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/LicenseDto.java
index e8f7109acb8adc3241fb893db48e0131bd612d57..0f548b71ba050aeefde1f909296e395a56289870 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/LicenseDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/LicenseDto.java
@@ -6,6 +6,8 @@ import lombok.*;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.extern.jackson.Jacksonized;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
 
 @Getter
 @Setter
@@ -18,10 +20,12 @@ public class LicenseDto {
 
     @NotNull
     @Schema(example = "MIT")
+    @Field(name = "identifier", type = FieldType.Keyword)
     private String identifier;
 
     @NotBlank
     @Schema(example = "https://opensource.org/licenses/MIT")
+    @Field(name = "uri", type = FieldType.Keyword)
     private String uri;
 
 }
\ No newline at end of file
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java
index 84df87e0170a537128f307d6b0c5479de0dd6630..9eef10f09ccebebfdac0a9c112950573d6d1c891 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/ViewDto.java
@@ -49,7 +49,7 @@ public class ViewDto {
     @Field(name = "name", type = FieldType.Keyword)
     private String name;
 
-    @Field(name = "identifiers", type = FieldType.Nested)
+    @Field(name = "identifiers", type = FieldType.Object)
     private List<IdentifierDto> identifiers;
 
     @NotBlank
@@ -90,6 +90,7 @@ public class ViewDto {
     private UUID createdBy;
 
     @NotNull
+    @org.springframework.data.annotation.Transient
     private UserDto creator;
 
     @NotNull(message = "columns are required")
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
index 62a347107409b5b8823fa53a445221bbe80a0927..9b48ff9ebfff35806d331541ba6e1333168973f8 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
@@ -30,11 +30,9 @@ public class QueryBriefDto {
     @NotNull(message = "id is required")
     private Long id;
 
-    @NotNull(message = "container id is required")
-    private Long cid;
-
     @NotNull(message = "database id is required")
-    private Long dbid;
+    @JsonProperty("database_id")
+    private Long databaseId;
 
     @JsonIgnore
     @NotNull(message = "created by is required")
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
index 59533d41b02b06f3c8da108cfea4263b1eceb5fc..593b65ce5bcea34316fc29576847c34e506f20a4 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
@@ -28,11 +28,9 @@ public class QueryDto {
     @NotNull(message = "id is required")
     private Long id;
 
-    @NotNull(message = "container id is required")
-    private Long cid;
-
     @NotNull(message = "database id is required")
-    private Long dbid;
+    @JsonProperty("database_id")
+    private Long databaseId;
 
     @JsonIgnore
     @EqualsAndHashCode.Exclude
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
index b05b843ae5c6f975b0ef9d00befcf5b4a4e50747..72f666fdd05b3cbb1f877628db19f5a07ab59a2c 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
@@ -49,7 +49,7 @@ public class TableDto {
     @Field(name = "internal_name", type = FieldType.Keyword)
     private String internalName;
 
-    @Field(name = "identifiers", type = FieldType.Nested)
+    @Field(name = "identifiers", type = FieldType.Object)
     private List<IdentifierDto> identifiers;
 
     @NotNull
@@ -64,11 +64,11 @@ public class TableDto {
     private UUID createdBy;
 
     @NotNull(message = "creator is required")
-    @Field(name = "creator", type = FieldType.Nested)
+    @org.springframework.data.annotation.Transient
     private UserDto creator;
 
     @NotNull(message = "owner is required")
-    @Field(name = "owner", type = FieldType.Nested)
+    @Field(name = "owner", type = FieldType.Object)
     private UserDto owner;
 
     @NotBlank(message = "queueName is required")
@@ -105,9 +105,10 @@ public class TableDto {
     private Instant created;
 
     @NotNull(message = "columns are required")
+    @Field(name = "columns", type = FieldType.Object)
     private List<ColumnDto> columns;
 
-    @Field(name = "constraints", type = FieldType.Nested)
+    @Field(name = "constraints", type = FieldType.Object)
     private ConstraintsDto constraints;
 
 }
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
index fc667ae8ee479d20dfb7289b061d8917cab63c8a..1f3dc0f3f04005fc4069c87a7a7c214db12dbe27 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
@@ -57,7 +57,7 @@ public class ColumnDto {
     private String alias;
 
     @JsonProperty("date_format")
-    @Field(name = "date_format", type = FieldType.Nested)
+    @Field(name = "date_format", type = FieldType.Object)
     private ImageDateDto dateFormat;
 
     @NotNull
@@ -126,10 +126,10 @@ public class ColumnDto {
     @Field(name = "std_dev", type = FieldType.Double)
     private BigDecimal stdDev;
 
-    @Field(name = "concept", type = FieldType.Nested)
+    @Field(name = "concept", type = FieldType.Object)
     private ConceptDto concept;
 
-    @Field(name = "unit", type = FieldType.Nested)
+    @Field(name = "unit", type = FieldType.Object)
     private UnitDto unit;
 
     @NotNull
@@ -144,11 +144,9 @@ public class ColumnDto {
     @Schema(example = "false")
     private Boolean isNullAllowed;
 
-    @Field(name = "enums", type = FieldType.Nested)
     @Parameter(description = "enum values, only considered when type = ENUM")
     private List<String> enums;
 
-    @Field(name = "sets", type = FieldType.Nested)
     @Parameter(description = "enum values, only considered when type = ENUM")
     private List<String> sets;
 
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/ConstraintsDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/ConstraintsDto.java
index 6c5b703634cce81fbbe0c2add8d8231792b4da29..6b5e0e7d7602118c3bddc4588ef9abf62eb7c4f2 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/ConstraintsDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/constraints/ConstraintsDto.java
@@ -19,12 +19,13 @@ import java.util.List;
 @ToString
 public class ConstraintsDto {
 
-    @Field(name = "uniques", type = FieldType.Nested)
+    @Field(name = "uniques", type = FieldType.Object)
     private List<UniqueDto> uniques;
 
     @JsonProperty("foreign_keys")
-    @Field(name = "foreign_keys", type = FieldType.Nested)
+    @Field(name = "foreign_keys", type = FieldType.Object)
     private List<ForeignKeyDto> foreignKeys;
 
+    @org.springframework.data.annotation.Transient
     private List<String> checks;
 }
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
index aee2e3281efdfe881a917e7ec0b002fcb3b6b3fd..a405eece1b6a4b601c4d73e27e6a0f01e117d9de 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java
@@ -58,13 +58,13 @@ public class IdentifierDto {
     @Field(name = "type", type = FieldType.Keyword)
     private IdentifierTypeDto type;
 
-    @Field(name = "titles", type = FieldType.Nested)
+    @Field(name = "titles", type = FieldType.Object)
     private List<IdentifierTitleDto> titles;
 
-    @Field(name = "descriptions", type = FieldType.Nested)
+    @Field(name = "descriptions", type = FieldType.Object)
     private List<IdentifierDescriptionDto> descriptions;
 
-    @Field(name = "funders", type = FieldType.Nested)
+    @Field(name = "funders", type = FieldType.Object)
     private List<IdentifierFunderDto> funders;
 
     @NotBlank
@@ -79,7 +79,7 @@ public class IdentifierDto {
     private String queryNormalized;
 
     @JsonProperty("related_identifiers")
-    @Field(name = "related_identifiers", type = FieldType.Nested)
+    @Field(name = "related_identifiers", type = FieldType.Object)
     private List<RelatedIdentifierDto> relatedIdentifiers;
 
     @NotBlank
@@ -116,7 +116,7 @@ public class IdentifierDto {
 
     @NotNull
     @JsonIgnore
-    @Field(name = "creator", type = FieldType.Nested)
+    @org.springframework.data.annotation.Transient
     private UserDto creator;
 
     @JsonProperty("publication_day")
@@ -138,11 +138,11 @@ public class IdentifierDto {
     @Field(name = "language", type = FieldType.Keyword)
     private LanguageTypeDto language;
 
-    @Field(name = "licenses", type = FieldType.Nested)
+    @Field(name = "licenses", type = FieldType.Object)
     private List<LicenseDto> licenses;
 
     @NotNull
-    @Field(name = "creators", type = FieldType.Nested)
+    @Field(name = "creators", type = FieldType.Object)
     private List<CreatorDto> creators;
 
     @NotNull
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/user/UserDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/user/UserDto.java
index 3ef24c16c1d23c221b44b6148d1833cbe50b6c52..e35da63f653dbc900ba014d8295b446be304545a 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/user/UserDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/user/UserDto.java
@@ -54,12 +54,8 @@ public class UserDto {
     @Field(name = "lastname", type = FieldType.Keyword)
     private String lastname;
 
-    @NotNull
-    private UserAttributesDto attributes;
-
     @NotNull
     @org.springframework.data.annotation.Transient
-    @Schema(example = "jcarberry@brown.edu")
-    private String email;
+    private UserAttributesDto attributes;
 
 }
diff --git a/dbrepo-metadata-service/entities/pom.xml b/dbrepo-metadata-service/entities/pom.xml
index a91ce44bf32969f9feb5005d331050d2e267c9fc..fcde8337055b923f595d6e42d1976c7b88de0306 100644
--- a/dbrepo-metadata-service/entities/pom.xml
+++ b/dbrepo-metadata-service/entities/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-entities</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-entity</name>
 
     <dependencies/>
diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java
index c5540ecf897559e5739da2940433534cc59a1c61..7888bb6fdde986f1e5c73213a811ac6c940fc9f6 100644
--- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java
+++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/View.java
@@ -2,6 +2,7 @@ package at.tuwien.entities.database;
 
 import at.tuwien.entities.database.table.columns.TableColumn;
 import at.tuwien.entities.identifier.Identifier;
+import at.tuwien.entities.user.User;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import jakarta.persistence.*;
 import jakarta.persistence.CascadeType;
@@ -47,10 +48,17 @@ public class View {
     @Column(updatable = false, nullable = false)
     private Long vdbid;
 
+    @ToString.Exclude
     @JdbcTypeCode(java.sql.Types.VARCHAR)
-    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Column(name = "created_by", columnDefinition = "VARCHAR(36)")
     private UUID createdBy;
 
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
+    @JoinColumns({
+            @JoinColumn(name = "created_by", referencedColumnName = "ID", insertable = false, updatable = false)
+    })
+    private User creator;
+
     @Column(name = "vname", nullable = false)
     private String name;
 
diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
index 0ba70fbd4a5331be6bab983701bec75b94b854a4..9cd43c09771e608b11490ab2e3ffa07640705a1f 100644
--- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
+++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
@@ -6,6 +6,8 @@ import at.tuwien.entities.database.table.Table;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -104,14 +106,18 @@ public class TableColumn implements Comparable<TableColumn> {
             inverseJoinColumns = @JoinColumn(name = "id", referencedColumnName = "id"))
     private TableColumnUnit unit;
 
-    @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
+    @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class)
     @CollectionTable(name = "mdb_columns_enums", joinColumns = @JoinColumn(name = "column_id"))
     @Column(name = "value", nullable = false)
+    @JoinColumn(name = "column_id")
+    @OnDelete(action = OnDeleteAction.CASCADE)
     private List<String> enums;
 
-    @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
+    @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class)
     @CollectionTable(name = "mdb_columns_sets", joinColumns = @JoinColumn(name = "column_id"))
     @Column(name = "value", nullable = false)
+    @JoinColumn(name = "column_id")
+    @OnDelete(action = OnDeleteAction.CASCADE)
     private List<String> sets;
 
     @Column
diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
index 0fb92413730f379f336faa5b514092919be0126f..6b2cba565be171e7108fc2c90732732545bddeee 100644
--- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
+++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
@@ -31,11 +31,11 @@ import java.util.UUID;
 @EntityListeners(AuditingEntityListener.class)
 @Table(name = "mdb_identifiers")
 @NamedQueries({
-        @NamedQuery(name = "Identifier.findAllDatabaseIdentifiers", query = "select i from Identifier i where i.type = 'DATABASE'"),
-        @NamedQuery(name = "Identifier.findAllSubsetIdentifiers", query = "select i from Identifier i where i.type = 'SUBSET'"),
-        @NamedQuery(name = "Identifier.findDatabaseIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.type = 'DATABASE'"),
-        @NamedQuery(name = "Identifier.findSubsetIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.queryId = ?2 and i.type = 'SUBSET'"),
-        @NamedQuery(name = "Identifier.findViewIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.viewId = ?2 and i.type = 'VIEW'"),
+        @NamedQuery(name = "Identifier.findAllDatabaseIdentifiers", query = "select i from Identifier i where i.type = 'DATABASE' ORDER BY i.id DESC"),
+        @NamedQuery(name = "Identifier.findAllSubsetIdentifiers", query = "select i from Identifier i where i.type = 'SUBSET' ORDER BY i.id DESC"),
+        @NamedQuery(name = "Identifier.findDatabaseIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.type = 'DATABASE' ORDER BY i.id DESC"),
+        @NamedQuery(name = "Identifier.findSubsetIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.queryId = ?2 and i.type = 'SUBSET' ORDER BY i.id DESC"),
+        @NamedQuery(name = "Identifier.findViewIdentifier", query = "select i from Identifier i where i.databaseId = ?1 and i.viewId = ?2 and i.type = 'VIEW' ORDER BY i.id DESC"),
 })
 public class Identifier implements Serializable {
 
diff --git a/dbrepo-metadata-service/oai/pom.xml b/dbrepo-metadata-service/oai/pom.xml
index c4e04a3e1d3578269474cf7f0b7d8051fbb2b3b1..82913d529529e843c8062e8aed73c8c6138edba3 100644
--- a/dbrepo-metadata-service/oai/pom.xml
+++ b/dbrepo-metadata-service/oai/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-oai</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-oai</name>
 
     <dependencies/>
diff --git a/dbrepo-metadata-service/pom.xml b/dbrepo-metadata-service/pom.xml
index 4c8525eb7f4bfe2d276bdb27dcbab17d2c21688a..f3d440e7cfc5e3e51ca349f07985338fa1f2beaf 100644
--- a/dbrepo-metadata-service/pom.xml
+++ b/dbrepo-metadata-service/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>at.tuwien</groupId>
     <artifactId>dbrepo-metadata-service</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service</name>
     <description>Service that manages the metadata</description>
 
diff --git a/dbrepo-metadata-service/querystore/pom.xml b/dbrepo-metadata-service/querystore/pom.xml
index fc125dea5e6edc9955826f7aff41c594616c68cb..bfead37257bd87829407aa5044446d4b2132ea55 100644
--- a/dbrepo-metadata-service/querystore/pom.xml
+++ b/dbrepo-metadata-service/querystore/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-querystore</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-querystore</name>
 
     <dependencies/>
diff --git a/dbrepo-metadata-service/querystore/src/main/java/at/tuwien/querystore/Query.java b/dbrepo-metadata-service/querystore/src/main/java/at/tuwien/querystore/Query.java
index e6925b48c5bfa30a1b568d7647358233e5daf2c2..272c03f65fcba81cf36fa80cfbcc12437958da40 100644
--- a/dbrepo-metadata-service/querystore/src/main/java/at/tuwien/querystore/Query.java
+++ b/dbrepo-metadata-service/querystore/src/main/java/at/tuwien/querystore/Query.java
@@ -6,9 +6,10 @@ import org.hibernate.annotations.GenericGenerator;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
-import jakarta.persistence.*;;
+import jakarta.persistence.*;
 import java.io.Serializable;
 import java.time.Instant;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -61,6 +62,6 @@ public class Query implements Serializable {
     private Instant executed;
 
     @jakarta.persistence.Column(nullable = false)
-    private String createdBy;
+    private UUID createdBy;
 
 }
diff --git a/dbrepo-metadata-service/report/pom.xml b/dbrepo-metadata-service/report/pom.xml
index f3793ae9da7db256b224477c9b5a9a4962c3541a..bc0bbd3a78b8dd71ac7788ae7e00a76ee54a9ad9 100644
--- a/dbrepo-metadata-service/report/pom.xml
+++ b/dbrepo-metadata-service/report/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-report</artifactId>
diff --git a/dbrepo-metadata-service/repositories/pom.xml b/dbrepo-metadata-service/repositories/pom.xml
index 06dbfd1a3f09dc818ec4d050b74e9c1998f2a32a..730f0782c8fb14aeac8ba51246ac24b3968528fb 100644
--- a/dbrepo-metadata-service/repositories/pom.xml
+++ b/dbrepo-metadata-service/repositories/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-repositories</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-repositories</name>
 
     <dependencies>
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java
index 09839e09f2a18c44c0d818d6504bc081b35aa271..4c232eafcee6be72b107c9b315ccae9203e69a84 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java
@@ -48,7 +48,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-@Mapper(componentModel = "spring")
+@Mapper(componentModel = "spring", imports = {LinkedList.class})
 public interface QueryMapper {
 
     org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(QueryMapper.class);
@@ -57,12 +57,13 @@ public interface QueryMapper {
             .withZone(ZoneId.of("UTC"));
 
     @Mappings({
-            @Mapping(target = "createdBy", ignore = true)
+            @Mapping(target = "createdBy", ignore = true),
+            @Mapping(target = "identifiers", expression = "java(new LinkedList())")
     })
     QueryDto queryToQueryDto(Query data);
 
     @Mappings({
-            @Mapping(target = "createdBy", ignore = true)
+            @Mapping(target = "identifiers", expression = "java(new LinkedList())")
     })
     QueryBriefDto queryToQueryBriefDto(Query data);
 
@@ -123,14 +124,7 @@ public interface QueryMapper {
 
     default void importCsvQuery(Connection connection, Table table, ImportDto csv) throws SQLException {
         final Statement statement = connection.createStatement();
-        final StringBuilder query0 = new StringBuilder("DROP TABLE IF EXISTS `")
-                .append(table.getDatabase().getInternalName())
-                .append("`.`")
-                .append(table.getInternalName())
-                .append("_temporary`;");
-        log.trace("mapped drop temporary table statement: {}", query0);
-        statement.execute(query0.toString());
-        final StringBuilder query1 = new StringBuilder("CREATE TABLE `")
+        final StringBuilder query0 = new StringBuilder("CREATE TABLE `")
                 .append(table.getDatabase().getInternalName())
                 .append("`.`")
                 .append(table.getInternalName())
@@ -140,13 +134,20 @@ public interface QueryMapper {
                 .append("`.`")
                 .append(table.getInternalName())
                 .append("`;");
-        log.trace("mapped create temporary table statement: {}", query1);
+        log.trace("mapped create temporary table statement: {}", query0);
+        statement.execute(query0.toString());
+        final String query1 = pathToRawInsertQuery(table, csv);
+        log.trace("mapped import csv statement: {}", query1);
         statement.execute(query1.toString());
-        final String query2 = pathToRawInsertQuery(table, csv);
-        log.trace("mapped import csv statement: {}", query2);
+        final String query2 = generateInsertFromTemporaryTableSQL(table);
+        log.trace("mapped import table statement: {}", query2);
         statement.execute(query2.toString());
-        final String query3 = generateInsertFromTemporaryTableSQL(table);
-        log.trace("mapped import table statement: {}", query3);
+        final StringBuilder query3 = new StringBuilder("DROP TABLE IF EXISTS `")
+                .append(table.getDatabase().getInternalName())
+                .append("`.`")
+                .append(table.getInternalName())
+                .append("_temporary`;");
+        log.trace("mapped drop temporary table statement: {}", query3);
         statement.execute(query3.toString());
 
     }
@@ -743,7 +744,7 @@ public interface QueryMapper {
             }
             final TableColumn aliasColumn = optionalColumn.get();
             if (item.getAlias() != null) {
-                aliasColumn.setAlias(item.getAlias().getName());
+                aliasColumn.setAlias(item.getAlias().getName().replace("`", ""));
             }
             log.trace("found column with internal name {} and alias {}", aliasColumn.getInternalName(), aliasColumn.getAlias());
             columns.add(aliasColumn);
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/StoreMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/StoreMapper.java
index 285d8fd14dd5aed30fbd4e919106395f95256072..cce0c72866eb1df34f68aeb959e6b165322e134f 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/StoreMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/StoreMapper.java
@@ -12,6 +12,7 @@ import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
+import java.util.UUID;
 
 @Mapper(componentModel = "spring")
 public interface StoreMapper {
@@ -32,8 +33,8 @@ public interface StoreMapper {
         }
         try {
             final CallableStatement ps = connection.prepareCall(statement);
-            ps.setString(1, user.getUsername());
-            log.trace("param 1={}", user.getUsername());
+            ps.setString(1, String.valueOf(user.getId()));
+            log.trace("param 1={}", user.getId());
             ps.setString(2, data.getStatement());
             log.trace("param 2={}", data.getStatement());
             ps.setTimestamp(3, Timestamp.from(data.getTimestamp()));
@@ -99,7 +100,7 @@ public interface StoreMapper {
         return Query.builder()
                 .id(data.getLong(1))
                 .created(createdInst)
-                .createdBy(data.getString(3))
+                .createdBy(UUID.fromString(data.getString(3)))
                 .query(data.getString(4))
                 .queryHash(data.getString(5))
                 .resultHash(data.getString(6))
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java
index 3e7ce40092cb571330ca8dffbb1ebf6e4dcf28bf..999704345ef34d9ad2482a57df73289ebb394f81 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java
@@ -44,7 +44,7 @@ import java.util.*;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-@Mapper(componentModel = "spring", uses = {IdentifierMapper.class})
+@Mapper(componentModel = "spring", uses = {IdentifierMapper.class, UserMapper.class})
 public interface TableMapper {
 
     org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TableMapper.class);
@@ -321,14 +321,14 @@ public interface TableMapper {
         final StringBuilder sequence = new StringBuilder();
         if (data.getColumns().stream().anyMatch(TableColumn::getAutoGenerated)) {
             log.debug("table with id {} has sequence generated which needs to be dropped too", data.getId());
-            sequence.append("DROP SEQUENCE `")
+            sequence.append("DROP SEQUENCE IF EXISTS `")
                     .append(tableToSequenceName(data))
                     .append("`;");
         }
-        final StringBuilder table = new StringBuilder("DROP TABLE `")
+        final StringBuilder table = new StringBuilder("DROP TABLE IF EXISTS `")
                 .append(data.getInternalName())
                 .append("`;");
-        final StringBuilder view = new StringBuilder("DROP VIEW `hs_")
+        final StringBuilder view = new StringBuilder("DROP VIEW IF EXISTS `hs_")
                 .append(data.getInternalName())
                 .append("`;");
         try {
@@ -342,7 +342,7 @@ public interface TableMapper {
             log.trace("mapped drop view statement {}", table);
         } catch (SQLException e) {
             log.error("Failed to drop table or sequence: {}", e.getMessage());
-            throw new QueryMalformedException("Failed to drop table or sequence", e);
+            throw new QueryMalformedException("Failed to drop table or sequence: " + e.getMessage(), e);
         }
     }
 
diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/ViewMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/ViewMapper.java
index e8b12e3c38b326dd59124176735f076f935c3891..272275fec6a2ac44ff5748585d0c365510cb5da6 100644
--- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/ViewMapper.java
+++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/ViewMapper.java
@@ -1,13 +1,9 @@
 package at.tuwien.mapper;
 
-import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.ViewBriefDto;
 import at.tuwien.api.database.ViewCreateDto;
 import at.tuwien.api.database.ViewDto;
-import at.tuwien.api.identifier.IdentifierDto;
-import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.View;
-import at.tuwien.entities.identifier.Identifier;
 import at.tuwien.exception.QueryMalformedException;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
@@ -49,9 +45,39 @@ public interface ViewMapper {
 
     ViewBriefDto viewToViewBriefDto(View data);
 
+
+    default PreparedStatement viewToSelectAll(Connection connection, View view, Long page, Long size) throws QueryMalformedException {
+        log.debug("mapping view query, view.query={}", view.getQuery());
+        final StringBuilder statement = new StringBuilder("SELECT ");
+        final int[] idx = new int[]{0};
+        view.getColumns()
+                .forEach(c -> statement.append(idx[0]++ > 0 ? "," : "")
+                        .append("`")
+                        .append(c.getInternalName())
+                        .append("`"));
+        statement.append(" FROM `")
+                .append(view.getInternalName())
+                .append("`");
+        /* pagination */
+        log.trace("pagination size/limit of {}", size);
+        statement.append(" LIMIT ")
+                .append(size);
+        log.trace("pagination page/offset of {}", page);
+        statement.append(" OFFSET ")
+                .append(page * size);
+        statement.append(";");
+        try {
+            log.trace("mapped view query {} to prepared statement", statement);
+            return connection.prepareStatement(statement.toString());
+        } catch (SQLException e) {
+            log.error("Failed to prepare statement {}: {}", statement, e.getMessage());
+            throw new QueryMalformedException("Failed to prepare statement: " + e.getMessage(), e);
+        }
+    }
+
     default PreparedStatement viewToRawDeleteViewQuery(Connection connection, View view)
             throws QueryMalformedException {
-        log.debug("mapping delete view query, view={}", view);
+        log.debug("mapping delete view query, view.name={}", view.getName());
         final StringBuilder statement = new StringBuilder("DROP VIEW `")
                 .append(nameToInternalName(view.getName()))
                 .append("`;");
@@ -59,8 +85,8 @@ public interface ViewMapper {
             log.trace("mapped delete view {} to prepared statement", view.getName());
             return connection.prepareStatement(statement.toString());
         } catch (SQLException e) {
-            log.debug("Failed to prepare statement {}, reason: {}", statement, e.getMessage());
-            throw new QueryMalformedException("Failed to prepare statement", e);
+            log.error("Failed to prepare statement {}: {}", statement, e.getMessage());
+            throw new QueryMalformedException("Failed to prepare statement: " + e.getMessage(), e);
         }
     }
 
@@ -77,8 +103,8 @@ public interface ViewMapper {
             log.trace("mapped create view {} to prepared statement {}", data.getName(), pstmt);
             return pstmt;
         } catch (SQLException e) {
-            log.error("Failed to prepare statement {}, reason: {}", statement, e.getMessage());
-            throw new QueryMalformedException("Failed to prepare statement", e);
+            log.error("Failed to prepare statement {}: {}", statement, e.getMessage());
+            throw new QueryMalformedException("Failed to prepare statement: " + e.getMessage(), e);
         }
     }
 
diff --git a/dbrepo-metadata-service/rest-service/pom.xml b/dbrepo-metadata-service/rest-service/pom.xml
index 024ea3282f562b78bccf8f0a48b12b261dc169a1..bc152de450e081021e95dcaac749ebe251ea1edf 100644
--- a/dbrepo-metadata-service/rest-service/pom.xml
+++ b/dbrepo-metadata-service/rest-service/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-rest-service</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-rest</name>
 
     <dependencies>
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
index 7907a04f775e3246d8060d3707309683d953c0d1..ad5f5d273eb6ffa8f4eacc28d28834fefeefeb32 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java
@@ -7,7 +7,6 @@ import io.swagger.v3.oas.models.info.Info;
 import io.swagger.v3.oas.models.info.License;
 import io.swagger.v3.oas.models.servers.Server;
 import org.springdoc.core.models.GroupedOpenApi;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -16,9 +15,6 @@ import java.util.List;
 @Configuration
 public class SwaggerConfig {
 
-    @Value("${app.version:unknown}")
-    private String version;
-
     @Bean
     public OpenAPI springShopOpenAPI() {
         return new OpenAPI()
@@ -28,7 +24,7 @@ public class SwaggerConfig {
                                 .name("Prof. Andreas Rauber")
                                 .email("andreas.rauber@tuwien.ac.at"))
                         .description("Service that manages the metadata")
-                        .version(version)
+                        .version("$TAG")
                         .license(new License()
                                 .name("Apache 2.0")
                                 .url("https://www.apache.org/licenses/LICENSE-2.0")))
@@ -40,7 +36,7 @@ public class SwaggerConfig {
                                 .url("http://localhost:9099"),
                         new Server()
                                 .description("Sandbox")
-                                .url("https://dbrepo2.tuwien.ac.at")));
+                                .url("https://test.dbrepo.tuwien.ac.at")));
     }
 
     @Bean
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java
index 1c9ade9d90a6ad7d7cb4a809fc64a33f23b2905b..054bc7cfa9e29eb819ec0329d6c4ba23aa559470 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/AccessEndpoint.java
@@ -59,6 +59,11 @@ public class AccessEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Failed giving access",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "Database or user not found",
                     content = {@Content(
@@ -75,7 +80,7 @@ public class AccessEndpoint {
                                     @Valid @RequestBody DatabaseGiveAccessDto accessDto,
                                     @NotNull Principal principal)
             throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException,
-            DatabaseMalformedException, KeycloakRemoteException, AccessDeniedException {
+            DatabaseMalformedException {
         log.debug("endpoint give access to database, databaseId={}, userId={}, accessDto={}, {}", databaseId, userId, accessDto, PrincipalUtil.formatForDebug(principal));
         try {
             accessService.find(databaseId, userId);
@@ -119,7 +124,7 @@ public class AccessEndpoint {
                                     @Valid @RequestBody DatabaseModifyAccessDto accessDto,
                                     @NotNull Principal principal)
             throws DatabaseNotFoundException, UserNotFoundException, NotAllowedException, QueryMalformedException,
-            DatabaseMalformedException, AccessDeniedException, KeycloakRemoteException {
+            DatabaseMalformedException, AccessDeniedException {
         log.debug("endpoint modify access to database, databaseId={}, userId={}, accessDto={}, {}", databaseId, userId, accessDto, PrincipalUtil.formatForDebug(principal));
         accessService.find(databaseId, userId);
         accessService.update(databaseId, userId, accessDto);
@@ -143,8 +148,8 @@ public class AccessEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Check access is not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "Database not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -173,18 +178,13 @@ public class AccessEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "User with access was not found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Revoke of access not permitted",
+            @ApiResponse(responseCode = "403",
+                    description = "Revoke of access not permitted as no access was found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "403",
-                    description = "Revoke of access not permitted as no access was found",
+            @ApiResponse(responseCode = "404",
+                    description = "User, database with access was not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
index 04f49f65b80f1361bef8689f62306e60521b9fba..c0e01632f35a48bda6b0be6534d84b0a054b6416 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
@@ -84,16 +84,6 @@ public class ContainerEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ContainerBriefDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Failed to connect",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Container image or user could not be found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "Container image or user could not be found",
                     content = {@Content(
@@ -126,24 +116,14 @@ public class ContainerEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ContainerDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Failed to connect",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "Container image could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Connection to the container failed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<ContainerDto> findById(@NotNull @PathVariable("id") Long containerId)
-            throws  ContainerNotFoundException {
+            throws ContainerNotFoundException {
         log.debug("endpoint find container, id={}", containerId);
         final Container container = containerService.find(containerId);
         final ContainerDto dto = containerMapper.containerToContainerDto(container);
@@ -159,15 +139,9 @@ public class ContainerEndpoint {
     @Operation(summary = "Delete some container", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
-                    description = "Deleted container successfully",
-                    content = {@Content}),
-            @ApiResponse(responseCode = "409",
-                    description = "Container is still running",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "410",
-                    description = "Container is already removed",
+                    description = "Deleted container successfully"),
+            @ApiResponse(responseCode = "404",
+                    description = "Container not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
index 57b62ef6699fc6443f72709392a3ab67d671dac2..beec5ad35112142480210e50c394df248cff2f29 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
@@ -72,6 +72,11 @@ public class DatabaseEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             array = @ArraySchema(schema = @Schema(implementation = DatabaseBriefDto.class)))}),
+            @ApiResponse(responseCode = "404",
+                    description = "User not found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<List<DatabaseDto>> list(@NotNull Principal principal,
                                                   @RequestParam(required = false) String filter)
@@ -100,8 +105,12 @@ public class DatabaseEndpoint {
     @Operation(summary = "Count databases")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200",
-                    description = "Count databases",
-                    content = {@Content()}),
+                    description = "Count databases"),
+            @ApiResponse(responseCode = "404",
+                    description = "User not found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<List<DatabaseDto>> count(@NotNull Principal principal,
                                                    @RequestParam(required = false) String filter)
@@ -140,37 +149,22 @@ public class DatabaseEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = DatabaseBriefDto.class))}),
             @ApiResponse(responseCode = "400",
-                    description = "Database create query is malformed",
+                    description = "Database create query is malformed or image is not supported",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Container, user or database could not be found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
+            @ApiResponse(responseCode = "403",
                     description = "Database create permission is missing or grant permissions at broker service failed",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "406",
-                    description = "Failed to create user at broker service or virtual host could not be reached at broker service",
+            @ApiResponse(responseCode = "404",
+                    description = "Container, user or database could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "409",
-                    description = "Database name already exist or query store could not be created",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "501",
-                    description = "Container image is not supported",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Connection to the container failed",
+                    description = "Query store could not be created",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -182,11 +176,9 @@ public class DatabaseEndpoint {
     })
     public ResponseEntity<DatabaseBriefDto> create(@Valid @RequestBody DatabaseCreateDto createDto,
                                                    @NotNull Principal principal)
-            throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException,
-            AmqpException, ContainerConnectionException, UserNotFoundException,
-            DatabaseNotFoundException, DatabaseNameExistsException, DatabaseConnectionException,
-            QueryMalformedException, NotAllowedException, BrokerVirtualHostModificationException, QueryStoreException,
-            BrokerVirtualHostGrantException, KeycloakRemoteException, AccessDeniedException, BrokerRemoteException {
+            throws ContainerNotFoundException, DatabaseMalformedException, UserNotFoundException,
+            DatabaseNotFoundException, DatabaseConnectionException, QueryMalformedException, NotAllowedException,
+            QueryStoreException {
         log.debug("endpoint create database, createDto={}, {}", createDto, PrincipalUtil.formatForDebug(principal));
         final User user = userService.findByUsername(principal.getName());
         final Database database = databaseService.create(createDto, principal);
@@ -212,11 +204,11 @@ public class DatabaseEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = DatabaseDto.class))}),
             @ApiResponse(responseCode = "404",
-                    description = "Database or user could not be found",
+                    description = "Database could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
+            @ApiResponse(responseCode = "403",
                     description = "Visibility modification is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
@@ -225,10 +217,9 @@ public class DatabaseEndpoint {
     public ResponseEntity<DatabaseDto> visibility(@NotNull @PathVariable Long id,
                                                   @Valid @RequestBody DatabaseModifyVisibilityDto data,
                                                   @NotNull Principal principal) throws DatabaseNotFoundException,
-            UserNotFoundException, NotAllowedException {
+            NotAllowedException {
         log.debug("endpoint update database, id={}, data={}, {}", id, data, PrincipalUtil.formatForDebug(principal));
         final Database database = databaseService.findById(id);
-        final User user = userService.findByUsername(principal.getName());
         if (!database.getOwnedBy().equals(UserUtil.getId(principal))) {
             log.error("Failed to create database: not owner");
             throw new NotAllowedException(("Failed to create database: not owner"));
@@ -255,7 +246,7 @@ public class DatabaseEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
+            @ApiResponse(responseCode = "403",
                     description = "Transfer of ownership is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
@@ -264,7 +255,7 @@ public class DatabaseEndpoint {
     public ResponseEntity<DatabaseDto> transfer(@NotNull @PathVariable Long id,
                                                 @Valid @RequestBody DatabaseTransferDto transferDto,
                                                 @NotNull Principal principal) throws DatabaseNotFoundException,
-            UserNotFoundException, NotAllowedException, KeycloakRemoteException, AccessDeniedException {
+            UserNotFoundException, NotAllowedException {
         log.debug("endpoint update database, id={}, transferDto={}, {}", id, transferDto, PrincipalUtil.formatForDebug(principal));
         final Database database = databaseService.findById(id);
         final User user = userService.findByUsername(principal.getName());
@@ -289,7 +280,12 @@ public class DatabaseEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = DatabaseDto.class))}),
             @ApiResponse(responseCode = "404",
-                    description = "Database could not be found",
+                    description = "Database or exchange could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "503",
+                    description = "Connection to the broker service could not be established",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
index e43e5fd4e6cf1c109377d38492b7ae4f16dd9999..aac1e1c4ef266fed4be72521518fb5821acb084e 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
@@ -6,15 +6,18 @@ import at.tuwien.api.identifier.IdentifierSaveDto;
 import at.tuwien.api.identifier.IdentifierTypeDto;
 import at.tuwien.api.user.external.ExternalMetadataDto;
 import at.tuwien.entities.database.Database;
+import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.entities.database.View;
 import at.tuwien.entities.database.table.Table;
 import at.tuwien.entities.identifier.Identifier;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.IdentifierMapper;
 import at.tuwien.querystore.Query;
 import at.tuwien.service.*;
 import at.tuwien.utils.PrincipalUtil;
 import at.tuwien.utils.UserUtil;
+import at.tuwien.validation.EndpointValidator;
 import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
@@ -35,6 +38,7 @@ import org.springframework.web.bind.annotation.*;
 
 import java.security.Principal;
 import java.util.List;
+import java.util.UUID;
 import java.util.stream.Collectors;
 
 @Log4j2
@@ -43,6 +47,7 @@ import java.util.stream.Collectors;
 @RequestMapping("/api/identifier")
 public class IdentifierEndpoint {
 
+    private final UserService userService;
     private final ViewService viewService;
     private final TableService tableService;
     private final StoreService storeService;
@@ -50,13 +55,15 @@ public class IdentifierEndpoint {
     private final DatabaseService databaseService;
     private final MetadataService metadataService;
     private final IdentifierMapper identifierMapper;
+    private final EndpointValidator endpointValidator;
     private final IdentifierService identifierService;
 
     @Autowired
-    public IdentifierEndpoint(ViewService viewService, TableService tableService, StoreService storeService,
-                              AccessService accessService, DatabaseService databaseService,
+    public IdentifierEndpoint(UserService userService, ViewService viewService, TableService tableService,
+                              StoreService storeService, AccessService accessService, DatabaseService databaseService,
                               MetadataService metadataService, IdentifierMapper identifierMapper,
-                              IdentifierService identifierService) {
+                              EndpointValidator endpointValidator, IdentifierService identifierService) {
+        this.userService = userService;
         this.viewService = viewService;
         this.tableService = tableService;
         this.storeService = storeService;
@@ -64,6 +71,7 @@ public class IdentifierEndpoint {
         this.databaseService = databaseService;
         this.metadataService = metadataService;
         this.identifierMapper = identifierMapper;
+        this.endpointValidator = endpointValidator;
         this.identifierService = identifierService;
     }
 
@@ -103,6 +111,11 @@ public class IdentifierEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = IdentifierDto.class))}),
+            @ApiResponse(responseCode = "204",
+                    description = "Identifier could not be created",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "400",
                     description = "Identifier form contains invalid request data",
                     content = {@Content(
@@ -138,66 +151,71 @@ public class IdentifierEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "503",
+                    description = "DataCite system did not respond",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<IdentifierDto> create(@NotNull @Valid @RequestBody IdentifierSaveDto data,
-                                                @NotNull Principal principal)
-            throws IdentifierAlreadyExistsException, QueryNotFoundException, IdentifierPublishingNotAllowedException,
-            RemoteUnavailableException, UserNotFoundException, DatabaseNotFoundException, IdentifierRequestException,
-            NotAllowedException, ViewNotFoundException, QueryStoreException, DatabaseConnectionException,
-            ImageNotSupportedException, IdentifierNotFoundException, TableNotFoundException, TableMalformedException,
-            QueryMalformedException, FileStorageException, DataDbSidecarException {
+                                                @NotNull Principal principal) throws DatabaseNotFoundException,
+            NotAllowedException, IdentifierRequestException, ViewNotFoundException, TableNotFoundException,
+            QueryStoreException, QueryNotFoundException, ImageNotSupportedException, UserNotFoundException,
+            DatabaseConnectionException, RemoteUnavailableException {
         log.debug("endpoint create identifier, data={}, {}", data, PrincipalUtil.formatForDebug(principal));
+        DatabaseAccess access = null;
         try {
-            accessService.find(data.getDatabaseId(), UserUtil.getId(principal));
+            access = accessService.find(data.getDatabaseId(), UserUtil.getId(principal));
         } catch (AccessDeniedException e) {
             if (!UserUtil.hasRole(principal, "create-foreign-identifier")) {
-                log.error("Failed to create identifier: insufficient access");
-                throw new NotAllowedException("Failed to create identifier: insufficient access");
+                log.error("Failed to create identifier: insufficient role");
+                throw new NotAllowedException("Failed to create identifier: insufficient role");
             }
         }
         final Database database = databaseService.find(data.getDatabaseId());
         switch (data.getType()) {
             case VIEW -> {
                 if (data.getDatabaseId() == null || data.getQueryId() != null || data.getViewId() == null || data.getTableId() != null) {
-                    log.error("Failed to create identifier: only parameters database_id & view_id must be present");
-                    throw new IdentifierRequestException("Failed to create identifier: only parameters database_id & view_id must be present");
+                    log.error("Failed to create view identifier: only parameters database_id & view_id must be present");
+                    throw new IdentifierRequestException("Failed to create view identifier: only parameters database_id & view_id must be present");
                 }
                 final View view = viewService.findById(data.getViewId());
-                if (!database.getOwnedBy().equals(UserUtil.getId(principal)) && !view.getCreatedBy().equals(UserUtil.getId(principal))) {
-                    log.error("Failed to create identifier: insufficient role");
-                    throw new IdentifierRequestException("Failed to create identifier: insufficient role");
+                if (!endpointValidator.validateOnlyMineOrReadAccessOrHasRole(view.getCreatedBy(), principal, access, "create-foreign-identifier")) {
+                    log.error("Failed to create view identifier: insufficient access or role");
+                    throw new IdentifierRequestException("Failed to create view identifier: insufficient access or role");
                 }
             }
             case TABLE -> {
                 if (data.getDatabaseId() == null || data.getQueryId() != null || data.getViewId() != null || data.getTableId() == null) {
-                    log.error("Failed to create identifier: only parameters database_id & table_id must be present");
-                    throw new IdentifierRequestException("Failed to create identifier: only parameters database_id & table_id must be present");
+                    log.error("Failed to create table identifier: only parameters database_id & table_id must be present");
+                    throw new IdentifierRequestException("Failed to create table identifier: only parameters database_id & table_id must be present");
                 }
                 final Table table = tableService.find(data.getDatabaseId(), data.getTableId());
-                if (!database.getOwnedBy().equals(UserUtil.getId(principal)) && !table.getOwnedBy().equals(UserUtil.getId(principal))) {
-                    log.error("Failed to create identifier: insufficient role");
-                    throw new IdentifierRequestException("Failed to create identifier: insufficient role");
+                if (!endpointValidator.validateOnlyMineOrReadAccessOrHasRole(table.getOwnedBy(), principal, access, "create-foreign-identifier")) {
+                    log.error("Failed to create table identifier: insufficient access or role");
+                    throw new IdentifierRequestException("Failed to create table identifier: insufficient access or role");
                 }
             }
             case SUBSET -> {
                 if (data.getDatabaseId() == null || data.getQueryId() == null || data.getViewId() != null || data.getTableId() != null) {
-                    log.error("Failed to create identifier: only parameters database_id & query_id must be present");
-                    throw new IdentifierRequestException("Failed to create identifier: only parameters database_id & query_id must be present");
+                    log.error("Failed to create subset identifier: only parameters database_id & query_id must be present");
+                    throw new IdentifierRequestException("Failed to create subset identifier: only parameters database_id & query_id must be present");
                 }
                 final Query query = storeService.findOne(data.getDatabaseId(), data.getQueryId(), principal);
-                if (!database.getOwnedBy().equals(UserUtil.getId(principal)) && !query.getCreatedBy().equals(UserUtil.getId(principal).toString())) {
-                    log.error("Failed to create identifier: insufficient role");
-                    throw new IdentifierRequestException("Failed to create identifier: insufficient role");
+                final User user = userService.find(query.getCreatedBy());
+                if (!endpointValidator.validateOnlyMineOrReadAccessOrHasRole(user.getId(), principal, access, "create-foreign-identifier")) {
+                    log.error("Failed to create subset identifier: insufficient access or role");
+                    throw new IdentifierRequestException("Failed to create subset identifier: insufficient access or role");
                 }
             }
             case DATABASE -> {
                 if (data.getDatabaseId() == null || data.getQueryId() != null || data.getViewId() != null || data.getTableId() != null) {
-                    log.error("Failed to create identifier: only parameters database_id must be present");
-                    throw new IdentifierRequestException("Failed to create identifier: only parameters database_id must be present");
+                    log.error("Failed to create database identifier: only parameters database_id must be present");
+                    throw new IdentifierRequestException("Failed to create database identifier: only parameters database_id must be present");
                 }
-                if (!database.getOwnedBy().equals(UserUtil.getId(principal))) {
-                    log.error("Failed to create identifier: insufficient role");
-                    throw new IdentifierRequestException("Failed to create identifier: insufficient role");
+                if (!endpointValidator.validateOnlyMineOrReadAccessOrHasRole(database.getOwnedBy(), principal, access, "create-foreign-identifier")) {
+                    log.error("Failed to create database identifier: insufficient access or role");
+                    throw new IdentifierRequestException("Failed to create database identifier: insufficient access or role");
                 }
             }
         }
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java
index e1290d84fc071a042adc47e5f50ff5d863e91100..1ac1988a2aca03557e63d19c884001bd8da06476 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ImageEndpoint.java
@@ -87,16 +87,6 @@ public class ImageEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "User could not be found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "502",
-                    description = "Failed to connect",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "409",
                     description = "Image already exists",
                     content = {@Content(
@@ -104,8 +94,8 @@ public class ImageEndpoint {
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<ImageDto> create(@Valid @RequestBody ImageCreateDto data,
-                                           @NotNull Principal principal) throws ImageNotFoundException,
-            ImageAlreadyExistsException, UserNotFoundException, ImageInvalidException {
+                                           @NotNull Principal principal) throws ImageAlreadyExistsException,
+            ImageInvalidException {
         log.debug("endpoint create image, data={}, {}", data, PrincipalUtil.formatForDebug(principal));
         if (data.getDefaultPort() == null) {
             log.error("Failed to create image, default port is null");
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MaintenanceEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MaintenanceEndpoint.java
index b71109d62ba5cd75e113a9f3f6d89677f5bd3ae8..e0702cd8a5eeed8bb94102db3f46aed1f7ff5b7f 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MaintenanceEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/MaintenanceEndpoint.java
@@ -1,5 +1,6 @@
 package at.tuwien.endpoints;
 
+import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.api.maintenance.BannerMessageBriefDto;
 import at.tuwien.api.maintenance.BannerMessageCreateDto;
 import at.tuwien.api.maintenance.BannerMessageDto;
@@ -69,6 +70,11 @@ public class MaintenanceEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = BannerMessageDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Could not find message",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<BannerMessageDto> find(@NotNull @PathVariable("id") Long messageId)
             throws BannerMessageNotFoundException {
@@ -131,7 +137,7 @@ public class MaintenanceEndpoint {
                     description = "Could not find message",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = BannerMessageNotFoundException.class))}),
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<BannerMessageDto> update(@NotNull @PathVariable("id") Long messageId,
                                                         @Valid @RequestBody BannerMessageUpdateDto data)
@@ -155,7 +161,7 @@ public class MaintenanceEndpoint {
                     description = "Could not find message",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = BannerMessageNotFoundException.class))}),
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<?> delete(@NotNull @PathVariable("id") Long messageId)
             throws BannerMessageNotFoundException {
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
index 649c51dfe11c924bc24ea8108892022be2b80fb5..b03d183707f2767c8e9b2c7929424e4198aa3f4f 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/OntologyEndpoint.java
@@ -96,16 +96,10 @@ public class OntologyEndpoint {
                     description = "Registered ontology successfully",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = OntologyDto.class))}),
-            @ApiResponse(responseCode = "201",
-                    description = "Could not find user",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
+                            schema = @Schema(implementation = OntologyDto.class))})
     })
     public ResponseEntity<OntologyDto> create(@NotNull @Valid @RequestBody OntologyCreateDto data,
-                                              @NotNull Principal principal) throws UserNotFoundException,
-            KeycloakRemoteException, AccessDeniedException {
+                                              @NotNull Principal principal) {
         log.debug("endpoint create ontology, data={}, {}", data, PrincipalUtil.formatForDebug(principal));
         final OntologyDto dto = ontologyMapper.ontologyToOntologyDto(ontologyService.create(data, principal));
         log.trace("create ontology resulted in dto {}", dto);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
index dda30b78d036ffe4ad6b7334de795410135d172a..a8d46160496c2144e3a92544ffcfed95af0eb7dc 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
@@ -72,11 +72,26 @@ public class PersistenceEndpoint {
                             mediaType = "text/bibliography",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
-                    description = "Identifier could not be exported from database as the resource was not found",
+                    description = "Identifier could not be found",
                     content = {@Content(
                             mediaType = "text/csv",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "502",
+            @ApiResponse(responseCode = "409",
+                    description = "Exported resource was not found",
+                    content = {@Content(
+                            mediaType = "text/csv",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "410",
+                    description = "Failed to retrieve from S3 endpoint",
+                    content = {@Content(
+                            mediaType = "text/csv",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "422",
+                    description = "Failed to retrieve from database sidecar",
+                    content = {@Content(
+                            mediaType = "text/csv",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "503",
                     description = "Identifier could not exported from database as it is not reachable",
                     content = {@Content(
                             mediaType = "text/csv",
@@ -85,9 +100,9 @@ public class PersistenceEndpoint {
     public ResponseEntity<?> find(@Valid @PathVariable("pid") Long pid,
                                   @RequestHeader(HttpHeaders.ACCEPT) String accept,
                                   @NotNull Principal principal) throws IdentifierNotFoundException,
-            QueryNotFoundException, RemoteUnavailableException, IdentifierRequestException, UserNotFoundException,
-            QueryStoreException, TableMalformedException, DatabaseConnectionException, QueryMalformedException,
-            DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, DataDbSidecarException {
+            QueryNotFoundException, IdentifierRequestException, UserNotFoundException, QueryStoreException,
+            TableMalformedException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException,
+            ImageNotSupportedException, FileStorageException, DataDbSidecarException {
         log.debug("endpoint find identifier, pid={}, accept={}", pid, accept);
         final Identifier identifier = identifierService.find(pid);
         log.info("Found persistent identifier with id {}", identifier.getId());
@@ -151,15 +166,14 @@ public class PersistenceEndpoint {
     @Operation(summary = "Delete some identifier", security = @SecurityRequirement(name = "bearerAuth"))
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
-                    description = "Deleted identifier",
-                    content = {@Content}),
-            @ApiResponse(responseCode = "404",
-                    description = "Identifier or database could not be found",
+                    description = "Deleted identifier"),
+            @ApiResponse(responseCode = "403",
+                    description = "Deleting identifier not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Deleting identifier not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "Identifier or database could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))})
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
index 612ad08e75e619937e2bac2383caaf46cb7f1abb..0b1c053865683fc0a2ed78cf896c792ea6d2530f 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java
@@ -4,6 +4,7 @@ import at.tuwien.ExportResource;
 import at.tuwien.SortType;
 import at.tuwien.api.database.query.ExecuteStatementDto;
 import at.tuwien.api.database.query.QueryResultDto;
+import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.entities.database.Database;
 import at.tuwien.exception.*;
 import at.tuwien.querystore.Query;
@@ -15,6 +16,10 @@ import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotNull;
@@ -53,6 +58,38 @@ public class QueryEndpoint {
     @Observed(name = "dbr_query_execute")
     @PreAuthorize("hasAuthority('execute-query')")
     @Operation(summary = "Execute query", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Executed query",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = QueryResultDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Execute query not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Database, query or user could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "409",
+                    description = "Could not store query in query store",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "417",
+                    description = "Could not parse columns",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))})
+    })
     public ResponseEntity<QueryResultDto> execute(@NotNull @PathVariable("databaseId") Long databaseId,
                                                   @NotNull @Valid @RequestBody ExecuteStatementDto data,
                                                   @RequestParam(value = "page", required = false) Long page,
@@ -61,8 +98,8 @@ public class QueryEndpoint {
                                                   @RequestParam(required = false) SortType sortDirection,
                                                   @RequestParam(required = false) String sortColumn)
             throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, QueryMalformedException,
-            ColumnParseException, UserNotFoundException, TableMalformedException, DatabaseConnectionException,
-            SortException, PaginationException, NotAllowedException, KeycloakRemoteException, AccessDeniedException, QueryNotFoundException {
+            ColumnParseException, UserNotFoundException, TableMalformedException, SortException, PaginationException,
+            NotAllowedException, AccessDeniedException, QueryNotFoundException {
         log.debug("endpoint execute query, databaseId={}, data={}, page={}, size={}, sortDirection={}, sortColumn={}, {}",
                 databaseId, data, page, size, sortDirection, sortColumn, PrincipalUtil.formatForDebug(principal));
         /* check */
@@ -85,6 +122,38 @@ public class QueryEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_query_reexecute")
     @Operation(summary = "Re-execute some query", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Executed query",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = QueryResultDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Execute query not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Database or query could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "409",
+                    description = "Could not store query in query store",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "417",
+                    description = "Could not parse columns",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))})
+    })
     public ResponseEntity<QueryResultDto> reExecute(@NotNull @PathVariable("databaseId") Long databaseId,
                                                     @NotNull @PathVariable("queryId") Long queryId,
                                                     Principal principal,
@@ -92,9 +161,9 @@ public class QueryEndpoint {
                                                     @RequestParam(value = "size", required = false) Long size,
                                                     @RequestParam(required = false) SortType sortDirection,
                                                     @RequestParam(required = false) String sortColumn)
-            throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            QueryMalformedException, TableMalformedException, ColumnParseException, DatabaseConnectionException,
-            SortException, PaginationException, UserNotFoundException, NotAllowedException, AccessDeniedException {
+            throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, QueryMalformedException,
+            ColumnParseException, TableMalformedException, SortException, PaginationException, NotAllowedException,
+            AccessDeniedException, QueryNotFoundException {
         log.debug("endpoint re-execute query, databaseId={}, queryId={}, page={}, size={}, sortDirection={}, sortColumn={}, {}",
                 databaseId, queryId, page, size, sortDirection, sortColumn, PrincipalUtil.formatForDebug(principal));
         endpointValidator.validateDataParams(page, size, sortDirection, sortColumn);
@@ -113,12 +182,39 @@ public class QueryEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_query_reexecute_count")
     @Operation(summary = "Re-execute some query", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Executed query",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = QueryResultDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Execute query not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Database or query could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "417",
+                    description = "Could not parse columns",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))})
+    })
     public ResponseEntity<Long> reExecuteCount(@NotNull @PathVariable("databaseId") Long databaseId,
                                                @NotNull @PathVariable("queryId") Long queryId,
                                                Principal principal)
             throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
             QueryMalformedException, TableMalformedException, ColumnParseException, NotAllowedException,
-            DatabaseConnectionException, UserNotFoundException, AccessDeniedException {
+            AccessDeniedException {
         log.debug("endpoint re-execute query count, databaseId={}, queryId={}, {}", databaseId, queryId, PrincipalUtil.formatForDebug(principal));
         endpointValidator.validateOnlyAccessOrPublic(databaseId, principal);
         /* execute */
@@ -133,13 +229,46 @@ public class QueryEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_query_export")
     @Operation(summary = "Exports some query", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200",
+                    description = "Executed query"),
+            @ApiResponse(responseCode = "400",
+                    description = "Image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Execute query not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Database or query could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "409",
+                    description = "Export of query failed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "410",
+                    description = "Could not find in S3 storage",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "422",
+                    description = "Sidecar failed to export",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))})
+    })
     public ResponseEntity<?> export(@NotNull @PathVariable("databaseId") Long databaseId,
                                     @NotNull @PathVariable("queryId") Long queryId,
                                     @RequestHeader(HttpHeaders.ACCEPT) String accept,
                                     Principal principal)
             throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            TableMalformedException, FileStorageException, QueryMalformedException, DatabaseConnectionException,
-            UserNotFoundException, NotAllowedException, DataDbSidecarException {
+            FileStorageException, QueryMalformedException, NotAllowedException, DataDbSidecarException {
         log.debug("endpoint export query, databaseId={}, queryId={}, accept={}, {}", databaseId, queryId, accept, PrincipalUtil.formatForDebug(principal));
         final Database database = databaseService.find(databaseId);
         if (!database.getIsPublic()) {
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
index bb5d1287716605286853b81bcc90a3c36123f753..1ff758a309f0b54c2f5f48005dc525d6571b698e 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/StoreEndpoint.java
@@ -5,6 +5,7 @@ import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.database.query.QueryPersistDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.api.identifier.IdentifierBriefDto;
+import at.tuwien.api.user.UserDto;
 import at.tuwien.entities.identifier.Identifier;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.IdentifierMapper;
@@ -38,9 +39,10 @@ import org.springframework.web.bind.annotation.*;
 
 import java.security.Principal;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 
+import static org.apache.jena.sparql.vocabulary.VocabTestQuery.query;
+
 @Log4j2
 @RestController
 @RequestMapping("/api/database/{databaseId}/query")
@@ -120,18 +122,26 @@ public class StoreEndpoint {
         endpointValidator.validateOnlyAccessOrPublic(databaseId, principal);
         /* find all from data database */
         final List<Query> queries = storeService.findAll(databaseId, persisted, principal);
-        /* add identifiers from metadata database */
+        /* add identifiers and creator from metadata database */
         final List<IdentifierBriefDto> identifiers = identifierService.findAllSubsetIdentifiers()
                 .stream()
                 .map(identifierMapper::identifierToIdentifierBriefDto)
                 .toList();
+        final List<UserDto> users = userService.findAll()
+                .stream()
+                .map(userMapper::userToUserDto)
+                .toList();
         final List<QueryBriefDto> dto = queries.stream()
                 .map(queryMapper::queryToQueryBriefDto)
                 .peek(q -> {
-                    final List<IdentifierBriefDto> subsetIdentifiers = identifiers.stream()
+                    q.setDatabaseId(databaseId);
+                    users.stream()
+                            .filter(u -> u.getId().equals(q.getCreatedBy()))
+                            .findFirst()
+                            .ifPresentOrElse(q::setCreator, () -> log.warn("Query creator with id {} not found in list of users", q.getCreatedBy()));
+                    q.setIdentifiers(identifiers.stream()
                             .filter(i -> i.getDatabaseId().equals(databaseId) && i.getQueryId().equals(q.getId()))
-                            .toList();
-                    q.setIdentifiers(subsetIdentifiers);
+                            .toList());
                 })
                 .collect(Collectors.toList());
         log.trace("find queries resulted in queries {}", dto);
@@ -186,7 +196,8 @@ public class StoreEndpoint {
         /* find */
         final Query query = storeService.findOne(databaseId, queryId, principal);
         final QueryDto dto = queryMapper.queryToQueryDto(query);
-        dto.setCreator(userMapper.userToUserDto(userService.findByUsername(query.getCreatedBy())));
+        dto.setDatabaseId(databaseId);
+        dto.setCreator(userMapper.userToUserDto(userService.find(query.getCreatedBy())));
         final List<Identifier> identifiers = identifierService.findByDatabaseIdAndQueryId(databaseId, queryId);
         if (!identifiers.isEmpty()) {
             dto.setIdentifiers(identifiers.stream()
@@ -208,53 +219,47 @@ public class StoreEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = QueryDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Database, query or user could not be found",
+            @ApiResponse(responseCode = "400",
+                    description = "Image not supported",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Persist query is not permitted",
+            @ApiResponse(responseCode = "403",
+                    description = "Not allowed to persist query",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "409",
-                    description = "Query is already persisted",
+            @ApiResponse(responseCode = "404",
+                    description = "Database, query or user could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "501",
-                    description = "Image is not supported",
+            @ApiResponse(responseCode = "405",
+                    description = "Persist query is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "504",
-                    description = "Query store failed to persist query",
+            @ApiResponse(responseCode = "412",
+                    description = "Query is already persisted",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
+                            schema = @Schema(implementation = ApiErrorDto.class))})
     })
     public ResponseEntity<QueryDto> persist(@NotNull @PathVariable("databaseId") Long databaseId,
                                             @NotNull @PathVariable("queryId") Long queryId,
                                             @NotNull @Valid @RequestBody QueryPersistDto data,
                                             @NotNull Principal principal)
-            throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException,
-            DatabaseConnectionException, UserNotFoundException, QueryNotFoundException,
-            QueryAlreadyPersistedException, NotAllowedException, AccessDeniedException {
-        log.debug("endpoint persist query, container, databaseId={}, queryId={}, {}", databaseId, queryId, PrincipalUtil.formatForDebug(principal));
+            throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException,
+            NotAllowedException, AccessDeniedException, IdentifierAlreadyPublishedException {
+        log.debug("endpoint persist query, container, databaseId={}, queryId={}, data.persist={}, {}", databaseId, queryId, data.getPersist(), PrincipalUtil.formatForDebug(principal));
         /* check */
         endpointValidator.validateOnlyAccessOrPublic(databaseId, principal);
-        final Query check = storeService.findOne(databaseId, queryId, principal);
-        if (check.getIsPersisted()) {
-            log.error("Failed to persist, is already persisted");
-            throw new QueryAlreadyPersistedException("Failed to persist");
-        }
         /* has access */
         accessService.find(databaseId, UserUtil.getId(principal));
         /* persist */
         final Query query = storeService.persist(databaseId, queryId, data);
         final QueryDto dto = queryMapper.queryToQueryDto(query);
-        dto.setCreator(userMapper.userToUserDto(userService.findByUsername(query.getCreatedBy())));
+        dto.setCreator(userMapper.userToUserDto(userService.find(query.getCreatedBy())));
         log.trace("persist query resulted in query {}", dto);
         return ResponseEntity.status(HttpStatus.ACCEPTED)
                 .body(dto);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
index 3cc440c088ba49caee6d7b5888193c65274125fd..999a66bb70f150e7fa1459724f782eca4744636c 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableColumnEndpoint.java
@@ -67,15 +67,10 @@ public class TableColumnEndpoint {
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
-                    description = "Table, database, semantic concept, unit of measurement or container could not be found",
+                    description = "Table or database could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Update column semantics not permitted",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ColumnDto.class))}),
     })
     public ResponseEntity<ColumnDto> update(@NotNull @PathVariable("id") Long id,
                                             @NotNull @PathVariable("tableId") Long tableId,
@@ -83,9 +78,8 @@ public class TableColumnEndpoint {
                                             @NotNull @Valid @RequestBody ColumnSemanticsUpdateDto updateDto,
                                             @NotNull Principal principal,
                                             @NotNull @RequestHeader("Authorization") String authorization)
-            throws TableNotFoundException, TableMalformedException, DatabaseNotFoundException,
-            ContainerNotFoundException, NotAllowedException, SemanticEntityPersistException,
-            SemanticEntityNotFoundException, QueryMalformedException, AccessDeniedException {
+            throws TableNotFoundException, TableMalformedException, DatabaseNotFoundException, NotAllowedException,
+            AccessDeniedException {
         log.debug("endpoint update table, id={}, tableId={}, columnId={}, {}", id, tableId, columnId, PrincipalUtil.formatForDebug(principal));
         if (principal != null && !UserUtil.hasRole(principal, "modify-foreign-table-column-semantics")) {
             endpointValidator.validateOnlyAccess(id, principal, true);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
index f2e1fb567c74bf3648ea95773c64a0c4cd0410d0..0b1f25f0fe4dc5e105a4e3626dd186471a507cb6 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableDataEndpoint.java
@@ -5,6 +5,8 @@ import at.tuwien.api.database.query.ImportDto;
 import at.tuwien.api.database.query.QueryResultDto;
 import at.tuwien.api.database.table.TableCsvDeleteDto;
 import at.tuwien.api.database.table.TableCsvDto;
+import at.tuwien.api.database.table.columns.ColumnDto;
+import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.entities.database.Database;
 import at.tuwien.exception.*;
 import at.tuwien.service.DatabaseService;
@@ -14,6 +16,10 @@ import at.tuwien.utils.UserUtil;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.observation.annotation.Observed;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotNull;
@@ -50,13 +56,31 @@ public class TableDataEndpoint {
     @Observed(name = "dbr_table_data_insert")
     @PreAuthorize("hasAuthority('insert-table-data')")
     @Operation(summary = "Insert data", security = @SecurityRequirement(name = "bearerAuth"))
-    public ResponseEntity<Void> insert(@NotNull @PathVariable("databaseId") Long databaseId,
-                                       @NotNull @PathVariable("tableId") Long tableId,
-                                       @NotNull @Valid @RequestBody TableCsvDto data,
-                                       @NotNull Principal principal)
-            throws TableNotFoundException, DatabaseNotFoundException, TableMalformedException,
-            ImageNotSupportedException, ContainerNotFoundException, DatabaseConnectionException, UserNotFoundException,
-            NotAllowedException, AccessDeniedException {
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Inserted data successfully"),
+            @ApiResponse(responseCode = "400",
+                    description = "Insert table data is malformed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Access to the database is forbidden",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Table or database could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
+    public ResponseEntity<?> insert(@NotNull @PathVariable("databaseId") Long databaseId,
+                                    @NotNull @PathVariable("tableId") Long tableId,
+                                    @NotNull @Valid @RequestBody TableCsvDto data,
+                                    @NotNull Principal principal)
+            throws TableNotFoundException, DatabaseNotFoundException, TableMalformedException, NotAllowedException,
+            AccessDeniedException {
         log.debug("endpoint insert data, databaseId={}, tableId={}, data={}, {}", databaseId, tableId, data, PrincipalUtil.formatForDebug(principal));
         /* check */
         endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(databaseId, tableId, principal);
@@ -71,13 +95,31 @@ public class TableDataEndpoint {
     @PreAuthorize("hasAuthority('delete-table-data')")
     @Observed(name = "dbr_table_data_delete")
     @Operation(summary = "Delete data", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Deleted table data successfully"),
+            @ApiResponse(responseCode = "400",
+                    description = "Table data or query is malformed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Access to the database is forbidden",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Table or database could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
     public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") Long databaseId,
                                        @NotNull @PathVariable("tableId") Long tableId,
                                        @NotNull @Valid @RequestBody TableCsvDeleteDto data,
                                        @NotNull Principal principal)
             throws TableNotFoundException, DatabaseNotFoundException, TableMalformedException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryMalformedException, UserNotFoundException,
-            NotAllowedException, AccessDeniedException {
+            ImageNotSupportedException, QueryMalformedException, NotAllowedException, AccessDeniedException {
         log.debug("endpoint delete data, databaseId={}, tableId={}, data={}, {}", databaseId, tableId, data, PrincipalUtil.formatForDebug(principal));
         /* check */
         endpointValidator.validateOnlyWriteOwnOrWriteAllAccess(databaseId, tableId, principal);
@@ -92,12 +134,35 @@ public class TableDataEndpoint {
     @PreAuthorize("hasAuthority('insert-table-data')")
     @Observed(name = "dbr_table_data_import")
     @Operation(summary = "Insert data from csv", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Import table data successfully"),
+            @ApiResponse(responseCode = "400",
+                    description = "Table data is malformed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Access to the database is forbidden",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Table or database could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "422",
+                    description = "Could not import csv via sidecar",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
     public ResponseEntity<Void> importCsv(@NotNull @PathVariable("databaseId") Long databaseId,
                                           @NotNull @PathVariable("tableId") Long tableId,
                                           @NotNull @Valid @RequestBody ImportDto data,
                                           @NotNull Principal principal)
             throws TableNotFoundException, DatabaseNotFoundException, TableMalformedException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryMalformedException, UserNotFoundException,
             NotAllowedException, AccessDeniedException, DataDbSidecarException {
         log.debug("endpoint insert data from csv, databaseId={}, tableId={}, data={}, {}", databaseId, tableId, data, PrincipalUtil.formatForDebug(principal));
         /* check */
@@ -112,6 +177,30 @@ public class TableDataEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_table_data_findall")
     @Operation(summary = "Find data", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Get table data successfully"),
+            @ApiResponse(responseCode = "400",
+                    description = "Table data is malformed or image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Access to the database is forbidden",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Table or database could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "422",
+                    description = "Could not import csv via sidecar",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
     public ResponseEntity<QueryResultDto> getAll(@NotNull @PathVariable("databaseId") Long databaseId,
                                                  @NotNull @PathVariable("tableId") Long tableId,
                                                  @NotNull Principal principal,
@@ -120,9 +209,9 @@ public class TableDataEndpoint {
                                                  @RequestParam(required = false) Long size,
                                                  @RequestParam(required = false) SortType sortDirection,
                                                  @RequestParam(required = false) String sortColumn)
-            throws TableNotFoundException, DatabaseNotFoundException, DatabaseConnectionException,
-            ImageNotSupportedException, TableMalformedException, PaginationException, QueryMalformedException,
-            UserNotFoundException, SortException, NotAllowedException, AccessDeniedException {
+            throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
+            TableMalformedException, PaginationException, QueryMalformedException, SortException, NotAllowedException,
+            AccessDeniedException {
         log.debug("endpoint find table data, databaseId={}, tableId={}, timestamp={}, page={}, size={}, sortDirection={}, sortColumn={}, {}",
                 databaseId, tableId, timestamp, page, size, sortDirection, sortColumn, PrincipalUtil.formatForDebug(principal));
         /* check */
@@ -144,13 +233,37 @@ public class TableDataEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_table_data_countall")
     @Operation(summary = "Find data", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "202",
+                    description = "Get table data count successfully"),
+            @ApiResponse(responseCode = "400",
+                    description = "Table data is malformed or image is not supported",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Access to the database is forbidden",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Table or database could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "422",
+                    description = "Could not import csv via sidecar",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+    })
     public ResponseEntity<Long> getCount(@NotNull @PathVariable("databaseId") Long databaseId,
                                          @NotNull @PathVariable("tableId") Long tableId,
                                          @NotNull Principal principal,
                                          @RequestParam(required = false) Instant timestamp)
-            throws TableNotFoundException, DatabaseNotFoundException, DatabaseConnectionException,
-            ImageNotSupportedException, TableMalformedException, QueryStoreException, QueryMalformedException,
-            UserNotFoundException, NotAllowedException, AccessDeniedException {
+            throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
+            TableMalformedException, QueryStoreException, QueryMalformedException, NotAllowedException,
+            AccessDeniedException {
         log.debug("endpoint find table data, databaseId={}, tableId={}, timestamp={}, {}", databaseId, tableId, timestamp, PrincipalUtil.formatForDebug(principal));
         /* check */
         endpointValidator.validateOnlyAccessOrPublic(databaseId, principal);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
index f3a8601a8dab6aba00606da01f2160e6582a6982..e3be34e34746452667def2da8ef63d937d6fdf62 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
@@ -68,13 +68,13 @@ public class TableEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             array = @ArraySchema(schema = @Schema(implementation = TableBriefDto.class)))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Database could not be found",
+            @ApiResponse(responseCode = "403",
+                    description = "List tables not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "List tables not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "Database could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -109,13 +109,13 @@ public class TableEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Database, container or user could not be found",
+            @ApiResponse(responseCode = "403",
+                    description = "Create table not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Create table not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "Database, container or user could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -124,23 +124,13 @@ public class TableEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "501",
-                    description = "Image is not supported",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "504",
-                    description = "Broker service failed to create queue",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<TableBriefDto> create(@NotNull @PathVariable("databaseId") Long databaseId,
                                                 @NotNull @Valid @RequestBody TableCreateDto createDto,
                                                 @NotNull Principal principal)
-            throws ImageNotSupportedException, DatabaseNotFoundException, TableMalformedException, AmqpException,
-            TableNameExistsException, ContainerNotFoundException, UserNotFoundException, QueryMalformedException,
-            NotAllowedException, AccessDeniedException, TableNotFoundException {
+            throws ImageNotSupportedException, DatabaseNotFoundException, TableMalformedException,
+            TableNameExistsException, QueryMalformedException, NotAllowedException, AccessDeniedException,
+            TableNotFoundException {
         log.debug("endpoint create table, databaseId={}, createDto={}, {}", databaseId, createDto, PrincipalUtil.formatForDebug(principal));
         /* checks */
         if (createDto.getName().isBlank()) {
@@ -177,8 +167,8 @@ public class TableEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Find table not permitted",
+            @ApiResponse(responseCode = "503",
+                    description = "Could not communicate with the broker service",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -207,9 +197,7 @@ public class TableEndpoint {
     @ApiResponses(value = {
             @ApiResponse(responseCode = "202",
                     description = "Delete table successfully",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = TableDto.class))}),
+                    content = {@Content}),
             @ApiResponse(responseCode = "400",
                     description = "Delete table query resulted in an invalid query statement",
                     content = {@Content(
@@ -224,29 +212,13 @@ public class TableEndpoint {
                     description = "Table, database or container could not be found",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Delete table not permitted",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "423",
-                    description = "Delete table resulted in an invalid state",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "501",
-                    description = "Image is not supported",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
+                            schema = @Schema(implementation = ApiErrorDto.class))})
     })
-    public ResponseEntity<Void> delete(@NotNull @PathVariable("databaseId") Long databaseId,
+    public ResponseEntity<?> delete(@NotNull @PathVariable("databaseId") Long databaseId,
                                        @NotNull @PathVariable("tableId") Long tableId,
                                        @NotNull Principal principal)
             throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            DataProcessingException, ContainerNotFoundException, TableMalformedException, QueryMalformedException,
-            NotAllowedException {
+            TableMalformedException, QueryMalformedException, NotAllowedException {
         log.debug("endpoint delete table, databaseId={}, tableId={}, {}", databaseId, tableId, PrincipalUtil.formatForDebug(principal));
         final Table table = tableService.find(databaseId, tableId);
         /* roles */
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableHistoryEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableHistoryEndpoint.java
index f3f893fe355f8e78d4e1af28d4a5062bd22ec2c0..727b3f69c3c27d8e1a652445dcbd753bc9f37ddd 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableHistoryEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/TableHistoryEndpoint.java
@@ -51,22 +51,17 @@ public class TableHistoryEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Table, database or user could not be found",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
+            @ApiResponse(responseCode = "403",
                     description = "Find table history is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "503",
-                    description = "Connection to the database failed",
+            @ApiResponse(responseCode = "404",
+                    description = "Table, database or user could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "504",
+            @ApiResponse(responseCode = "409",
                     description = "Query store failed to query table history",
                     content = {@Content(
                             mediaType = "application/json",
@@ -75,8 +70,7 @@ public class TableHistoryEndpoint {
     public ResponseEntity<List<TableHistoryDto>> getAll(@NotNull @PathVariable("databaseId") Long databaseId,
                                                         @NotNull @PathVariable("tableId") Long tableId,
                                                         @NotNull Principal principal)
-            throws TableNotFoundException, QueryMalformedException, DatabaseNotFoundException,
-            QueryStoreException, DatabaseConnectionException, UserNotFoundException {
+            throws TableNotFoundException, QueryMalformedException, DatabaseNotFoundException, QueryStoreException {
         log.debug("endpoint find all history, databaseId={}, tableId={}, {}", databaseId, tableId, PrincipalUtil.formatForDebug(principal));
         final List<TableHistoryDto> history = tableService.findHistory(databaseId, tableId, principal);
         log.trace("find all history resulted in history {}", history);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
index 2d0b400e691058f7385063b7b2da3823335c825e..4b9418005bfd9df475992e37fbff6c1978c371d7 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
@@ -154,20 +154,20 @@ public class UserEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = UserDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "User was not found",
+            @ApiResponse(responseCode = "403",
+                    description = "Find user is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Find user is not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "User was not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<UserDto> find(@NotNull @PathVariable("id") UUID id,
-                                        @NotNull Principal principal) throws UserNotFoundException, NotAllowedException,
-            KeycloakRemoteException, AccessDeniedException {
+                                        @NotNull Principal principal) throws UserNotFoundException,
+            NotAllowedException {
         log.debug("endpoint find a user, id={}, {}", id, PrincipalUtil.formatForDebug(principal));
         /* check */
         final User user = userService.find(id);
@@ -196,13 +196,23 @@ public class UserEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = UserDto.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Modify user query is malformed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Modify user is not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "User attribute was not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "405",
-                    description = "Modify user is not permitted",
+                    description = "Foreign user modification",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -210,8 +220,7 @@ public class UserEndpoint {
     public ResponseEntity<UserDto> modify(@NotNull @PathVariable("id") UUID id,
                                           @NotNull @Valid @RequestBody UserUpdateDto data,
                                           @NotNull Principal principal) throws UserNotFoundException,
-            ForeignUserException, UserAttributeNotFoundException, KeycloakRemoteException, AccessDeniedException,
-            QueryMalformedException, DatabaseMalformedException {
+            ForeignUserException, QueryMalformedException {
         log.debug("endpoint modify a user, id={}, data={}, {}", id, data, PrincipalUtil.formatForDebug(principal));
         /* check */
         if (!id.equals(UserUtil.getId(principal))) {
@@ -238,13 +247,18 @@ public class UserEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = UserDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Modify user is not permitted",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "User or user attribute was not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "405",
-                    description = "Modify user is not permitted",
+                    description = "Foreign user modification",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -278,13 +292,23 @@ public class UserEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = UserDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Modify is not allowed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "404",
                     description = "User was not found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "405",
-                    description = "Modify user is not permitted",
+                    description = "Foreign user modification",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "503",
+                    description = "Authentication service does not respond",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -292,8 +316,7 @@ public class UserEndpoint {
     public ResponseEntity<?> password(@NotNull @PathVariable("id") UUID id,
                                       @NotNull @Valid @RequestBody UserPasswordDto data,
                                       @NotNull Principal principal)
-            throws UserNotFoundException, ForeignUserException, KeycloakRemoteException, AccessDeniedException,
-            QueryMalformedException, DatabaseMalformedException {
+            throws UserNotFoundException, ForeignUserException, KeycloakRemoteException, AccessDeniedException {
         log.debug("endpoint modify a user password, id={}, data={}, {}", id, data, PrincipalUtil.formatForDebug(principal));
         /* check */
         if (!id.equals(UserUtil.getId(principal))) {
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
index cf9ae3a146f444cf0dd29cf2d3925834fcfbabe1..fd379d6afd4468a6cd0fda52b8f349425335c3a6 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
@@ -74,11 +74,6 @@ public class ViewEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Find views is not permitted",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<List<ViewBriefDto>> findAll(@NotNull @PathVariable("databaseId") Long databaseId,
                                                       Principal principal) throws DatabaseNotFoundException,
@@ -172,21 +167,21 @@ public class ViewEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ViewDto.class))}),
-            @ApiResponse(responseCode = "404",
-                    description = "Database, view or user could not be found",
+            @ApiResponse(responseCode = "403",
+                    description = "Find view is not permitted",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Find view is not permitted",
+            @ApiResponse(responseCode = "404",
+                    description = "Database, view or user could not be found",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<ViewDto> find(@NotNull @PathVariable("databaseId") Long databaseId,
                                         @NotNull @PathVariable("viewId") Long viewId,
-                                        Principal principal) throws DatabaseNotFoundException,
-            NotAllowedException, ViewNotFoundException, UserNotFoundException {
+                                        Principal principal) throws DatabaseNotFoundException, ViewNotFoundException,
+            UserNotFoundException {
         log.debug("endpoint find view, databaseId={}, viewId={}, {}", databaseId, viewId, PrincipalUtil.formatForDebug(principal));
         final Database database = databaseService.find(databaseId);
         log.trace("find view for database {}", database);
@@ -209,13 +204,8 @@ public class ViewEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "401",
-                    description = "Credentials missing",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "403",
-                    description = "Credentials missing",
+                    description = "Deletion not allowed",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -243,8 +233,8 @@ public class ViewEndpoint {
     public ResponseEntity<?> delete(@NotNull @PathVariable("databaseId") Long databaseId,
                                     @NotNull @PathVariable("viewId") Long viewId,
                                     @NotNull Principal principal) throws DatabaseNotFoundException,
-            ViewNotFoundException, UserNotFoundException, DatabaseConnectionException,
-            ViewMalformedException, QueryMalformedException, NotAllowedException {
+            ViewNotFoundException, UserNotFoundException, DatabaseConnectionException, ViewMalformedException,
+            QueryMalformedException, NotAllowedException {
         log.debug("endpoint delete view, databaseId={}, viewId={}, {}", databaseId, viewId, PrincipalUtil.formatForDebug(principal));
         /* check */
         final Database database = databaseService.find(databaseId);
@@ -272,13 +262,8 @@ public class ViewEndpoint {
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "401",
-                    description = "Credentials missing",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
             @ApiResponse(responseCode = "403",
-                    description = "Credentials missing",
+                    description = "View data not allowed",
                     content = {@Content(
                             mediaType = "application/json",
                             schema = @Schema(implementation = ApiErrorDto.class))}),
@@ -286,37 +271,7 @@ public class ViewEndpoint {
                     description = "Database, view, container or user could not be found",
                     content = {@Content(
                             mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "405",
-                    description = "Find data is not permitted",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "417",
-                    description = "Parsing of resulting columns failed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "423",
-                    description = "Find data resulted in an invalid query statement",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "501",
-                    description = "Image is not supported",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "503",
-                    description = "Connection to the database failed",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
-            @ApiResponse(responseCode = "504",
-                    description = "Query store failed to query view data",
-                    content = {@Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ApiErrorDto.class))}),
+                            schema = @Schema(implementation = ApiErrorDto.class))})
     })
     public ResponseEntity<QueryResultDto> data(@NotNull @PathVariable("databaseId") Long databaseId,
                                                @NotNull @PathVariable("viewId") Long viewId,
@@ -324,8 +279,7 @@ public class ViewEndpoint {
                                                @RequestParam(required = false) Long page,
                                                @RequestParam(required = false) Long size)
             throws DatabaseNotFoundException, NotAllowedException, ViewNotFoundException, PaginationException,
-            QueryStoreException, DatabaseConnectionException, TableMalformedException, QueryMalformedException,
-            ImageNotSupportedException, ColumnParseException, UserNotFoundException, ContainerNotFoundException, ViewMalformedException {
+            TableMalformedException, QueryMalformedException, UserNotFoundException {
         log.debug("endpoint find view data, databaseId={}, viewId={}, page={}, size={}, {}", databaseId, viewId, page, size, PrincipalUtil.formatForDebug(principal));
         /* check */
         endpointValidator.validateDataParams(page, size);
@@ -354,12 +308,38 @@ public class ViewEndpoint {
     @Transactional(readOnly = true)
     @Observed(name = "dbr_view_data_count")
     @Operation(summary = "Find view data count", security = @SecurityRequirement(name = "bearerAuth"))
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200",
+                    description = "Count data successfully",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = Long.class))}),
+            @ApiResponse(responseCode = "400",
+                    description = "Pagination not in valid range or find data query is malformed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "403",
+                    description = "Count data not allowed",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "404",
+                    description = "Database, view, container or user could not be found",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))}),
+            @ApiResponse(responseCode = "409",
+                    description = "Could not count query data",
+                    content = {@Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ApiErrorDto.class))})
+    })
     public ResponseEntity<Long> count(@NotNull @PathVariable("databaseId") Long databaseId,
                                       @NotNull @PathVariable("viewId") Long viewId,
                                       Principal principal)
-            throws DatabaseNotFoundException, ViewNotFoundException, QueryStoreException, DatabaseConnectionException,
-            TableMalformedException, QueryMalformedException, ImageNotSupportedException, UserNotFoundException,
-            ContainerNotFoundException {
+            throws DatabaseNotFoundException, ViewNotFoundException, QueryStoreException, TableMalformedException,
+            QueryMalformedException, ImageNotSupportedException, UserNotFoundException {
         log.debug("endpoint find view data count, databaseId={}, viewId={}, {}", databaseId, viewId, PrincipalUtil.formatForDebug(principal));
         /* find */
         databaseService.find(databaseId);
diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
index af5c852bfb4037dc0af88d8b06bd069f8a5a778b..5fa79263ba6230f2a1dd54483325a28bf66b9faa 100644
--- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
+++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/validation/EndpointValidator.java
@@ -10,6 +10,7 @@ import at.tuwien.entities.database.AccessType;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.entities.database.table.Table;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.repository.mdb.IdentifierRepository;
 import at.tuwien.service.AccessService;
@@ -30,16 +31,14 @@ import java.util.regex.Pattern;
 public class EndpointValidator {
 
     private final QueryConfig queryConfig;
-    private final IdentifierRepository identifierRepository;
     private final AccessService accessService;
     private final DatabaseService databaseService;
     private final TableService tableService;
 
     @Autowired
-    public EndpointValidator(QueryConfig queryConfig, IdentifierRepository identifierRepository,
-                             AccessService accessService, DatabaseService databaseService, TableService tableService) {
+    public EndpointValidator(QueryConfig queryConfig, AccessService accessService, DatabaseService databaseService,
+                             TableService tableService) {
         this.queryConfig = queryConfig;
-        this.identifierRepository = identifierRepository;
         this.accessService = accessService;
         this.databaseService = databaseService;
         this.tableService = tableService;
@@ -90,7 +89,7 @@ public class EndpointValidator {
                 .filter(c -> needSize.contains(c.getType()))
                 .findFirst();
         if (optional0.isPresent()) {
-            log.error("Validation failed: column {} needs size parameter", optional0.get().getName() );
+            log.error("Validation failed: column {} needs size parameter", optional0.get().getName());
             throw new TableMalformedException("Validation failed: column " + optional0.get().getName() + " needs size parameter");
         }
         /* check size and d */
@@ -153,6 +152,40 @@ public class EndpointValidator {
         }
     }
 
+    public boolean validateOnlyMineOrWriteAccessOrHasRole(UUID ownerId, Principal principal, DatabaseAccess access, String role) {
+        if (UserUtil.hasRole(principal, role)) {
+            log.debug("validation passed: role {} present", role);
+            return true;
+        }
+        if (access == null) {
+            /* should never happen */
+            log.error("validation failed: access is null");
+            return false;
+        }
+        if (ownerId.equals(UserUtil.getId(principal)) && (access.getType().equals(AccessType.WRITE_ALL) || access.getType().equals(AccessType.WRITE_OWN))) {
+            log.debug("validation passed: user id {} matches owner id {} and has write access {}", UserUtil.getId(principal), ownerId, access.getType());
+            return true;
+        }
+        if (access.getType().equals(AccessType.WRITE_ALL)) {
+            log.debug("validation passed: user with id {} has write all access", UserUtil.getId(principal));
+            return true;
+        }
+        log.debug("validation failed: user with id {} has insufficient access {} or role", UserUtil.getId(principal), access.getType());
+        return false;
+    }
+
+    public boolean validateOnlyMineOrReadAccessOrHasRole(UUID ownerId, Principal principal, DatabaseAccess access, String role) {
+        if (validateOnlyMineOrWriteAccessOrHasRole(ownerId, principal, access, role)) {
+            return true;
+        }
+        if (access.getType().equals(AccessType.READ)) {
+            log.debug("validation passed: user with id {} has read access", UserUtil.getId(principal));
+            return true;
+        }
+        log.debug("validation failed: user with id {} has insufficient access {} or role", UserUtil.getId(principal), access.getType());
+        return false;
+    }
+
     public void validateOnlyOwnerOrWriteAll(Long databaseId, Long tableId, Principal principal)
             throws DatabaseNotFoundException, NotAllowedException, TableNotFoundException, AccessDeniedException {
         if (principal == null) {
diff --git a/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore.sql b/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore.sql
index 35808b8eb7ff48df9256a42c2e8361be51fc7f3a..212e262742b7517b3b6e22d319609a0492e8e243 100644
--- a/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore.sql
+++ b/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore.sql
@@ -1,5 +1,5 @@
 CREATE SEQUENCE `qs_queries_seq` NOCACHE;
-CREATE TABLE `qs_queries` ( `id` bigint not null primary key default nextval(`qs_queries_seq`), `created` datetime not null default now(), `executed` datetime not null default now(), `created_by` varchar(255) not null, `query` text not null, `query_normalized` text not null, `is_persisted` boolean not null, `query_hash` varchar(255) not null, `result_hash` varchar(255), `result_number` bigint );
+CREATE TABLE `qs_queries` ( `id` bigint not null primary key default nextval(`qs_queries_seq`), `created` datetime not null default now(), `executed` datetime not null default now(), `created_by` varchar(36) not null, `query` text not null, `query_normalized` text not null, `is_persisted` boolean not null, `query_hash` varchar(255) not null, `result_hash` varchar(255), `result_number` bigint );
 CREATE PROCEDURE hash_table(IN name VARCHAR(255), OUT hash VARCHAR(255), OUT count BIGINT) BEGIN DECLARE _sql TEXT; SELECT CONCAT('SELECT SHA2(GROUP_CONCAT(CONCAT_WS(\'\',', GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name), ') SEPARATOR \',\'), 256) AS hash, COUNT(*) AS count FROM `', name, '` INTO @hash, @count;') FROM `information_schema`.`columns` WHERE `table_schema` = DATABASE() AND `table_name` = name INTO _sql; PREPARE stmt FROM _sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET hash = @hash; SET count = @count; END;
 CREATE PROCEDURE store_query(IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _username varchar(255) DEFAULT REGEXP_REPLACE(current_user(), '@.*', ''); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END;
 CREATE DEFINER = 'root' PROCEDURE _store_query(IN _username VARCHAR(255), IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END;
\ No newline at end of file
diff --git a/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore_manual.sql b/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore_manual.sql
index 1b22fc218c5579e895b3be1fa328a1f2784ea8ce..037701fa15f2eb4f3520d0aeda79c5f8e92a60fe 100644
--- a/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore_manual.sql
+++ b/dbrepo-metadata-service/rest-service/src/main/resources/init/querystore_manual.sql
@@ -3,7 +3,7 @@ CREATE TABLE `qs_queries` (
     `id`               bigint       not null primary key default nextval(`qs_queries_seq`),
     `created`          datetime     not null             default now(),
     `executed`         datetime     not null             default now(),
-    `created_by`       varchar(255) not null,
+    `created_by`       varchar(36)  not null,
     `query`            text         not null,
     `query_normalized` text         not null,
     `is_persisted`     boolean      not null,
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java
index cb900af8acdd7467c76eff1f67e65c8da9243b27..fab3add8f6bc3b103fd9b59d5cbd162ae5903b80 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/config/MariaDbConfig.java
@@ -38,7 +38,7 @@ public class MariaDbConfig {
      * @return The generated or retrieved query id.
      * @throws SQLException The procedure did not succeed.
      */
-    public static Long mockSystemQueryInsert(Database database, String query, String username, String password)
+    public static Long mockSystemQueryInsert(Database database, String query, String username, UUID userId, String password)
             throws SQLException {
         final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName();
         log.trace("connect to database {}", jdbc);
@@ -46,7 +46,7 @@ public class MariaDbConfig {
             final String call = "{call _store_query(?,?,?,?)}";
             log.trace("prepare procedure '{}'", call);
             final CallableStatement statement = connection.prepareCall(call);
-            statement.setString(1, username);
+            statement.setString(1, String.valueOf(userId));
             statement.setString(2, query);
             statement.setTimestamp(3, Timestamp.from(Instant.now()));
             statement.registerOutParameter(4, Types.BIGINT);
@@ -88,17 +88,18 @@ public class MariaDbConfig {
         try (Connection connection = DriverManager.getConnection(jdbc, container.getPrivilegedUsername(), container.getPrivilegedPassword())) {
             final String sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema');";
             log.trace("prepare statement '{}'", sql);
-            final PreparedStatement statement = connection.prepareStatement(sql);
-            final ResultSet resultSet = statement.executeQuery();
+            final PreparedStatement preparedStatement = connection.prepareStatement(sql);
+            final ResultSet resultSet = preparedStatement.executeQuery();
             final List<String> databases = new LinkedList<>();
             while (resultSet.next()) {
                 databases.add(resultSet.getString(1));
             }
             resultSet.close();
-            statement.close();
-            for (String database : databases) {
-                final String drop = "DROP DATABASE IF EXISTS `" + database + "`;";
-                final PreparedStatement dropStatement = connection.prepareStatement(drop);
+            preparedStatement.close();
+            for (String databaseName : databases) {
+                final String statement = "DROP DATABASE IF EXISTS `" + databaseName + "`;";
+                log.trace("drop database {}", databaseName);
+                final PreparedStatement dropStatement = connection.prepareStatement(statement);
                 dropStatement.executeUpdate();
                 dropStatement.close();
             }
@@ -162,7 +163,7 @@ public class MariaDbConfig {
 
     public static String getPrivileges(String hostname, Integer port, String database, String username, String password)
             throws Exception {
-        final String jdbc = "jdbc:mariadb://" + hostname + ":" + port  + (database != null ? "/" + database : "");
+        final String jdbc = "jdbc:mariadb://" + hostname + ":" + port + (database != null ? "/" + database : "");
         log.trace("connect to database {}", jdbc);
         try (Connection connection = DriverManager.getConnection(jdbc, username, password)) {
             final String query = "SHOW GRANTS FOR `" + username + "`;";
@@ -217,16 +218,16 @@ public class MariaDbConfig {
      * @throws SQLException The procedure did not succeed.
      */
     public static Long mockSystemQueryInsert(Database database, String query) throws SQLException {
-        return mockSystemQueryInsert(database, query, database.getContainer().getPrivilegedUsername(), database.getContainer().getPrivilegedPassword());
+        return mockSystemQueryInsert(database, query, database.getContainer().getPrivilegedUsername(), UUID.randomUUID(), database.getContainer().getPrivilegedPassword());
     }
 
-    public static void insertQueryStore(Database database, Query query, String username) throws SQLException {
+    public static void insertQueryStore(Database database, Query query, UUID userId) throws SQLException {
         final String jdbc = "jdbc:mariadb://" + database.getContainer().getHost() + ":" + database.getContainer().getPort() + "/" + database.getInternalName();
         log.trace("connect to database {}", jdbc);
         try (Connection connection = DriverManager.getConnection(jdbc, database.getContainer().getPrivilegedUsername(), database.getContainer().getPrivilegedPassword())) {
             final PreparedStatement prepareStatement = connection.prepareStatement(
                     "INSERT INTO qs_queries (created_by, query, query_normalized, is_persisted, query_hash, result_hash, result_number, created, executed) VALUES (?,?,?,?,?,?,?,?,?)");
-            prepareStatement.setString(1, username);
+            prepareStatement.setString(1, String.valueOf(userId));
             prepareStatement.setString(2, query.getQuery());
             prepareStatement.setString(3, query.getQuery());
             prepareStatement.setBoolean(4, query.getIsPersisted());
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
index f2a7d6d332c727515c189f0ff0a3d2b9a676f456..26c180c5e21457d49e6108326e5d077a55c4d565 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/IdentifierEndpointUnitTest.java
@@ -8,12 +8,14 @@ import at.tuwien.config.EndpointConfig;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.DatabaseAccess;
 import at.tuwien.entities.identifier.Identifier;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.repository.mdb.DatabaseRepository;
 import at.tuwien.repository.mdb.IdentifierRepository;
 import at.tuwien.service.AccessService;
 import at.tuwien.service.IdentifierService;
 import at.tuwien.service.StoreService;
+import at.tuwien.service.UserService;
 import org.apache.commons.io.FileUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -52,6 +54,9 @@ public class IdentifierEndpointUnitTest extends BaseUnitTest {
     @MockBean
     private DatabaseRepository databaseRepository;
 
+    @MockBean
+    private UserService userService;
+
     @MockBean
     private IdentifierRepository identifierRepository;
 
@@ -291,6 +296,8 @@ public class IdentifierEndpointUnitTest extends BaseUnitTest {
                     .when(accessService)
                     .find(databaseId, userId);
         }
+        when(userService.find(USER_1_ID))
+                .thenReturn(USER_1);
         when(storeService.findOne(databaseId, data.getQueryId(), principal))
                 .thenReturn(QUERY_1);
         when(identifierService.create(data, principal))
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/StoreEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/StoreEndpointUnitTest.java
index 62e2b37824f3d28c731e648e645d6019d7cc5f85..5b1278f33c47ea1553e175b7e387881aa66a0d4d 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/StoreEndpointUnitTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/StoreEndpointUnitTest.java
@@ -13,6 +13,7 @@ import at.tuwien.querystore.Query;
 import at.tuwien.repository.mdb.UserRepository;
 import at.tuwien.service.AccessService;
 import at.tuwien.service.DatabaseService;
+import at.tuwien.service.UserService;
 import at.tuwien.service.impl.StoreServiceImpl;
 import lombok.extern.log4j.Log4j2;
 import org.junit.jupiter.api.Test;
@@ -53,6 +54,9 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
     @MockBean
     private DatabaseService databaseService;
 
+    @MockBean
+    private UserService userService;
+
     @MockBean
     private AccessService accessService;
 
@@ -172,13 +176,18 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
             KeycloakRemoteException, AccessDeniedException {
 
         /* mock */
-        when(userRepository.findByUsername(USER_1_USERNAME))
-                .thenReturn(Optional.of(USER_1));
+        when(userService.find(USER_1_ID))
+                .thenReturn(USER_1);
 
         /* test */
         final QueryDto response = find_generic(DATABASE_1_ID, DATABASE_1, QUERY_1_ID, QUERY_1, USER_1_PRINCIPAL);
+        assertNotNull(response.getCreator());
+        assertEquals(DATABASE_1_ID, response.getDatabaseId());
         assertEquals(QUERY_1_ID, response.getId());
+        assertNotNull(response.getIdentifiers());
+        assertTrue(response.getIsPersisted());
         assertEquals(QUERY_1_STATEMENT, response.getQuery());
+        assertNotNull(response.getResultNumber());
     }
 
     @Test
@@ -220,8 +229,8 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = "persist-query")
     public void persist_ownRead_succeeds() throws UserNotFoundException, QueryStoreException,
-            NotAllowedException, DatabaseConnectionException, QueryAlreadyPersistedException, QueryNotFoundException,
-            DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException, AccessDeniedException {
+            NotAllowedException, DatabaseConnectionException, QueryNotFoundException, DatabaseNotFoundException,
+            ImageNotSupportedException, AccessDeniedException, IdentifierAlreadyPublishedException {
 
         /* mock */
         when(userRepository.findByUsername(USER_1_USERNAME))
@@ -236,8 +245,8 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = "persist-query")
     public void persist_ownWriteOwn_succeeds() throws UserNotFoundException, QueryStoreException,
-            NotAllowedException, DatabaseConnectionException, QueryAlreadyPersistedException, QueryNotFoundException,
-            DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException, AccessDeniedException {
+            NotAllowedException, DatabaseConnectionException, QueryNotFoundException, DatabaseNotFoundException,
+            ImageNotSupportedException, AccessDeniedException, IdentifierAlreadyPublishedException {
 
         /* mock */
         when(userRepository.findByUsername(USER_1_USERNAME))
@@ -252,8 +261,8 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
     @Test
     @WithMockUser(username = USER_1_USERNAME, authorities = "persist-query")
     public void persist_ownWriteAll_succeeds() throws UserNotFoundException, QueryStoreException,
-            NotAllowedException, DatabaseConnectionException, QueryAlreadyPersistedException, QueryNotFoundException,
-            DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException, AccessDeniedException {
+            NotAllowedException, DatabaseConnectionException, QueryNotFoundException, DatabaseNotFoundException,
+            ImageNotSupportedException, AccessDeniedException, IdentifierAlreadyPublishedException {
 
         /* mock */
         when(userRepository.findByUsername(USER_1_USERNAME))
@@ -268,8 +277,8 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
     @Test
     @WithMockUser(username = USER_2_USERNAME, authorities = "persist-query")
     public void persist_foreignWriteAll_succeeds() throws UserNotFoundException, QueryStoreException,
-            NotAllowedException, DatabaseConnectionException, QueryAlreadyPersistedException, QueryNotFoundException,
-            DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException, AccessDeniedException {
+            NotAllowedException, DatabaseConnectionException, QueryNotFoundException, DatabaseNotFoundException,
+            ImageNotSupportedException, AccessDeniedException, IdentifierAlreadyPublishedException {
 
         /* mock */
         when(userRepository.findByUsername(USER_1_USERNAME))
@@ -288,7 +297,7 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
                                        UUID userId, Principal principal, DatabaseAccess access)
             throws DatabaseNotFoundException, UserNotFoundException, QueryStoreException, QueryNotFoundException,
             ImageNotSupportedException, NotAllowedException, DatabaseConnectionException,
-            QueryAlreadyPersistedException, KeycloakRemoteException, AccessDeniedException {
+            AccessDeniedException, IdentifierAlreadyPublishedException {
         final QueryPersistDto request = QueryPersistDto.builder()
                 .persist(true)
                 .build();
@@ -323,19 +332,26 @@ public class StoreEndpointUnitTest extends BaseUnitTest {
             AccessDeniedException {
 
         /* mock */
-        doReturn(List.of(QUERY_1)).when(storeService)
-                .findAll(databaseId, true, principal);
+        when(storeService.findAll(databaseId, true, principal))
+                .thenReturn(List.of(QUERY_1));
         when(databaseService.find(databaseId))
                 .thenReturn(database);
+        when(userService.findAll())
+                .thenReturn(List.of(USER_1));
 
         /* test */
         final ResponseEntity<List<QueryBriefDto>> response = storeEndpoint.findAll(databaseId, true, principal);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
         assertEquals(1, response.getBody().size());
-        final QueryBriefDto query = response.getBody().get(0);
-        assertEquals(QUERY_1_ID, query.getId());
-        assertEquals(QUERY_1_STATEMENT, query.getQuery());
+        final QueryBriefDto query0 = response.getBody().get(0);
+        assertNotNull(query0.getCreator());
+        assertEquals(databaseId, query0.getDatabaseId());
+        assertEquals(QUERY_1_ID, query0.getId());
+        assertNotNull(query0.getIdentifiers());
+        assertTrue(query0.getIsPersisted());
+        assertEquals(QUERY_1_STATEMENT, query0.getQuery());
+        assertNotNull(query0.getResultNumber());
     }
 
     protected QueryDto find_generic(Long databaseId, Database database, Long queryId, Query query, Principal principal)
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
index 2a9553b246c09526f2861faca7b58f255f64f371..91dc9c7d9ca5b69ba3f43999082b799912a1a965 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
@@ -35,6 +35,7 @@ import java.sql.SQLException;
 import java.sql.SQLInvalidAuthorizationSpecException;
 import java.util.List;
 import java.util.Optional;
+import java.util.UUID;
 
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.any;
@@ -274,7 +275,7 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
                 .thenReturn("SELECT, CREATE, CREATE VIEW, CREATE ROUTINE, CREATE TEMPORARY TABLES, LOCK TABLES, INDEX, TRIGGER, INSERT, UPDATE, DELETE");
 
         /* test */
-        generic_system_insert(CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD);
+        generic_system_insert(CONTAINER_1_PRIVILEGED_USERNAME, UUID.randomUUID(), CONTAINER_1_PRIVILEGED_PASSWORD);
     }
 
     @Test
@@ -286,7 +287,7 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
 
         /* test */
         assertThrows(SQLException.class, () -> {
-            generic_system_insert("junit1", "junit1");
+            generic_system_insert(USER_1_USERNAME, USER_1_ID, USER_1_PASSWORD);
         });
     }
 
@@ -425,13 +426,13 @@ public class DatabaseServiceIntegrationTest extends BaseUnitTest {
         return response;
     }
 
-    protected void generic_system_insert(String username, String password) throws SQLException, QueryMalformedException {
+    protected void generic_system_insert(String username, UUID userId, String password) throws SQLException, QueryMalformedException {
 
         /* mock */
         mariaDbConfig.grantUserPermissions(CONTAINER_1, DATABASE_3, USER_1_USERNAME);
 
         /* test */
-        final Long queryId = MariaDbConfig.mockSystemQueryInsert(DATABASE_3, QUERY_4_STATEMENT, username, password);
+        final Long queryId = MariaDbConfig.mockSystemQueryInsert(DATABASE_3, QUERY_4_STATEMENT, username, userId, password);
         assertEquals(1L, queryId);
     }
 
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
index bf20c618ecda14fd3a41564849cc5e60a6799939..78298edfea16ae9b62e7f1133e6225d42b754670 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java
@@ -316,7 +316,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest {
             QueryStoreException, ColumnParseException, InterruptedException, KeycloakRemoteException,
             AccessDeniedException, QueryNotFoundException {
         final ExecuteStatementDto request = ExecuteStatementDto.builder()
-                .statement("SELECT n.`firstname`, n.`lastname`, n.`birth`, n.`reminder`, z.`animal_name`, z.`legs` FROM `likes` l JOIN `names` n ON l.`name_id` = n.`id` JOIN `mock_view` z ON z.`id` = l.`zoo_id`")
+                .statement("SELECT n.`firstname`, n.`lastname`, n.`birth`, n.`reminder`, z.`animal_name`, z.`legs` FROM `likes` l JOIN `names` n ON l.`name_id` = n.`id` JOIN `mock_view` z ON z.`id` = l.`zoo_id` ORDER BY animal_name ASC")
                 .build();
 
         /* pre-condition */
@@ -531,12 +531,12 @@ public class QueryServiceIntegrationTest extends BaseUnitTest {
                 .resultNumber(0L)
                 .created(QUERY_1_CREATED)
                 .executed(QUERY_1_EXECUTION)
-                .createdBy(USER_1_USERNAME)
+                .createdBy(USER_1_ID)
                 .isPersisted(true)
                 .build();
 
         /* mock */
-        MariaDbConfig.insertQueryStore(DATABASE_1, query, USER_1_USERNAME);
+        MariaDbConfig.insertQueryStore(DATABASE_1, query, USER_1_ID);
         doNothing()
                 .when(dataDbSidecarGateway)
                 .exportFile(anyString(), anyInt(), anyString());
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationReadTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationReadTest.java
deleted file mode 100644
index aae9e492a7e888f433adc08c592d00c401c15592..0000000000000000000000000000000000000000
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationReadTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package at.tuwien.service;
-
-import at.tuwien.BaseUnitTest;
-import at.tuwien.annotations.MockAmqp;
-import at.tuwien.annotations.MockOpensearch;
-import at.tuwien.config.MariaDbConfig;
-import at.tuwien.config.MariaDbContainerConfig;
-import at.tuwien.exception.*;
-import at.tuwien.querystore.Query;
-import at.tuwien.repository.mdb.DatabaseRepository;
-import lombok.extern.log4j.Log4j2;
-import org.apache.http.auth.BasicUserPrincipal;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.testcontainers.containers.MariaDBContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-import java.security.Principal;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.when;
-
-@Log4j2
-@Testcontainers
-@ExtendWith(SpringExtension.class)
-@EnableAutoConfiguration(exclude= RabbitAutoConfiguration.class)
-@SpringBootTest
-@MockAmqp
-@MockOpensearch
-public class StoreServiceIntegrationReadTest extends BaseUnitTest {
-
-    @MockBean
-    private DatabaseRepository databaseRepository;
-
-    @Autowired
-    private StoreService storeService;
-
-    @Container
-    private static MariaDBContainer<?> mariaDBContainer = MariaDbContainerConfig.getContainer();
-
-    @BeforeAll
-    public static void beforeAll() throws SQLException {
-        /* insert query */
-        MariaDbConfig.dropAllDatabases(CONTAINER_1);
-        MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1);
-        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_USERNAME);
-    }
-
-    @Test
-    public void findAll_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
-            DatabaseNotFoundException, ImageNotSupportedException, TableMalformedException, ContainerNotFoundException {
-
-        /* mock */
-        when(databaseRepository.findById(DATABASE_1_ID))
-                .thenReturn(Optional.of(DATABASE_1));
-
-        /* test */
-        final List<Query> queries = storeService.findAll(DATABASE_1_ID, null, USER_1_PRINCIPAL);
-        assertEquals(1, queries.size());
-    }
-
-    @Test
-    public void findAll_filterPersisted_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
-            DatabaseNotFoundException, ImageNotSupportedException, TableMalformedException, ContainerNotFoundException {
-
-        /* mock */
-        when(databaseRepository.findById(DATABASE_1_ID))
-                .thenReturn(Optional.of(DATABASE_1));
-
-        /* test */
-        final List<Query> queries = storeService.findAll(DATABASE_1_ID, true, USER_1_PRINCIPAL);
-        assertEquals(0, queries.size());
-    }
-
-    @Test
-    public void findOne_succeeds() throws UserNotFoundException, QueryStoreException,
-            DatabaseConnectionException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException {
-
-        /* mock */
-        when(databaseRepository.findById(DATABASE_1_ID))
-                .thenReturn(Optional.of(DATABASE_1));
-
-        /* test */
-        storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
-    }
-
-    @Test
-    public void findOne_notFound_succeeds() {
-
-        /* mock */
-        when(databaseRepository.findById(DATABASE_1_ID))
-                .thenReturn(Optional.of(DATABASE_1));
-
-        /* test */
-        assertThrows(QueryNotFoundException.class, () -> {
-            storeService.findOne(DATABASE_1_ID, 9999L, USER_1_PRINCIPAL);
-        });
-    }
-
-    @Test
-    public void findOne_notFound_fails() {
-        final Principal principal = new BasicUserPrincipal(USER_1_USERNAME);
-
-        /* mock */
-        when(databaseRepository.findById(DATABASE_1_ID))
-                .thenReturn(Optional.of(DATABASE_1));
-
-        /* test */
-        assertThrows(QueryNotFoundException.class, () -> {
-            storeService.findOne(DATABASE_1_ID, QUERY_2_ID, principal);
-        });
-    }
-
-}
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java
index 21da3ad82178f5ae9f750106610b083f782db0ef..e12e7b1b6ba945c72d68f18e5e83e764b94a7956 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java
@@ -3,14 +3,19 @@ package at.tuwien.service;
 import at.tuwien.BaseUnitTest;
 import at.tuwien.annotations.MockAmqp;
 import at.tuwien.annotations.MockOpensearch;
+import at.tuwien.api.database.query.ExecuteStatementDto;
 import at.tuwien.api.database.query.QueryPersistDto;
+import at.tuwien.api.database.query.QueryResultDto;
 import at.tuwien.config.MariaDbConfig;
 import at.tuwien.config.MariaDbContainerConfig;
 import at.tuwien.exception.*;
 import at.tuwien.querystore.Query;
 import at.tuwien.repository.mdb.*;
+import com.github.jsonldjava.utils.Obj;
 import lombok.extern.log4j.Log4j2;
+import org.apache.http.auth.BasicUserPrincipal;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,8 +26,12 @@ import org.testcontainers.containers.MariaDBContainer;
 import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 
+import java.security.Principal;
 import java.sql.SQLException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.List;
+import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.*;
 
@@ -47,6 +56,9 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
     @Autowired
     private LicenseRepository licenseRepository;
 
+    @Autowired
+    private QueryService queryService;
+
     @Autowired
     private UserRepository userRepository;
 
@@ -64,7 +76,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
         TABLE_4.setColumns(TABLE_4_COLUMNS);
         /* metadata database */
         imageRepository.save(IMAGE_1);
-        userRepository.save(USER_1);
+        userRepository.saveAll(List.of(USER_1, USER_2, USER_3, USER_4, USER_5));
         licenseRepository.save(LICENSE_1);
         containerRepository.save(CONTAINER_1);
         DATABASE_1.setAccesses(List.of());
@@ -72,8 +84,35 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
         /* data stuff */
         MariaDbConfig.dropAllDatabases(CONTAINER_1);
         MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1);
-        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_USERNAME);
-        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_3, USER_1_USERNAME);
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_ID);
+    }
+
+    @Test
+    public void findAll_filterPersisted_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
+            DatabaseNotFoundException, ImageNotSupportedException, TableMalformedException, ContainerNotFoundException {
+
+        /* test */
+        final List<Query> queries = storeService.findAll(DATABASE_1_ID, true, USER_1_PRINCIPAL);
+        assertEquals(1, queries.size());
+    }
+
+    @Test
+    public void findOne_notFound_succeeds() {
+
+        /* test */
+        assertThrows(QueryNotFoundException.class, () -> {
+            storeService.findOne(DATABASE_1_ID, 9999L, USER_1_PRINCIPAL);
+        });
+    }
+
+    @Test
+    public void findOne_notFound_fails() {
+        final Principal principal = new BasicUserPrincipal(USER_1_USERNAME);
+
+        /* test */
+        assertThrows(QueryNotFoundException.class, () -> {
+            storeService.findOne(DATABASE_1_ID, 9999L, principal);
+        });
     }
 
     @Test
@@ -83,7 +122,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
 
         /* test */
         final List<Query> response = storeService.findAll(DATABASE_1_ID, null, USER_1_PRINCIPAL);
-        assertEquals(2, response.size());
+        assertEquals(1, response.size());
     }
 
     @Test
@@ -103,16 +142,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
 
         /* test */
         final List<Query> response = storeService.findAll(DATABASE_1_ID, false, USER_1_PRINCIPAL);
-        assertEquals(1, response.size());
-    }
-
-    @Test
-    public void findOne_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
-            DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException {
-
-        /* test */
-        final Query response = storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
-        assertNotNull(response);
+        assertEquals(0, response.size());
     }
 
     @Test
@@ -126,14 +156,15 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
 
     @Test
     public void persist_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
-            DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException {
+            DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException,
+            IdentifierAlreadyPublishedException {
         final QueryPersistDto request = QueryPersistDto.builder()
                 .persist(true)
                 .build();
 
         /* precondition */
-        final Query query3 = storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
-        assertFalse(query3.getIsPersisted());
+        final Query query1 = storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
+        assertTrue(query1.getIsPersisted());
 
         /* test */
         final Query response = storeService.persist(DATABASE_1_ID, QUERY_1_ID, request);
@@ -142,19 +173,249 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
     }
 
     @Test
-    public void persist_unchanged_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
-            DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException {
+    public void persist_unPersistUnchanged_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException,
+            IdentifierAlreadyPublishedException, SQLException {
+        final Query query = Query.builder()
+                .id(2L)
+                .query(QUERY_3_STATEMENT)
+                .queryHash(QUERY_3_QUERY_HASH)
+                .resultHash(QUERY_3_RESULT_HASH)
+                .created(QUERY_3_CREATED)
+                .executed(QUERY_3_EXECUTION)
+                .createdBy(USER_1_ID)
+                .resultNumber(QUERY_3_RESULT_NUMBER)
+                .isPersisted(false) // <<<<<<<
+                .build();
         final QueryPersistDto request = QueryPersistDto.builder()
                 .persist(false) // <<<<<<<
                 .build();
 
+        /* mock */
+        MariaDbConfig.insertQueryStore(DATABASE_1, query, USER_1_ID);
+
         /* precondition */
-        final Query query3 = storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
-        assertFalse(query3.getIsPersisted());
+        final Query query2 = storeService.findOne(DATABASE_1_ID, 2L, USER_1_PRINCIPAL);
+        assertFalse(query2.getIsPersisted());
 
         /* test */
-        final Query response = storeService.persist(DATABASE_1_ID, QUERY_1_ID, request);
+        final Query response = storeService.persist(DATABASE_1_ID, 2L, request);
         assertNotNull(response);
         assertFalse(response.getIsPersisted());
     }
+
+    @Test
+    public void persist_unPersistIdentifierAlreadyAttached_fails () {
+        final QueryPersistDto request = QueryPersistDto.builder()
+                .persist(false)
+                .build();
+
+        /* test */
+        assertThrows(IdentifierAlreadyPublishedException.class, () -> {
+            storeService.persist(DATABASE_1_ID, QUERY_1_ID, request);
+        });
+    }
+
+    @Test
+    public void insert_same_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
+            DatabaseNotFoundException, ImageNotSupportedException, SQLException, KeycloakRemoteException,
+            AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_2_STATEMENT)
+                .build();
+
+        /* test */
+        final Query response = storeService.insert(DATABASE_1_ID, request, USER_1_PRINCIPAL);
+        log.debug("found queries in query store: {}", MariaDbConfig.selectQuery(DATABASE_1,
+                "SELECT `query_normalized`, `query_hash`, `result_hash` FROM `qs_queries`", "query_normalized", "query_hash", "result_hash"));
+        assertEquals(QUERY_1_ID, response.getId()) /* no new query inserted */;
+    }
+
+    @Test
+    public void execute_differentResult_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, ColumnParseException, KeycloakRemoteException, AccessDeniedException,
+            QueryNotFoundException, SQLException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .build();
+
+        /* mock */
+        MariaDbConfig.execute(DATABASE_1, "INSERT INTO `weather_aus` (`id`, `date`) VALUES (4, '2024-01-12');");
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        assertEquals(2L, response.getId()) /* new query inserted */;
+    }
+
+    @Test
+    @Disabled("not testable")
+    public void execute_same_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
+            TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException,
+            ColumnParseException, KeycloakRemoteException, AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .build();
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        assertEquals(1L, response.getId()) /* no new query inserted */;
+    }
+
+    @Test
+    @Disabled("not testable")
+    public void execute_notPersisted_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, ColumnParseException, SQLException, KeycloakRemoteException,
+            AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .build();
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        assertEquals(1L, response.getId()) /* no new query inserted */;
+        assertFalse(Boolean.parseBoolean(MariaDbConfig.listQueryStore(DATABASE_1).get(0).get("is_persisted").toString()));
+    }
+
+    @Test
+    public void execute_emptyResult_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, ColumnParseException, KeycloakRemoteException, AccessDeniedException,
+            QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement("SELECT `id`, `date`, `location`, `mintemp`, `rainfall` FROM `weather_aus` WHERE `location` = 'Wien'")
+                .build();
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        assertEquals(2L, response.getId()) /* new query inserted */;
+    }
+
+    @Test
+    public void execute_emptyResultTwice_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, ColumnParseException, KeycloakRemoteException, AccessDeniedException,
+            QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement("SELECT `location`, `mintemp` FROM `weather_aus` WHERE `rainfall` < 0")
+                .build();
+
+        /* mock */
+        queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        assertEquals(2L, response.getId()) /* no new query inserted */;
+    }
+
+    @Test
+    public void execute_dataChangeSameQuery_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, ColumnParseException, SQLException, KeycloakRemoteException,
+            AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .build();
+
+        /* mock */
+        queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        MariaDbConfig.execute(DATABASE_1, "INSERT INTO weather_aus (id, `date`, location, mintemp, rainfall) VALUES (4, '2008-12-04', 'Albury', 12.9, 0.2)");
+
+        /* test */
+        storeService.insert(DATABASE_1_ID, request, USER_1_PRINCIPAL);
+    }
+
+    @Test
+    public void execute_semicolon_fails() {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT + ";")
+                .build();
+
+        /* test */
+        assertThrows(QueryMalformedException.class, () -> {
+            queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 10L, null, null);
+        });
+    }
+
+    @Test
+    public void persist_alreadyPersisted_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, SQLException,
+            IdentifierAlreadyPublishedException {
+        final QueryPersistDto request = QueryPersistDto.builder()
+                .persist(true)
+                .build();
+
+        /* mock */
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_ID);
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_2, USER_1_ID);
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_3, USER_1_ID);
+
+        /* test */
+        final Query response = storeService.persist(DATABASE_1_ID, QUERY_3_ID, request);
+        assertTrue(response.getIsPersisted());
+    }
+
+    @Test
+    public void persist_unPersist_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, SQLException,
+            IdentifierAlreadyPublishedException {
+        final QueryPersistDto request = QueryPersistDto.builder()
+                .persist(false)
+                .build();
+
+        /* mock */
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_ID);
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_2, USER_1_ID);
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_3, USER_1_ID);
+
+        /* test */
+        final Query response = storeService.persist(DATABASE_1_ID, QUERY_3_ID, request);
+        assertFalse(response.getIsPersisted());
+    }
+
+    @Test
+    public void insert_timestamp_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException,
+            AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .timestamp(Instant.now().plus(1, ChronoUnit.SECONDS))
+                .build();
+
+        /* test */
+        storeService.insert(DATABASE_1_ID, request, USER_1_PRINCIPAL);
+    }
+
+    @Test
+    public void insert_anonymous_succeeds() throws UserNotFoundException, QueryStoreException,
+            DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, KeycloakRemoteException,
+            AccessDeniedException, QueryNotFoundException {
+        final ExecuteStatementDto request = ExecuteStatementDto.builder()
+                .statement(QUERY_1_STATEMENT)
+                .build();
+
+        /* test */
+        storeService.insert(DATABASE_1_ID, request, null);
+    }
+
+    @Test
+    public void findOne_succeeds() throws UserNotFoundException, QueryStoreException, DatabaseConnectionException,
+            QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException, SQLException {
+
+        /* mock */
+        MariaDbConfig.insertQueryStore(DATABASE_1, QUERY_1, USER_1_ID);
+
+        /* test */
+        storeService.findOne(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL);
+    }
+
+    @Test
+    public void deleteStaleQueries_succeeds() throws QueryStoreException, ImageNotSupportedException, SQLException {
+
+        /* test */
+        storeService.deleteStaleQueries();
+        final List<Map<String, Object>> response = MariaDbConfig.listQueryStore(DATABASE_1);
+        assertEquals(1, response.size());
+    }
 }
diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
index fd19d92df0b74fc5ed329bc4954311243a48576a..8ef2a0ce4ad5bf39739c24123b651de325383f3a 100644
--- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
+++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java
@@ -139,218 +139,15 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest {
 
     @Test
     public void create_full_succeeds() throws Exception {
-        final TableCreateDto request = TableCreateDto.builder()
-                .name("full")
-                .description("full example")
-                .constraints(ConstraintsCreateDto.builder()
-                        .uniques(List.of())
-                        .foreignKeys(List.of())
-                        .build())
-                .columns(List.of(ColumnCreateDto.builder()
-                                .name("col1a")
-                                .type(ColumnTypeDto.CHAR)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col1b")
-                                .type(ColumnTypeDto.CHAR)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .size(50L)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col2a")
-                                .type(ColumnTypeDto.VARCHAR)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col2b")
-                                .type(ColumnTypeDto.VARCHAR)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .size(1024L)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col3")
-                                .type(ColumnTypeDto.BINARY)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col4")
-                                .type(ColumnTypeDto.VARBINARY)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .size(200L)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col5")
-                                .type(ColumnTypeDto.TINYBLOB)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col6")
-                                .type(ColumnTypeDto.TINYTEXT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col7")
-                                .type(ColumnTypeDto.TEXT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col8")
-                                .type(ColumnTypeDto.BLOB)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col9")
-                                .type(ColumnTypeDto.MEDIUMTEXT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col10")
-                                .type(ColumnTypeDto.MEDIUMBLOB)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col11")
-                                .type(ColumnTypeDto.LONGTEXT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col12")
-                                .type(ColumnTypeDto.LONGBLOB)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col13")
-                                .type(ColumnTypeDto.ENUM)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .enums(List.of("val1", "val2"))
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col14")
-                                .type(ColumnTypeDto.SET)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .sets(List.of("val1", "val2"))
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col15")
-                                .type(ColumnTypeDto.BIT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col16")
-                                .type(ColumnTypeDto.TINYINT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col17")
-                                .type(ColumnTypeDto.BOOL)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col18")
-                                .type(ColumnTypeDto.SMALLINT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col19")
-                                .type(ColumnTypeDto.MEDIUMINT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col20")
-                                .type(ColumnTypeDto.INT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col21")
-                                .type(ColumnTypeDto.BIGINT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col22")
-                                .type(ColumnTypeDto.FLOAT)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col23")
-                                .type(ColumnTypeDto.DOUBLE)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col24")
-                                .type(ColumnTypeDto.DECIMAL)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col25")
-                                .type(ColumnTypeDto.DATE)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .dfid(IMAGE_DATE_1_ID)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col26")
-                                .type(ColumnTypeDto.DATETIME)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .dfid(IMAGE_DATE_3_ID)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col27")
-                                .type(ColumnTypeDto.TIMESTAMP)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .dfid(IMAGE_DATE_3_ID)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col28")
-                                .type(ColumnTypeDto.TIME)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .dfid(IMAGE_DATE_4_ID)
-                                .build(),
-                        ColumnCreateDto.builder()
-                                .name("col29")
-                                .type(ColumnTypeDto.YEAR)
-                                .nullAllowed(true)
-                                .primaryKey(false)
-                                .build()))
-                .build();
 
         /* test */
-        final Table response = tableService.createTable(DATABASE_1_ID, request, USER_1_PRINCIPAL);
+        final Table response = tableService.createTable(DATABASE_1_ID, TABLE_0_CREATE_DTO, USER_1_PRINCIPAL);
         assertNotNull(response.getId());
         assertEquals("full", response.getInternalName());
         assertEquals("full example", response.getDescription());
         assertEquals(32, response.getColumns().size());
-        for (int i = 1; i < request.getColumns().size(); i++) {
-            final ColumnCreateDto expected = request.getColumns().get(i);
+        for (int i = 1; i < TABLE_0_CREATE_DTO.getColumns().size(); i++) {
+            final ColumnCreateDto expected = TABLE_0_CREATE_DTO.getColumns().get(i);
             final TableColumn result = response.getColumns().get(i);
             assertEquals(expected.getName(), result.getName());
             assertEquals(expected.getType(), tableMapper.columnTypeToColumnTypeDto(result.getColumnType()));
@@ -373,7 +170,7 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest {
         }
         final Map<String, List<Object>> schema = MariaDbConfig.describeTableSchema(response, CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD);
         for (Map.Entry<String, List<Object>> entry : schema.entrySet()) {
-            final ColumnCreateDto columnRequest = request.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get();
+            final ColumnCreateDto columnRequest = TABLE_0_CREATE_DTO.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get();
             final TableColumn columnEntity = response.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get();
             final List<Object> columnSchema = schema.get(columnEntity.getInternalName());
             if (columnEntity.getInternalName().equals("id")) {
@@ -428,6 +225,17 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest {
         tableService.deleteTable(DATABASE_1_ID, TABLE_1_ID);
     }
 
+    @Test
+    @Transactional
+    public void delete_full_succeeds() throws TableNotFoundException, TableMalformedException, QueryMalformedException,
+            DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException, TableNameExistsException,
+            ContainerNotFoundException {
+
+        /* test */
+        final Table response = tableService.createTable(DATABASE_1_ID, TABLE_0_CREATE_DTO, USER_1_PRINCIPAL);
+        tableService.deleteTable(DATABASE_1_ID, response.getId());
+    }
+
     @Test
     @Transactional
     public void delete_hasIdentifier_succeeds() throws TableNotFoundException, TableMalformedException,
diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/application.properties b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
index 0b6850a3e4f42d2547eb1fa123c7ed6089bbab05..0c0fab40c34a920f03a7c48022a4b0bfe4c8de0c 100644
--- a/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
+++ b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties
@@ -16,7 +16,7 @@ spring.jpa.hibernate.ddl-auto=create
 
 # logging
 logging.level.root=error
-logging.level.at.tuwien.=info
+logging.level.at.tuwien.=debug
 
 # rabbitmq
 spring.rabbitmq.host=localhost
diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/init/querystore.sql b/dbrepo-metadata-service/rest-service/src/test/resources/init/querystore.sql
index 35808b8eb7ff48df9256a42c2e8361be51fc7f3a..212e262742b7517b3b6e22d319609a0492e8e243 100644
--- a/dbrepo-metadata-service/rest-service/src/test/resources/init/querystore.sql
+++ b/dbrepo-metadata-service/rest-service/src/test/resources/init/querystore.sql
@@ -1,5 +1,5 @@
 CREATE SEQUENCE `qs_queries_seq` NOCACHE;
-CREATE TABLE `qs_queries` ( `id` bigint not null primary key default nextval(`qs_queries_seq`), `created` datetime not null default now(), `executed` datetime not null default now(), `created_by` varchar(255) not null, `query` text not null, `query_normalized` text not null, `is_persisted` boolean not null, `query_hash` varchar(255) not null, `result_hash` varchar(255), `result_number` bigint );
+CREATE TABLE `qs_queries` ( `id` bigint not null primary key default nextval(`qs_queries_seq`), `created` datetime not null default now(), `executed` datetime not null default now(), `created_by` varchar(36) not null, `query` text not null, `query_normalized` text not null, `is_persisted` boolean not null, `query_hash` varchar(255) not null, `result_hash` varchar(255), `result_number` bigint );
 CREATE PROCEDURE hash_table(IN name VARCHAR(255), OUT hash VARCHAR(255), OUT count BIGINT) BEGIN DECLARE _sql TEXT; SELECT CONCAT('SELECT SHA2(GROUP_CONCAT(CONCAT_WS(\'\',', GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name), ') SEPARATOR \',\'), 256) AS hash, COUNT(*) AS count FROM `', name, '` INTO @hash, @count;') FROM `information_schema`.`columns` WHERE `table_schema` = DATABASE() AND `table_name` = name INTO _sql; PREPARE stmt FROM _sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET hash = @hash; SET count = @count; END;
 CREATE PROCEDURE store_query(IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _username varchar(255) DEFAULT REGEXP_REPLACE(current_user(), '@.*', ''); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END;
 CREATE DEFINER = 'root' PROCEDURE _store_query(IN _username VARCHAR(255), IN query TEXT, IN executed DATETIME, OUT queryId BIGINT) BEGIN DECLARE _queryhash varchar(255) DEFAULT SHA2(query, 256); DECLARE _query TEXT DEFAULT CONCAT('CREATE OR REPLACE TABLE _tmp AS (', query, ')'); PREPARE stmt FROM _query; EXECUTE stmt; DEALLOCATE PREPARE stmt; CALL hash_table('_tmp', @hash, @count); DROP TABLE IF EXISTS `_tmp`; IF @hash IS NULL THEN INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` IS NULL); ELSE INSERT INTO `qs_queries` (`created_by`, `query`, `query_normalized`, `is_persisted`, `query_hash`, `result_hash`, `result_number`, `executed`) SELECT _username, query, query, false, _queryhash, @hash, @count, executed WHERE NOT EXISTS (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); SET queryId = (SELECT `id` FROM `qs_queries` WHERE `query_hash` = _queryhash AND `result_hash` = @hash); END IF; END;
\ No newline at end of file
diff --git a/dbrepo-metadata-service/services/pom.xml b/dbrepo-metadata-service/services/pom.xml
index 5fd908ca79cd63351f4b969da505711dd151c60f..5fcb23cc55f9636ee70d5321728976ffa43c347b 100644
--- a/dbrepo-metadata-service/services/pom.xml
+++ b/dbrepo-metadata-service/services/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <artifactId>dbrepo-metadata-service</artifactId>
         <groupId>at.tuwien</groupId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-services</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-services</name>
 
     <dependencies>
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/amqp/RabbitMqConsumer.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/amqp/RabbitMqConsumer.java
deleted file mode 100644
index 0f32e23535458cb25e2e2fc78e21c55f10c74986..0000000000000000000000000000000000000000
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/amqp/RabbitMqConsumer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package at.tuwien.amqp;
-
-import at.tuwien.api.database.table.TableCsvDto;
-import at.tuwien.exception.*;
-import at.tuwien.service.QueryService;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.rabbitmq.client.AMQP;
-import com.rabbitmq.client.Consumer;
-import com.rabbitmq.client.Envelope;
-import com.rabbitmq.client.ShutdownSignalException;
-import lombok.extern.log4j.Log4j2;
-import org.apache.http.auth.BasicUserPrincipal;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.HttpClientErrorException;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-@Log4j2
-public class RabbitMqConsumer implements Consumer {
-
-    private final Long databaseId;
-    private final Long tableId;
-    private final ObjectMapper objectMapper;
-    private final QueryService queryService;
-
-    public RabbitMqConsumer(Long databaseId, Long tableId, ObjectMapper objectMapper, QueryService queryService) {
-        this.databaseId = databaseId;
-        this.tableId = tableId;
-        this.objectMapper = objectMapper;
-        this.queryService = queryService;
-    }
-
-    @Override
-    public void handleConsumeOk(String consumerTag) {
-        //
-    }
-
-    @Override
-    public void handleCancelOk(String consumerTag) {
-        //
-    }
-
-    @Override
-    public void handleCancel(String consumerTag) {
-        //
-    }
-
-    @Override
-    public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {
-        //
-    }
-
-    @Override
-    public void handleRecoverOk(String consumerTag) {
-        //
-    }
-
-    @Override
-    @Transactional(readOnly = true)
-    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
-            throws IOException {
-        log.trace("handle delivery of tuple, consumerTag={}, envelope={}, properties={}, body=(bytes)",
-                consumerTag, envelope, properties);
-        final TypeReference<HashMap<String, Object>> payloadReference = new TypeReference<>() {
-        };
-        final TableCsvDto data = TableCsvDto.builder()
-                .data(objectMapper.readValue(body, payloadReference))
-                .build();
-        log.trace("received tuple data {}", data);
-        try {
-            queryService.insert(databaseId, tableId, data, new BasicUserPrincipal(properties.getUserId()));
-        } catch (HttpClientErrorException.Unauthorized e) {
-            log.error("Failed to authenticate for table with id {}, reason: {}", tableId, e.getMessage());
-            throw new IOException("Failed to authenticate for table", e);
-        } catch (HttpClientErrorException.BadRequest e) {
-            log.error("Failed to insert for table with id {}, reason: {}", tableId, e.getMessage());
-            throw new IOException("Failed to insert for table", e);
-        } catch (TableNotFoundException e) {
-            log.error("Failed to find table with id {}, reason: {}", tableId, e.getMessage());
-            throw new IOException("Failed to find table", e);
-        } catch (TableMalformedException e) {
-            log.error("Tuple columns do not match table columns with table id {}, reason: {}", tableId, e.getMessage());
-            throw new IOException("Tuple columns do not match table columns", e);
-        } catch (DatabaseNotFoundException e) {
-            log.error("Failed to find database with id {}, reason: {}", databaseId, e.getMessage());
-            throw new IOException("Failed to find database", e);
-        } catch (ImageNotSupportedException e) {
-            log.error("Image is not supported");
-            throw new IOException("Image is not supported", e);
-        } catch (DatabaseConnectionException e) {
-            log.error("Failed to connect to database, reason: {}", e.getMessage());
-            throw new IOException("Failed to connect to container", e);
-        } catch (UserNotFoundException e) {
-            log.error("Failed to find user with id {}", properties.getUserId());
-            throw new IOException("Failed to find user", e);
-        }
-    }
-
-}
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AccessService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AccessService.java
index 380bf8330940f3dc8f765389c61712b56763eee2..86df08020442982606ef7f1f2b5fa349f1cabb2e 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AccessService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AccessService.java
@@ -15,6 +15,7 @@ public interface AccessService {
      *
      * @param databaseId The database id.
      * @return The list of database access definitions.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
      */
     List<DatabaseAccess> list(Long databaseId) throws DatabaseNotFoundException;
 
@@ -24,7 +25,8 @@ public interface AccessService {
      * @param databaseId The database id.
      * @param userId     The user id.
      * @return The database access.
-     * @throws AccessDeniedException The access does not exist.
+     * @throws AccessDeniedException     The access does not exist.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
      */
     DatabaseAccess find(Long databaseId, UUID userId) throws AccessDeniedException, DatabaseNotFoundException;
 
@@ -56,8 +58,7 @@ public interface AccessService {
      * @throws DatabaseMalformedException The database has an invalid state.
      */
     void update(Long databaseId, UUID userId, DatabaseModifyAccessDto accessDto) throws DatabaseNotFoundException,
-            UserNotFoundException, QueryMalformedException, DatabaseMalformedException,
-            NotAllowedException;
+            UserNotFoundException, QueryMalformedException, DatabaseMalformedException, NotAllowedException;
 
     /**
      * Revokes access to a database of container.
@@ -69,6 +70,7 @@ public interface AccessService {
      * @throws NotAllowedException        The access is not allowed.
      * @throws QueryMalformedException    The mapped access query is malformed.
      * @throws DatabaseMalformedException The database has an invalid state.
+     * @throws AccessDeniedException      The access to the database was denied.
      */
     void delete(Long databaseId, UUID userId) throws DatabaseNotFoundException, UserNotFoundException,
             NotAllowedException, QueryMalformedException, DatabaseMalformedException, AccessDeniedException;
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java
index a39e0d66c20348a35d5d2fcafbbd7ab1a364fd85..d98869850fde3a2f7921ab6d4db0851572c1d8b7 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/AuthenticationService.java
@@ -43,5 +43,13 @@ public interface AuthenticationService {
     UserDto findByUsername(String username) throws UserNotFoundException, KeycloakRemoteException,
             AccessDeniedException;
 
+    /**
+     * Updates the password of a user with given id.
+     *
+     * @param id   The user id.
+     * @param data The new password.
+     * @throws KeycloakRemoteException The Authentication Service was not able to respond within the 3s timeout.
+     * @throws AccessDeniedException   The admin token could not be obtained.
+     */
     void updatePassword(UUID id, UserPasswordDto data) throws KeycloakRemoteException, AccessDeniedException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/DatabaseService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/DatabaseService.java
index 430f4b62504bfc0d834eb841e7d91bbfc028ecd6..e013d982743af03509b703609d59298fe94d269b 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/DatabaseService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/DatabaseService.java
@@ -63,20 +63,13 @@ public interface DatabaseService {
      *
      * @param createDto The metadata.
      * @return The database, if successful.
-     * @throws ImageNotSupportedException   The image is not supported.
-     * @throws ContainerNotFoundException   The container was not found in the metadata database.
-     * @throws DatabaseMalformedException   The query string is malformed.
-     * @throws AmqpException                The exchange could not be created.
-     * @throws ContainerConnectionException The connection to the container could not be established.
-     * @throws UserNotFoundException        The current user could not be loaded in the metadata database.
-     * @throws DatabaseNameExistsException  A database with this name already exists in the container.
-     * @throws DatabaseConnectionException  The connection to the database could not be established by the database connector.
-     * @throws QueryMalformedException      The mapped creation query resulted in an invalid query statement and thus was rejected by the database engine.
+     * @throws ContainerNotFoundException The container was not found in the metadata database.
+     * @throws DatabaseMalformedException The query string is malformed.
+     * @throws UserNotFoundException      The current user could not be loaded in the metadata database.
+     * @throws QueryMalformedException    The mapped creation query resulted in an invalid query statement and thus was rejected by the database engine.
      */
-    Database create(DatabaseCreateDto createDto, Principal principal) throws ImageNotSupportedException,
-            ContainerNotFoundException, DatabaseMalformedException, AmqpException, ContainerConnectionException,
-            UserNotFoundException, DatabaseNameExistsException, DatabaseConnectionException, QueryMalformedException,
-            KeycloakRemoteException, AccessDeniedException;
+    Database create(DatabaseCreateDto createDto, Principal principal) throws ContainerNotFoundException,
+            DatabaseMalformedException, UserNotFoundException, QueryMalformedException;
 
     /**
      * Updates the user's password.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/EntityService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/EntityService.java
index d8f4e2f306dfee9568186ae2ea6b1466b68e29e2..947b9660312c6a202adf967890b7c65e9477452b 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/EntityService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/EntityService.java
@@ -9,18 +9,81 @@ import java.util.List;
 
 public interface EntityService {
 
+    /**
+     * Finds entities in the ontology whose label match the given label.
+     *
+     * @param ontology The ontology.
+     * @param label    The label.
+     * @return The list of entities that match.
+     * @throws QueryMalformedException  The SPARQL query is malformed.
+     * @throws OntologyInvalidException The given ontology is invalid.
+     */
     List<EntityDto> findByLabel(Ontology ontology, String label) throws QueryMalformedException, OntologyInvalidException;
 
+    /**
+     * Finds entities in the ontology whose label match the given label with maximum number of entities.
+     *
+     * @param ontology The ontology.
+     * @param label    The label.
+     * @param limit    The maximum number of entities to return.
+     * @return The list of entities that match.
+     * @throws QueryMalformedException  The SPARQL query is malformed.
+     * @throws OntologyInvalidException The given ontology is invalid.
+     */
     List<EntityDto> findByLabel(Ontology ontology, String label, Integer limit) throws QueryMalformedException, OntologyInvalidException;
 
+    /**
+     * Finds entities in the ontology whose uri match the given uri.
+     *
+     * @param ontology The ontology.
+     * @param uri      The uri.
+     * @return The list of entities that match.
+     * @throws QueryMalformedException  The SPARQL query is malformed.
+     * @throws OntologyInvalidException The given ontology is invalid.
+     */
     List<EntityDto> findByUri(Ontology ontology, String uri) throws QueryMalformedException, OntologyInvalidException;
 
+    /**
+     * Finds an entity in the ontology whose uri match the given uri.
+     *
+     * @param ontology The ontology.
+     * @param uri      The uri.
+     * @return The entity, if successful.
+     * @throws QueryMalformedException         The SPARQL query is malformed.
+     * @throws OntologyInvalidException        The given ontology is invalid.
+     * @throws SemanticEntityNotFoundException The entity was not found.
+     */
     EntityDto findOneByUri(Ontology ontology, String uri) throws QueryMalformedException,
             SemanticEntityNotFoundException, OntologyInvalidException;
 
+    /**
+     * Attempts to suggest table semantics for a table with given id in database with given id.
+     *
+     * @param databaseId The database id.
+     * @param tableId    The table id.
+     * @return The list of entities that were suggested.
+     * @throws TableNotFoundException    The table with id was not found in the metadata database.
+     * @throws QueryMalformedException   The SPARQL query is malformed.
+     * @throws DatabaseNotFoundException The database with id was not found in the metadata database.
+     * @throws OntologyInvalidException  The given ontology is invalid.
+     */
     List<EntityDto> suggestTableSemantics(Long databaseId, Long tableId) throws TableNotFoundException,
             QueryMalformedException, DatabaseNotFoundException, OntologyInvalidException;
 
+    /**
+     * Attempts to suggest table column semantics for a table column in table with given id in database with given id.
+     *
+     * @param databaseId The database id.
+     * @param tableId    The table id.
+     * @param columnId   The table column id.
+     * @return The list of entities that were suggested.
+     * @throws TableNotFoundException       The table with id was not found in the metadata database.
+     * @throws QueryMalformedException      The SPARQL query is malformed.
+     * @throws DatabaseNotFoundException    The database with id was not found in the metadata database.
+     * @throws OntologyInvalidException     The given ontology is invalid.
+     * @throws TableColumnNotFoundException The table column was not found.
+     */
     List<TableColumnEntityDto> suggestTableColumnSemantics(Long databaseId, Long tableId, Long columnId)
-            throws QueryMalformedException, TableColumnNotFoundException, TableNotFoundException, DatabaseNotFoundException, OntologyInvalidException;
+            throws QueryMalformedException, TableColumnNotFoundException, TableNotFoundException,
+            DatabaseNotFoundException, OntologyInvalidException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
index e4f823c44e7cb86596c9b6aec6117268b6bbb0a8..4a3032281a1de86dcc165450b474c3d89dadd066 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/IdentifierService.java
@@ -33,11 +33,18 @@ public interface IdentifierService {
      * Finds an identifier by given id.
      *
      * @param id The identifier id.
-     * @return The identifier.
+     * @return The identifier, if successful.
      * @throws IdentifierNotFoundException The identifier does not exist.
      */
     Identifier find(Long id) throws IdentifierNotFoundException;
 
+    /**
+     * Finds an identifier by given doi.
+     *
+     * @param doi The identifier doi.
+     * @return The identifier, if successful.
+     * @throws IdentifierNotFoundException The identifier does not exist.
+     */
     Identifier findByDoi(String doi) throws IdentifierNotFoundException;
 
     /**
@@ -45,12 +52,22 @@ public interface IdentifierService {
      *
      * @param databaseId The database id.
      * @param queryId    The query id.
-     * @return The identifiers, if found.
+     * @return The list of identifiers.
      */
     List<Identifier> findByDatabaseIdAndQueryId(Long databaseId, Long queryId);
 
+    /**
+     * Finds all identifiers in the metadata database which are identifying databases.
+     *
+     * @return The list of identifiers.
+     */
     List<Identifier> findAllDatabaseIdentifiers();
 
+    /**
+     * Finds all identifiers in the metadata database which are identifying subsets.
+     *
+     * @return The list of identifiers.
+     */
     List<Identifier> findAllSubsetIdentifiers();
 
     /**
@@ -62,7 +79,7 @@ public interface IdentifierService {
      * @param queryId    Optional. The query id.
      * @param viewId     Optional. The view id.
      * @param tableId    Optional. The table id.
-     * @return List of identifiers
+     * @return The list of identifiers.
      */
     List<Identifier> findAll(IdentifierTypeDto type, Long databaseId, Long queryId, Long viewId, Long tableId);
 
@@ -72,19 +89,19 @@ public interface IdentifierService {
      * @param data      The identifier.
      * @param principal The authorization principal.
      * @return The created identifier from the metadata database if successful.
-     * @throws IdentifierPublishingNotAllowedException The identifier with this visibility could not be created.
-     * @throws QueryNotFoundException                  The query was not found in the data database.
-     * @throws RemoteUnavailableException              The connection to the Query Store could not be established by
-     *                                                 the database connector.
-     * @throws IdentifierAlreadyExistsException        The identifier for this query/database already exists.
-     * @throws UserNotFoundException                   The user was not found in the metadata database.
-     * @throws DatabaseNotFoundException               The database was not found in the metadata database.
-     * @throws IdentifierNotFoundException             The identifier was not found in the metadata database.
+     * @throws QueryNotFoundException     The query was not found in the data database.
+     * @throws IdentifierRequestException The identifier requested could not be created.
+     * @throws RemoteUnavailableException The connection to the Query Store could not be established by
+     *                                    the database connector.
+     * @throws UserNotFoundException      The user was not found in the metadata database.
+     * @throws DatabaseNotFoundException  The database was not found in the metadata database.
+     * @throws ViewNotFoundException      The view with id was not found.
+     * @throws QueryStoreException        The query store failed to retrieve.
+     * @throws ImageNotSupportedException The image is not supported.
      */
-    Identifier create(IdentifierSaveDto data, Principal principal) throws IdentifierPublishingNotAllowedException,
-            QueryNotFoundException, RemoteUnavailableException, IdentifierAlreadyExistsException, UserNotFoundException,
-            DatabaseNotFoundException, IdentifierRequestException, ViewNotFoundException, QueryStoreException,
-            DatabaseConnectionException, ImageNotSupportedException, IdentifierNotFoundException;
+    Identifier create(IdentifierSaveDto data, Principal principal) throws QueryNotFoundException,
+            IdentifierRequestException, RemoteUnavailableException, UserNotFoundException, DatabaseNotFoundException,
+            ViewNotFoundException, QueryStoreException, ImageNotSupportedException;
 
     /**
      * Export metadata for a identifier
@@ -104,7 +121,8 @@ public interface IdentifierService {
      * @throws IdentifierNotFoundException The identifier was not found in the metadata database or was deleted.
      * @throws IdentifierRequestException  The identifier style was not found.
      */
-    String exportBibliography(Long id, BibliographyTypeDto style) throws IdentifierNotFoundException, IdentifierRequestException;
+    String exportBibliography(Long id, BibliographyTypeDto style) throws IdentifierNotFoundException,
+            IdentifierRequestException;
 
     /**
      * Exports an identifier to XML
@@ -114,8 +132,16 @@ public interface IdentifierService {
      * @throws IdentifierNotFoundException The identifier was not found in the metadata database or was deleted.
      * @throws QueryNotFoundException      The query was not found in the metadata database or was deleted.
      * @throws IdentifierRequestException  The identifier does not allow for exporting.
+     * @throws QueryStoreException         The query store failed to retrieve.
+     * @throws QueryMalformedException     The export query is malformed.
+     * @throws DatabaseNotFoundException   The database was not found in the metadata database.
+     * @throws ImageNotSupportedException  The image is not supported.
+     * @throws FileStorageException        The S3 storage failed to produce an export resource.
+     * @throws DataDbSidecarException      The sidecar failed to upload the export to the S3 storage.
      */
-    InputStreamResource exportResource(Long identifierId, Principal principal) throws IdentifierNotFoundException, QueryNotFoundException, FileStorageException, IdentifierRequestException, UserNotFoundException, QueryStoreException, TableMalformedException, DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, DataDbSidecarException;
+    InputStreamResource exportResource(Long identifierId, Principal principal) throws IdentifierNotFoundException,
+            QueryNotFoundException, IdentifierRequestException, QueryStoreException, QueryMalformedException,
+            DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, DataDbSidecarException;
 
     /**
      * Soft-deletes an identifier for a given id in the metadata database. Does not actually remove the entity from the
@@ -123,6 +149,7 @@ public interface IdentifierService {
      *
      * @param identifierId The identifier id.
      * @throws IdentifierNotFoundException The identifier was not found in the metadata database or was deleted.
+     * @throws DatabaseNotFoundException   The database was not found in the metadata database.
      */
     void delete(Long identifierId) throws IdentifierNotFoundException, DatabaseNotFoundException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
index 61d731316d90adc951289eee8e218bb325efc013..b58294feb204b3ae839c9ee563593040f7e7c575 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MessageQueueService.java
@@ -12,7 +12,7 @@ public interface MessageQueueService {
      *
      * @param username The username.
      * @param password The password.
-     * @throws BrokerRemoteException                  The user could not be created.
+     * @throws BrokerRemoteException                  The broker service did not answer.
      * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout.
      */
     void createUser(String username, String password) throws BrokerRemoteException, BrokerVirtualHostModificationException;
@@ -21,7 +21,7 @@ public interface MessageQueueService {
      * Delete a user on the broker service with given username.
      *
      * @param username The username.
-     * @throws BrokerRemoteException                  The user could not be deleted.
+     * @throws BrokerRemoteException                  The broker service did not answer.
      * @throws BrokerVirtualHostModificationException The Broker Service did not respond within the 3s timeout.
      */
     void deleteUser(String username) throws BrokerRemoteException, BrokerVirtualHostModificationException;
@@ -31,13 +31,37 @@ public interface MessageQueueService {
      *
      * @param username The username.
      * @throws BrokerVirtualHostGrantException The Broker Service refused to grant the permissions.
+     * @throws BrokerRemoteException           The broker service did not answer.
      */
     void setVirtualHostPermissions(String username) throws BrokerVirtualHostGrantException, BrokerRemoteException;
 
+    /**
+     * Sets topic exchange permissions for a user.
+     *
+     * @param user The user.
+     * @throws BrokerVirtualHostGrantException The Broker Service refused to grant the permissions.
+     * @throws BrokerRemoteException           The broker service did not answer.
+     */
     void setTopicExchangePermissions(User user) throws BrokerVirtualHostGrantException,
             BrokerRemoteException;
 
+    /**
+     * Finds a queue with a given name.
+     *
+     * @param name The queue name.
+     * @return The queue.
+     * @throws QueueNotFoundException The queue could not be found in the broker service.
+     * @throws BrokerRemoteException  The broker service did not answer.
+     */
     QueueDto findQueue(String name) throws QueueNotFoundException, BrokerRemoteException;
 
+    /**
+     * Finds an exchange with given name.
+     *
+     * @param name The name.
+     * @return The exchange.
+     * @throws ExchangeNotFoundException The exchange could not be found in the broker service.
+     * @throws BrokerRemoteException     The broker service did not answer.
+     */
     ExchangeDto findExchange(String name) throws ExchangeNotFoundException, BrokerRemoteException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MetadataService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MetadataService.java
index 79d618730cb57699d5dc2a31c5bf41787f606177..b7b2d1de20ed6a8b76ee79d3238728152e242b52 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MetadataService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/MetadataService.java
@@ -55,6 +55,8 @@ public interface MetadataService {
      * @throws OrcidNotFoundException     The provided identifier is of ORCID type and does not exist.
      * @throws RorNotFoundException       The provided identifier is of ROR type and does not exist.
      * @throws RemoteUnavailableException The remote service is not supported.
+     * @throws DoiNotFoundException       The doi was not found.
      */
-    ExternalMetadataDto findByUrl(String url) throws OrcidNotFoundException, RorNotFoundException, RemoteUnavailableException, DoiNotFoundException;
+    ExternalMetadataDto findByUrl(String url) throws OrcidNotFoundException, RorNotFoundException,
+            RemoteUnavailableException, DoiNotFoundException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/OntologyService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/OntologyService.java
index 0f91626406f47dc290a7bc4ef5e3d3603c369ce8..6d94249c285fc9eb383343ecc2240e03c5415cc3 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/OntologyService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/OntologyService.java
@@ -12,15 +12,54 @@ import java.security.Principal;
 import java.util.List;
 
 public interface OntologyService {
+
+    /**
+     * Finds all ontologies in the metadata database.
+     *
+     * @return The list of ontologies.
+     */
     List<Ontology> findAll();
 
+    /**
+     * Finds all processable ontologies.
+     *
+     * @return The list of ontologies.
+     */
     List<Ontology> findAllProcessable();
 
+    /**
+     * Finds an ontology in the metadata database with given id.
+     *
+     * @param id The ontology id.
+     * @return The ontology, if successful.
+     * @throws OntologyNotFoundException The ontology was not found in the metadata database.
+     */
     Ontology find(Long id) throws OntologyNotFoundException;
 
-    Ontology create(OntologyCreateDto data, Principal principal) throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException;
+    /**
+     * Registers an ontology in the metadata database.
+     *
+     * @param data      The ontology data.
+     * @param principal The user principal.
+     * @return The created ontology, if successful.
+     */
+    Ontology create(OntologyCreateDto data, Principal principal);
 
+    /**
+     * Updates an ontology in the metadata database with given id.
+     *
+     * @param id   The ontology id.
+     * @param data The ontology data.
+     * @return The updated ontology, if successful.
+     * @throws OntologyNotFoundException The ontology was not found in the metadata database.
+     */
     Ontology update(Long id, OntologyModifyDto data) throws OntologyNotFoundException;
 
+    /**
+     * Unregisters an ontology in the metadata database with given id.
+     *
+     * @param id The ontology id.
+     * @throws OntologyNotFoundException The ontology was not found in the metadata database.
+     */
     void delete(Long id) throws OntologyNotFoundException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java
index 4ed19c2742196248f9c8f530cdcacebb3316cb3f..738eddb4a6d110341d364ec3da8c93f896d0aff3 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java
@@ -31,16 +31,18 @@ public interface QueryService {
      * @param sortColumn    The sorting column.
      * @return The result.
      * @throws QueryStoreException        The query store is not reachable.
-     * @throws QueryMalformedException    The query is malformed.
-     * @throws DatabaseNotFoundException  The database was not found in the metdata database.
+     * @throws DatabaseNotFoundException  The database was not found in the metadata database.
      * @throws ImageNotSupportedException The image is not supported.
      * @throws QueryMalformedException    The query is malformed.
+     * @throws ColumnParseException       The column could not be parsed.
+     * @throws UserNotFoundException      The user could not be found.
+     * @throws TableMalformedException    The table is malformed.
+     * @throws QueryNotFoundException     The query was not found in the query store.
      */
     QueryResultDto execute(Long databaseId, ExecuteStatementDto statement, Principal principal, Long page, Long size,
                            SortType sortDirection, String sortColumn) throws DatabaseNotFoundException,
             ImageNotSupportedException, QueryMalformedException, QueryStoreException, ColumnParseException,
-            UserNotFoundException, TableMalformedException, DatabaseConnectionException, KeycloakRemoteException,
-            AccessDeniedException, QueryNotFoundException;
+            UserNotFoundException, TableMalformedException, QueryNotFoundException;
 
     /**
      * Re-Executes an arbitrary query on the database. We allow the user to only view the data, therefore the
@@ -54,7 +56,6 @@ public interface QueryService {
      * @param sortColumn    The sorting column.
      * @param principal     The user principal.
      * @return The result.
-     * @throws QueryStoreException        The query store is not reachable.
      * @throws QueryMalformedException    The query is malformed.
      * @throws DatabaseNotFoundException  The database was not found in the metdata database.
      * @throws ImageNotSupportedException The image is not supported.
@@ -64,8 +65,7 @@ public interface QueryService {
      */
     QueryResultDto reExecute(Long databaseId, Query query, Long page, Long size, SortType sortDirection,
                              String sortColumn, Principal principal) throws QueryMalformedException,
-            DatabaseNotFoundException, ImageNotSupportedException, ColumnParseException, DatabaseConnectionException,
-            TableMalformedException, QueryStoreException, UserNotFoundException;
+            DatabaseNotFoundException, ImageNotSupportedException, ColumnParseException, TableMalformedException;
 
     /**
      * Re-Executes the count-statement of an arbitrary query on the database. We allow the user to only view
@@ -105,8 +105,7 @@ public interface QueryService {
      */
     QueryResultDto tableFindAll(Long databaseId, Long tableId, Instant timestamp, Long page, Long size,
                                 Principal principal) throws TableNotFoundException, DatabaseNotFoundException,
-            ImageNotSupportedException, DatabaseConnectionException, TableMalformedException, PaginationException,
-            QueryMalformedException, UserNotFoundException;
+            TableMalformedException, QueryMalformedException, ImageNotSupportedException;
 
     /**
      * Select all data known in the database-table id tuple at a given time and return a downloadable input stream
@@ -118,18 +117,15 @@ public interface QueryService {
      * @param timestamp  The given time.
      * @param principal  The user principal.
      * @return The select all data result in the form of a downloadable .csv file.
-     * @throws TableNotFoundException      The table was not found in the metadata database.
-     * @throws TableMalformedException     The table columns are messed up what we got from the metadata database.
-     * @throws DatabaseNotFoundException   The database was not found in the remote database.
-     * @throws ImageNotSupportedException  The image is not supported.
-     * @throws DatabaseConnectionException The connection to the remote database was unsuccessful.
-     * @throws FileStorageException        The file could not be exported.
-     * @throws QueryMalformedException     The query is malformed.
+     * @throws TableNotFoundException    The table was not found in the metadata database.
+     * @throws DatabaseNotFoundException The database was not found in the remote database.
+     * @throws FileStorageException      The file could not be exported.
+     * @throws QueryMalformedException   The query is malformed.
+     * @throws DataDbSidecarException    The data database sidecar failed to produce the export resource.
      */
     ExportResource tableFindAll(Long databaseId, Long tableId, Instant timestamp, Principal principal)
-            throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            DatabaseConnectionException, TableMalformedException, PaginationException,
-            FileStorageException, QueryMalformedException, UserNotFoundException, DataDbSidecarException;
+            throws TableNotFoundException, DatabaseNotFoundException, FileStorageException, QueryMalformedException,
+            DataDbSidecarException;
 
     /**
      * Select all data known in the view id tuple and return a page of specific size.
@@ -141,16 +137,12 @@ public interface QueryService {
      * @param size       The page size.
      * @param principal  The user principal.
      * @return The select all data result
-     * @throws ViewNotFoundException      The view was not found in the metadata database.
-     * @throws DatabaseNotFoundException  The database was not found in the metdata database.
-     * @throws ImageNotSupportedException The image is not supported.
-     * @throws ViewMalformedException     The table is malformed.
-     * @throws QueryMalformedException    The query is malformed.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
+     * @throws QueryMalformedException   The query is malformed.
+     * @throws TableMalformedException   The table is malformed.
      */
     QueryResultDto viewFindAll(Long databaseId, View view, Long page, Long size, Principal principal)
-            throws ViewNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
-            DatabaseConnectionException, ViewMalformedException, PaginationException, QueryMalformedException,
-            UserNotFoundException, TableMalformedException;
+            throws DatabaseNotFoundException, QueryMalformedException, TableMalformedException;
 
     /**
      * Finds one query by database id and query id.
@@ -161,16 +153,15 @@ public interface QueryService {
      * @return The query result in the form  of a downloadable .csv file.
      * @throws DatabaseNotFoundException  The database was not found in the remote database.
      * @throws ImageNotSupportedException The image is not supported.
-     * @throws TableMalformedException    The table columns are messed up what we got from the metadata database.
      * @throws FileStorageException       The file could not be exported.
      * @throws QueryStoreException        The query store is not reachable.
      * @throws QueryNotFoundException     THe query was not found in the query store.
      * @throws QueryMalformedException    The query is malformed.
+     * @throws DataDbSidecarException     The data database sidecar failed to produce the export resource.
      */
     ExportResource findOne(Long databaseId, Long queryId, Principal principal) throws DatabaseNotFoundException,
-            ImageNotSupportedException, TableMalformedException, FileStorageException, QueryStoreException,
-            QueryNotFoundException, QueryMalformedException, DatabaseConnectionException, UserNotFoundException,
-            DataDbSidecarException;
+            ImageNotSupportedException, FileStorageException, QueryStoreException, QueryNotFoundException,
+            QueryMalformedException, DataDbSidecarException;
 
     /**
      * Count the total tuples for a given table id within a database id at a given time.
@@ -184,11 +175,12 @@ public interface QueryService {
      * @throws TableNotFoundException     The table was not found in the metadata database.
      * @throws TableMalformedException    The table columns are messed up what we got from the metadata database.
      * @throws ImageNotSupportedException The image is not supported.
+     * @throws QueryMalformedException    The query is malformed.
+     * @throws QueryStoreException        The query store could not retrieve.
      */
     Long tableCount(Long databaseId, Long tableId, Instant timestamp, Principal principal)
-            throws DatabaseNotFoundException, TableNotFoundException, TableMalformedException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryMalformedException, QueryStoreException,
-            UserNotFoundException;
+            throws DatabaseNotFoundException, TableNotFoundException, ImageNotSupportedException,
+            QueryMalformedException, QueryStoreException, TableMalformedException;
 
     /**
      * Count the total tuples for a given table id within a database id at a given time.
@@ -202,8 +194,7 @@ public interface QueryService {
      * @throws ImageNotSupportedException The image is not supported.
      */
     Long viewCount(Long databaseId, View view, Principal principal) throws DatabaseNotFoundException,
-            TableMalformedException, ImageNotSupportedException, DatabaseConnectionException, QueryMalformedException,
-            QueryStoreException, UserNotFoundException;
+            ImageNotSupportedException, QueryMalformedException, QueryStoreException, TableMalformedException;
 
     /**
      * Insert data from AMQP client into a table of a table-database id tuple, we need the "root" role for this as the
@@ -213,14 +204,12 @@ public interface QueryService {
      * @param tableId    The table id.
      * @param data       The data.
      * @param principal  The user principal.
-     * @throws ImageNotSupportedException The image is not supported.
-     * @throws TableMalformedException    The table does not exist in the metadata database.
-     * @throws DatabaseNotFoundException  The database is not found in the metadata database.
-     * @throws TableNotFoundException     The table is not found in the metadata database.
+     * @throws TableMalformedException   The table does not exist in the metadata database.
+     * @throws DatabaseNotFoundException The database is not found in the metadata database.
+     * @throws TableNotFoundException    The table is not found in the metadata database.
      */
-    void insert(Long databaseId, Long tableId, TableCsvDto data, Principal principal) throws ImageNotSupportedException,
-            TableMalformedException, DatabaseNotFoundException, TableNotFoundException, DatabaseConnectionException,
-            UserNotFoundException;
+    void insert(Long databaseId, Long tableId, TableCsvDto data, Principal principal) throws TableMalformedException,
+            DatabaseNotFoundException, TableNotFoundException;
 
     /**
      * Deletes a tuple by given constraint set
@@ -237,7 +226,7 @@ public interface QueryService {
      */
     void delete(Long databaseId, Long tableId, TableCsvDeleteDto data, Principal principal)
             throws ImageNotSupportedException, TableMalformedException, DatabaseNotFoundException,
-            TableNotFoundException, DatabaseConnectionException, QueryMalformedException, UserNotFoundException;
+            TableNotFoundException, QueryMalformedException;
 
     /**
      * Insert data from a csv into a table of a table-database id tuple, we need the "root" role for this as the
@@ -247,13 +236,11 @@ public interface QueryService {
      * @param tableId    The table id.
      * @param data       The data path.
      * @param principal  The user principal.
-     * @throws ImageNotSupportedException The image is not supported.
-     * @throws TableMalformedException    The table does not exist in the metadata database.
-     * @throws DatabaseNotFoundException  The database is not found in the metadata database.
-     * @throws TableNotFoundException     The table is not found in the metadata database.
-     * @throws QueryMalformedException    The query is malformed.
+     * @throws TableMalformedException   The table does not exist in the metadata database.
+     * @throws DatabaseNotFoundException The database is not found in the metadata database.
+     * @throws TableNotFoundException    The table is not found in the metadata database.
+     * @throws DataDbSidecarException    The data database sidecar failed to import the dataset.
      */
-    void insert(Long databaseId, Long tableId, ImportDto data, Principal principal) throws ImageNotSupportedException,
-            TableMalformedException, DatabaseNotFoundException, TableNotFoundException, DatabaseConnectionException,
-            QueryMalformedException, UserNotFoundException, DataDbSidecarException;
+    void insert(Long databaseId, Long tableId, ImportDto data, Principal principal) throws TableMalformedException,
+            DatabaseNotFoundException, TableNotFoundException, DataDbSidecarException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryStoreService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryStoreService.java
index 680f8322db35e2663c164d3306ede6d33ed6c1a0..7fe8d91b6af4037ecb54f5a80cb459eceabe3df9 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryStoreService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryStoreService.java
@@ -9,13 +9,13 @@ public interface QueryStoreService {
     /**
      * Creates the query store in the database.
      *
-     * @param databaseId  The database id.
-     * @param principal   The principal of the user.
-     * @throws DatabaseNotFoundException
-     * @throws DatabaseConnectionException
-     * @throws DatabaseMalformedException
-     * @throws UserNotFoundException
-     * @throws QueryStoreException
+     * @param databaseId The database id.
+     * @param principal  The principal of the user.
+     * @throws DatabaseNotFoundException  The database is not found in the metadata database.
+     * @throws DatabaseMalformedException The database is malformed.
+     * @throws UserNotFoundException      The user was not found in the metadata database.
+     * @throws QueryStoreException        The query store failed to retrieve.
      */
-    void create(Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException;
+    void create(Long databaseId, Principal principal) throws DatabaseNotFoundException, DatabaseMalformedException,
+            UserNotFoundException, QueryStoreException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/SemanticService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/SemanticService.java
index bfa1928ec02048594e36c4f6a9ed1e2ba5483efa..8a0c44dc081e2cbebe54e187ec8bfb8c862fe1a1 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/SemanticService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/SemanticService.java
@@ -9,11 +9,35 @@ import java.util.List;
 
 public interface SemanticService {
 
+    /**
+     * Finds all table column concepts in the metadata database.
+     *
+     * @return The list of table column concepts.
+     */
     List<TableColumnConcept> findAllConcepts();
 
+    /**
+     * Finds all table column units in the metadata database.
+     *
+     * @return The list of table column units.
+     */
     List<TableColumnUnit> findAllUnits();
 
+    /**
+     * Finds a table column unit by given uri in the metadata database.
+     *
+     * @param uri The uri.
+     * @return The table column unit, if successful.
+     * @throws UnitNotFoundException The unit was not found.
+     */
     TableColumnUnit findUnit(String uri) throws UnitNotFoundException;
 
+    /**
+     * Finds a table column concept by given uri in the metadata database.
+     *
+     * @param uri The uri.
+     * @return The table column concept, if successful.
+     * @throws ConceptNotFoundException The concept was not found.
+     */
     TableColumnConcept findConcept(String uri) throws ConceptNotFoundException;
 }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/StoreService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/StoreService.java
index d62b959713a273b8ab81334f96e8a7830ca29c9f..ab48966bd002915ad2e619c5849a8a7c54445d2b 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/StoreService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/StoreService.java
@@ -24,8 +24,7 @@ public interface StoreService {
      * @throws QueryStoreException        The query store produced an invalid result
      */
     List<Query> findAll(Long databaseId, Boolean persisted, Principal principal) throws DatabaseNotFoundException,
-            ImageNotSupportedException, QueryStoreException, ContainerNotFoundException, DatabaseConnectionException,
-            TableMalformedException, UserNotFoundException;
+            ImageNotSupportedException, QueryStoreException;
 
     /**
      * Finds a query in the query store of the given database id and query id.
@@ -40,7 +39,7 @@ public interface StoreService {
      * @throws QueryNotFoundException     The query store did not return a query
      */
     Query findOne(Long databaseId, Long queryId, Principal principal) throws DatabaseNotFoundException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryNotFoundException, QueryStoreException, UserNotFoundException;
+            ImageNotSupportedException, QueryNotFoundException, QueryStoreException;
 
     /**
      * Inserts a query and metadata to the query store of a given database id.
@@ -49,14 +48,15 @@ public interface StoreService {
      * @param metadata   The statement.
      * @param principal  The user principal.
      * @return The stored query on success
-     * @throws QueryStoreException         The query store raised some error
-     * @throws DatabaseNotFoundException   The database id was not found in the metadata database
-     * @throws ImageNotSupportedException  The image is not supported
-     * @throws UserNotFoundException       The user was not found in the metadata database.
-     * @throws DatabaseConnectionException The database connection to the remote container failed.
+     * @throws QueryStoreException        The query store raised some error
+     * @throws DatabaseNotFoundException  The database id was not found in the metadata database
+     * @throws ImageNotSupportedException The image is not supported
+     * @throws UserNotFoundException      The user was not found in the metadata database.
+     * @throws QueryNotFoundException     The query was not found in the query store.
      */
     Query insert(Long databaseId, ExecuteStatementDto metadata, Principal principal) throws QueryStoreException,
-            DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException, DatabaseConnectionException, KeycloakRemoteException, AccessDeniedException, QueryNotFoundException;
+            DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException,
+            QueryNotFoundException;
 
     /**
      * Persists a query to be displayed in the frontend.
@@ -65,16 +65,16 @@ public interface StoreService {
      * @param queryId    The query id.
      * @param data       The desired persist state.
      * @return The stored query on success.
-     * @throws DatabaseNotFoundException   The database id was not found in the metadata database
-     * @throws ImageNotSupportedException  The image is not supported.
-     * @throws DatabaseConnectionException The database connection to the remote container failed.
-     * @throws QueryStoreException         The query store raised some error.
+     * @throws DatabaseNotFoundException           The database id was not found in the metadata database
+     * @throws ImageNotSupportedException          The image is not supported.
+     * @throws QueryStoreException                 The query store raised some error.
+     * @throws IdentifierAlreadyPublishedException The query is already persisted.
      */
     Query persist(Long databaseId, Long queryId, QueryPersistDto data) throws DatabaseNotFoundException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryStoreException, UserNotFoundException;
+            ImageNotSupportedException, QueryStoreException, IdentifierAlreadyPublishedException;
 
     /**
-     * Deletes the stale queries that have not been persisted within 24 hozrs.
+     * Deletes the stale queries that have not been persisted within 24 hours.
      *
      * @throws ImageNotSupportedException The image is not supported.
      * @throws QueryStoreException        The query store raised some error.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/TableService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/TableService.java
index 9c09b94cc1e5a7883790bdad936c0b99e0d71e6e..e1e57273a72923e0455635dd4cb53b525dcff08e 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/TableService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/TableService.java
@@ -14,17 +14,25 @@ import java.util.List;
 public interface TableService {
 
     /**
-     * Find a table in the metadata database by database-table id tuple
+     * Find a table in the metadata database by database and table id.
      *
      * @param databaseId The database id.
      * @param tableId    The table id.
-     * @return The database.
-     * @throws DatabaseNotFoundException The database is not found.
-     * @throws TableNotFoundException    The table is not found.
+     * @return The table, if successful.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
+     * @throws TableNotFoundException    The table was not found in the metadata database.
      */
     Table find(Long databaseId, Long tableId) throws DatabaseNotFoundException, TableNotFoundException;
 
-    @Transactional(readOnly = true)
+    /**
+     * Find a table in the metadata database by database id and table name.
+     *
+     * @param databaseId   The database id.
+     * @param internalName The table name.
+     * @return The table, if successful.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
+     * @throws TableNotFoundException    The table was not found in the metadata database.
+     */
     Table find(Long databaseId, String internalName) throws DatabaseNotFoundException, TableNotFoundException;
 
     /**
@@ -44,16 +52,17 @@ public interface TableService {
      * @throws QueryMalformedException   The query is malformed.
      * @throws DatabaseNotFoundException The database is not found.
      * @throws TableNotFoundException    The table is not found.
+     * @throws QueryStoreException       The query store failed.
      */
     List<TableHistoryDto> findHistory(Long databaseId, Long tableId, Principal principal)
-            throws DatabaseNotFoundException, QueryMalformedException, TableNotFoundException,
-            DatabaseConnectionException, QueryStoreException, UserNotFoundException;
+            throws DatabaseNotFoundException, TableNotFoundException, QueryStoreException, QueryMalformedException;
 
     /**
      * Select all tables from the metadata database.
      *
      * @param databaseId The database id.
      * @return The list of tables.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
      */
     List<Table> findAll(Long databaseId) throws DatabaseNotFoundException;
 
@@ -68,14 +77,12 @@ public interface TableService {
      * @throws ImageNotSupportedException The image is not supported.
      * @throws DatabaseNotFoundException  The database was not found in the metadata database.
      * @throws TableNameExistsException   The table name exists already in this database.
-     * @throws ContainerNotFoundException The container was not found.
      * @throws TableMalformedException    The table seems malformed by the mapper.
      * @throws QueryMalformedException    The query to create the table is malformed.
      */
     Table createTable(Long databaseId, TableCreateDto createDto, Principal principal)
             throws ImageNotSupportedException, DatabaseNotFoundException, TableMalformedException,
-            TableNameExistsException, ContainerNotFoundException, UserNotFoundException, QueryMalformedException,
-            TableNotFoundException;
+            TableNameExistsException, QueryMalformedException, TableNotFoundException;
 
 
     /**
@@ -86,16 +93,14 @@ public interface TableService {
      * @param columnId   The column id.
      * @param updateDto  The update data containing unit and concept uris.
      * @return The updated table column, if successful.
-     * @throws TableNotFoundException     The table was not found in the metadata database.
-     * @throws DatabaseNotFoundException  The database was not found in the metadata database.
-     * @throws ContainerNotFoundException The container was not found.
-     * @throws TableMalformedException    The table seems malformed by the mapper.
-     * @throws QueryMalformedException    The query to update the table is malformed.
+     * @throws TableNotFoundException    The table was not found in the metadata database.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
+     * @throws TableMalformedException   The table seems malformed by the mapper.
+     * @throws TableNotFoundException    The table is not found.
      */
     TableColumn update(Long databaseId, Long tableId, Long columnId, ColumnSemanticsUpdateDto updateDto,
                        String authorization) throws TableNotFoundException, DatabaseNotFoundException,
-            ContainerNotFoundException, TableMalformedException, SemanticEntityPersistException,
-            SemanticEntityNotFoundException, QueryMalformedException;
+            TableMalformedException;
 
     /**
      * Deletes a table from the database in the metadata database and data database.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
index a5edcc519c9643afc2915217eaebd14df20550ac..9dd6554774c5503c64a1f473d9a7102c9f5ac19c 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java
@@ -11,14 +11,14 @@ import java.util.UUID;
 public interface UserService {
 
     /**
-     * Finds all users in the metadata database
+     * Finds all users in the metadata database.
      *
      * @return The list of users.
      */
     List<User> findAll();
 
     /**
-     * Finds a user by username.
+     * Finds a user by username in the metadata database.
      *
      * @param username The username.
      * @return The user, if successfully.
@@ -30,7 +30,7 @@ public interface UserService {
      * Finds a specific user in the metadata database by given id.
      *
      * @param id The user id.
-     * @return The user if successful. False otherwise.
+     * @return The user, if successful.
      * @throws UserNotFoundException The user was not found.
      */
     User find(UUID id) throws UserNotFoundException;
@@ -39,11 +39,10 @@ public interface UserService {
      * Creates a user in the metadata database managed by Keycloak in the given realm.
      *
      * @param data The user data.
-     * @return The user, if successful. False otherwise.
-     * @throws UserAlreadyExistsException The user already exists in the metadata database.
+     * @param id   The user id.
+     * @return The user, if successful.
      */
-    User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException,
-            KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException;
+    User create(SignupRequestDto data, UUID id);
 
     /**
      * Updates the user information for a user with given id in the metadata database.
@@ -51,12 +50,12 @@ public interface UserService {
      * @param id   The user id.
      * @param data The user information.
      * @return The user if successful. False otherwise.
-     * @throws UserNotFoundException          The user was not found.
+     * @throws UserNotFoundException The user was not found.
      */
     User modify(UUID id, UserUpdateDto data) throws UserNotFoundException;
 
     /**
-     * Updates the user password for a user with given id.
+     * Updates the user password for a user with given id in the metadata database.
      *
      * @param id   The user id.
      * @param data The new password.
@@ -64,12 +63,12 @@ public interface UserService {
     void updatePassword(UUID id, UserPasswordDto data) throws UserNotFoundException;
 
     /**
-     * Updates the user theme for a user with given id.
+     * Updates the user theme for a user with given id in the metadata database.
      *
      * @param id   The user id.
      * @param data The user theme.
      * @return The user if successful. False otherwise.
-     * @throws UserNotFoundException          The user was not found.
+     * @throws UserNotFoundException The user was not found.
      */
     User toggleTheme(UUID id, UserThemeSetDto data) throws UserNotFoundException;
 
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java
index 208f55fe45dc9acf7c09831bc00bed2725bfad0b..48803195a6589bd956a95df2287901e9527ceab0 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/ViewService.java
@@ -17,7 +17,8 @@ public interface ViewService {
      * @param databaseId The database id.
      * @param principal  The user.
      * @return A list of views.
-     * @throws UserNotFoundException The user with authorization principal was not found.
+     * @throws UserNotFoundException     The user with authorization principal was not found.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
      */
     List<View> findAll(Long databaseId, Principal principal) throws UserNotFoundException, DatabaseNotFoundException;
 
@@ -28,8 +29,9 @@ public interface ViewService {
      * @param id         The view id.
      * @param principal  The user.
      * @return The view, if successful.
-     * @throws ViewNotFoundException The view was not found in the metadata database.
-     * @throws UserNotFoundException The user with authorization principal was not found.
+     * @throws ViewNotFoundException     The view was not found in the metadata database.
+     * @throws UserNotFoundException     The user with authorization principal was not found.
+     * @throws DatabaseNotFoundException The database was not found in the metadata database.
      */
     View findById(Long databaseId, Long id, Principal principal) throws ViewNotFoundException, UserNotFoundException,
             DatabaseNotFoundException;
@@ -37,9 +39,9 @@ public interface ViewService {
     /**
      * Delete view in the container with the given id and database with id and the given view id.
      *
-     * @param databaseId  The database id.
-     * @param id          The view id.
-     * @param principal   The authorization principal.
+     * @param databaseId The database id.
+     * @param id         The view id.
+     * @param principal  The authorization principal.
      * @throws ViewNotFoundException       The view was not found in the metadata database.
      * @throws UserNotFoundException       The user with authorization principal was not found.
      * @throws DatabaseNotFoundException   The database was not found.
@@ -48,14 +50,15 @@ public interface ViewService {
      * @throws ViewMalformedException      The view is malformed and could not be deleted.
      */
     void delete(Long databaseId, Long id, Principal principal) throws ViewNotFoundException,
-            UserNotFoundException, DatabaseNotFoundException, DatabaseConnectionException, QueryMalformedException, ViewMalformedException;
+            UserNotFoundException, DatabaseNotFoundException, DatabaseConnectionException, QueryMalformedException,
+            ViewMalformedException;
 
     /**
      * Creates a view in the container with given id and database with id with the given query.
      *
-     * @param databaseId  The database id.
-     * @param data        The given query.
-     * @param principal   The authorization principal.
+     * @param databaseId The database id.
+     * @param data       The given query.
+     * @param principal  The authorization principal.
      * @return The view that was created.
      * @throws DatabaseNotFoundException   The database was not found.
      * @throws DatabaseConnectionException The connection to the database could not be established.
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
index 60dbcc40f98f496b1b4aef267d83e02712691f45..77c8420eefcecf04c3b5b569e17809573f978364 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/AccessServiceImpl.java
@@ -149,8 +149,8 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi
             final PreparedStatement preparedStatement4 = databaseMapper.rawFlushPrivileges(connection);
             preparedStatement4.executeUpdate();
         } catch (SQLException e) {
-            log.error("Failed to modify database access {}, reason {}", accessDto, e.getMessage());
-            throw new DatabaseMalformedException("Failed to execute query", e);
+            log.error("Failed to modify database access: {}", e.getMessage());
+            throw new DatabaseMalformedException("Failed to modify database access: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -176,8 +176,8 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi
 
     @Override
     @Transactional
-    public void delete(Long databaseId, UUID userId) throws DatabaseNotFoundException, UserNotFoundException,
-            NotAllowedException, QueryMalformedException, DatabaseMalformedException, AccessDeniedException {
+    public void delete(Long databaseId, UUID userId) throws DatabaseNotFoundException, NotAllowedException,
+            QueryMalformedException, DatabaseMalformedException, AccessDeniedException {
         /* check */
         final Database database = databaseService.findById(databaseId);
         final Container container = database.getContainer();
@@ -195,8 +195,8 @@ public class AccessServiceImpl extends HibernateConnector implements AccessServi
             final PreparedStatement preparedStatement2 = databaseMapper.userToRawDropUserQuery(connection, access.getUser().getUsername());
             preparedStatement2.executeUpdate();
         } catch (SQLException e) {
-            log.error("Failed to revoke database access, reason {}", e.getMessage());
-            throw new DatabaseMalformedException("Failed to execute query", e);
+            log.error("Failed to revoke database access: {}", e.getMessage());
+            throw new DatabaseMalformedException("Failed to execute query: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
index 29db821a09850b4078ea48f785efcf9a7cb558b0..5f2a5f0a5dc0b8d70c6d9e5e4c7801224bbf09c6 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
@@ -45,13 +45,13 @@ public class ContainerServiceImpl implements ContainerService {
         final Optional<Container> optional = containerRepository.findByInternalName(
                 containerMapper.containerToInternalContainerName(data.getName()));
         if (optional.isPresent()) {
-            log.error("Failed to create container with name {}: already exists in metadata database", data.getName());
-            throw new ContainerAlreadyExistsException("Failed to create container with name " + data.getName() + ": already exists in metadata database");
+            log.error("Failed to create container with name {}: already exists", data.getName());
+            throw new ContainerAlreadyExistsException("Failed to create container with name " + data.getName() + ": already exists");
         }
         final Optional<ContainerImage> optional2 = imageRepository.findById(data.getImageId());
         if (optional2.isEmpty()) {
-            log.error("Failed to find image with id {} in metadata database", data.getImageId());
-            throw new ImageNotFoundException("Failed to find image with id " + data.getImageId() + " in metadata database");
+            log.error("Failed to find image with id {}", data.getImageId());
+            throw new ImageNotFoundException("Failed to find image with id " + data.getImageId());
         }
         /* entity */
         final Container container = Container.builder()
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
index 6a9ed0de7f90e32be4b4948a490df9df1b681aaf..3dfa60dc757343d49bd197c747e9831faa4c0d44 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/DataCiteIdentifierServiceImpl.java
@@ -82,11 +82,9 @@ public class DataCiteIdentifierServiceImpl implements IdentifierService {
 
     @Override
     @Transactional(rollbackFor = {Exception.class})
-    public Identifier create(IdentifierSaveDto data, Principal principal)
-            throws IdentifierPublishingNotAllowedException, QueryNotFoundException, RemoteUnavailableException,
-            IdentifierAlreadyExistsException, UserNotFoundException, DatabaseNotFoundException,
-            IdentifierRequestException, ViewNotFoundException, QueryStoreException, DatabaseConnectionException,
-            ImageNotSupportedException, IdentifierNotFoundException {
+    public Identifier create(IdentifierSaveDto data, Principal principal) throws QueryNotFoundException,
+            IdentifierRequestException, RemoteUnavailableException, UserNotFoundException, DatabaseNotFoundException,
+            ViewNotFoundException, QueryStoreException, ImageNotSupportedException {
         final Identifier identifier = identifierService.create(data, principal);
         /* https://stackoverflow.com/questions/55090541/spring-data-jpa-lombok-unsupportedoperationexception-during-saving */
         if (identifier.getCreators() != null) {
@@ -190,9 +188,8 @@ public class DataCiteIdentifierServiceImpl implements IdentifierService {
     @Transactional(readOnly = true)
     public InputStreamResource exportResource(Long identifierId, Principal principal)
             throws IdentifierNotFoundException, QueryNotFoundException, FileStorageException,
-            IdentifierRequestException, UserNotFoundException, QueryStoreException, TableMalformedException,
-            DatabaseConnectionException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException,
-            DataDbSidecarException {
+            IdentifierRequestException, QueryStoreException, QueryMalformedException, DatabaseNotFoundException,
+            ImageNotSupportedException, DataDbSidecarException {
         return identifierService.exportResource(identifierId, principal);
     }
 
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/EntityServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/EntityServiceImpl.java
index 1c0ca06c39e8cde9f2d4c0a0e066beefb41324b3..7e983019e7f7955cee1c462e40a3b96912e82917 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/EntityServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/EntityServiceImpl.java
@@ -126,7 +126,7 @@ public class EntityServiceImpl implements EntityService {
             return results;
         } catch (QueryParseException | IllegalArgumentException | RiotException e) {
             log.error("Failed to parse query: {}", e.getMessage());
-            throw new QueryMalformedException("Failed to parse query", e);
+            throw new QueryMalformedException("Failed to parse query: " + e.getMessage(), e);
         }
     }
 
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
index 5e57b6c0f5f4ad2e9c46bb0569a0af1654a73de1..4b2724a9aa55006abe48e3c033d86b68dd7bce91 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
@@ -84,8 +84,8 @@ public class IdentifierServiceImpl implements IdentifierService {
     public Identifier find(Long identifierId) throws IdentifierNotFoundException {
         final Optional<Identifier> optional = identifierRepository.findById(identifierId);
         if (optional.isEmpty()) {
-            log.error("Identifier with id {} not existing", identifierId);
-            throw new IdentifierNotFoundException("Unable to find identifier with pid: " + identifierId);
+            log.error("Failed to find identifier with id: {}", identifierId);
+            throw new IdentifierNotFoundException("Failed to find identifier with id: " + identifierId);
         }
         return optional.get();
     }
@@ -95,8 +95,8 @@ public class IdentifierServiceImpl implements IdentifierService {
     public Identifier findByDoi(String doi) throws IdentifierNotFoundException {
         final Optional<Identifier> optional = identifierRepository.findByDoi(doi);
         if (optional.isEmpty()) {
-            log.error("Identifier with doi {} not existing", doi);
-            throw new IdentifierNotFoundException("Unable to find identifier with doi: " + doi);
+            log.error("Failed to find identifier with doi {}: not existing", doi);
+            throw new IdentifierNotFoundException("Failed to find identifier with doi " + doi + ": not existing");
         }
         return optional.get();
     }
@@ -153,11 +153,9 @@ public class IdentifierServiceImpl implements IdentifierService {
 
     @Override
     @Transactional
-    public Identifier create(IdentifierSaveDto data, Principal principal)
-            throws QueryNotFoundException, RemoteUnavailableException, IdentifierAlreadyExistsException,
-            UserNotFoundException, DatabaseNotFoundException, IdentifierPublishingNotAllowedException,
-            IdentifierRequestException, ViewNotFoundException, QueryStoreException, DatabaseConnectionException,
-            ImageNotSupportedException, IdentifierNotFoundException {
+    public Identifier create(IdentifierSaveDto data, Principal principal) throws QueryNotFoundException,
+            IdentifierRequestException, RemoteUnavailableException, UserNotFoundException, DatabaseNotFoundException,
+            ViewNotFoundException, QueryStoreException, ImageNotSupportedException {
         /* create identifier */
         final Identifier entity = identifierMapper.identifierCreateDtoToIdentifier(data);
         entity.setCreatedBy(UserUtil.getId(principal));
@@ -218,8 +216,8 @@ public class IdentifierServiceImpl implements IdentifierService {
 
     @Override
     @Transactional(readOnly = true)
-    public String exportBibliography(Long id, BibliographyTypeDto style)
-            throws IdentifierNotFoundException, IdentifierRequestException {
+    public String exportBibliography(Long id, BibliographyTypeDto style) throws IdentifierNotFoundException,
+            IdentifierRequestException {
         /* check */
         final Identifier identifier = find(id);
         /* context */
@@ -237,7 +235,7 @@ public class IdentifierServiceImpl implements IdentifierService {
             body = templateEngine.process(template, context);
         } catch (TemplateInputException e) {
             log.error("Failed to load template: {}", e.getMessage());
-            throw new IdentifierRequestException("Failed to load template", e);
+            throw new IdentifierRequestException("Failed to load template: " + e.getMessage(), e);
         }
         log.trace("mapped bibliography {}", body);
         return body;
@@ -246,8 +244,7 @@ public class IdentifierServiceImpl implements IdentifierService {
     @Override
     @Transactional(readOnly = true)
     public InputStreamResource exportResource(Long identifierId, Principal principal) throws IdentifierNotFoundException,
-            QueryNotFoundException, IdentifierRequestException, UserNotFoundException, QueryStoreException,
-            TableMalformedException, DatabaseConnectionException, QueryMalformedException,
+            QueryNotFoundException, IdentifierRequestException, QueryStoreException, QueryMalformedException,
             DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, DataDbSidecarException {
         /* check */
         final Identifier identifier = find(identifierId);
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java
index 28ada413a74d01b6d363ebc8d30353c7e9c2c321..35e3e87b3b387895f9eacee4adab83dc77f81bca 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java
@@ -45,8 +45,8 @@ public class ImageServiceImpl implements ImageService {
     public ContainerImage find(Long imageId) throws ImageNotFoundException {
         final Optional<ContainerImage> image = imageRepository.findById(imageId);
         if (image.isEmpty()) {
-            log.error("Failed to find image with id {} in metadata database", imageId);
-            throw new ImageNotFoundException("Failed to find image with id " + imageId + " in metadata database");
+            log.error("Failed to find image with id {}", imageId);
+            throw new ImageNotFoundException("Failed to find image with id " + imageId);
         }
         return image.get();
     }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/LicenseServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/LicenseServiceImpl.java
index 3f558d93edc76cde93fd9f64ed279fba925d0625..4d387a3b76a66be4a317905032e32c8cc0269d74 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/LicenseServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/LicenseServiceImpl.java
@@ -29,8 +29,8 @@ public class LicenseServiceImpl implements LicenseService {
     public License find(String identifier) throws LicenseNotFoundException {
         final Optional<License> license = licenseRepository.findByIdentifier(identifier);
         if (license.isEmpty()) {
-            log.error("Failed to find license with identifier {} in metadata database", identifier);
-            throw new LicenseNotFoundException("Failed to find license with identifier " + identifier + " in metadata database");
+            log.error("Failed to find license with identifier {}", identifier);
+            throw new LicenseNotFoundException("Failed to find license with identifier " + identifier);
         }
         return license.get();
     }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
index 0fa65b87a8f9ace956c9a0bef9c49f4511ac3d67..07df2b4ca5950d5f3dbbb60c8e68746044b919f6 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
@@ -118,10 +118,8 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
 
     @Override
     @Transactional
-    public Database create(DatabaseCreateDto createDto, Principal principal)
-            throws ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException, AmqpException,
-            ContainerConnectionException, UserNotFoundException, DatabaseNameExistsException,
-            DatabaseConnectionException, QueryMalformedException, KeycloakRemoteException, AccessDeniedException {
+    public Database create(DatabaseCreateDto createDto, Principal principal) throws ContainerNotFoundException,
+            DatabaseMalformedException, UserNotFoundException, QueryMalformedException {
         /* start the object */
         final Database database = databaseMapper.databaseCreateDtoToDatabase(createDto);
         final Container container = containerService.find(database.getCid());
@@ -145,7 +143,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
             preparedStatement3.executeUpdate();
         } catch (SQLException e) {
             log.error("Failed to create database/-user: {}", e.getMessage());
-            throw new DatabaseMalformedException("Failed to create database/-user", e);
+            throw new DatabaseMalformedException("Failed to create database/-user: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -223,7 +221,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
         final Database database = findById(databaseId);
         final List<Table> diffTables;
         final List<View> diffViews;
-        final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(), database.getContainer());
+        final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(), database.getContainer(), database);
         try {
             final Connection connection = dataSource.getConnection();
             final PreparedStatement preparedStatement0 = databaseMapper.databaseToDatabaseMetadata(connection, database);
@@ -268,7 +266,9 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
                     log.info("Enabled system-versioning for table with name {}", table.getInternalName());
                 }
                 final PreparedStatement preparedStatement2 = queryMapper.databaseToDatabaseConstraintMetadata(connection, table.getDatabase().getInternalName(), table.getInternalName());
-                table.setConstraints(resultSetTableToObtainedConstraintsMetadata(preparedStatement2.executeQuery(), table));
+                table.setConstraints(resultSetTableToObtainedConstraintsMetadata(preparedStatement2.executeQuery()));
+                final PreparedStatement preparedStatement3 = tableMapper.tableToCreateHistoryViewRawQuery(connection, table);
+                preparedStatement3.executeUpdate();
                 database.getTables().add(table);
             }
         } catch (SQLException e) {
@@ -298,8 +298,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
     }
 
     @Transactional
-    public Constraints resultSetTableToObtainedConstraintsMetadata(ResultSet resultSet, Table table)
-            throws SQLException {
+    public Constraints resultSetTableToObtainedConstraintsMetadata(ResultSet resultSet) throws SQLException {
         final Set<String> checks = new LinkedHashSet<>();
         final List<Unique> uniques = new LinkedList<>();
         final List<ForeignKey> foreignKeys = new LinkedList<>();
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/OntologyServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/OntologyServiceImpl.java
index a629754c4fb24358723557b3152538fd6043fbf6..8818e51b724bf59884df8ad0016557b950dc4618 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/OntologyServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/OntologyServiceImpl.java
@@ -52,8 +52,7 @@ public class OntologyServiceImpl implements OntologyService {
     }
 
     @Override
-    public Ontology create(OntologyCreateDto data, Principal principal) throws UserNotFoundException,
-            KeycloakRemoteException, AccessDeniedException {
+    public Ontology create(OntologyCreateDto data, Principal principal) {
         final Ontology entity = ontologyMapper.ontologyCreateDtoToOntology(data);
         final Ontology ontology = ontologyRepository.save(entity);
         log.info("Created ontology with id {}  in metadata database", ontology.getId());
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
index e8f64ab7203dfd7228dee7691f7a9369add43b31..b78715ee47068b3c4956e92a8ca562c792fe3ab1 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
@@ -16,6 +16,7 @@ import at.tuwien.entities.database.table.columns.TableColumn;
 import at.tuwien.exception.*;
 import at.tuwien.gateway.DataDbSidecarGateway;
 import at.tuwien.mapper.QueryMapper;
+import at.tuwien.mapper.ViewMapper;
 import at.tuwien.querystore.Query;
 import at.tuwien.service.DatabaseService;
 import at.tuwien.service.QueryService;
@@ -51,6 +52,7 @@ import java.util.List;
 public class QueryServiceImpl extends HibernateConnector implements QueryService {
 
     private final S3Config s3Config;
+    private final ViewMapper viewMapper;
     private final MinioClient minioClient;
     private final QueryMapper queryMapper;
     private final StoreService storeService;
@@ -59,10 +61,11 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     private final DataDbSidecarGateway dataDbSidecarGateway;
 
     @Autowired
-    public QueryServiceImpl(S3Config s3Config, MinioClient minioClient, QueryMapper queryMapper,
+    public QueryServiceImpl(S3Config s3Config, ViewMapper viewMapper, MinioClient minioClient, QueryMapper queryMapper,
                             TableService tableService, DatabaseService databaseService, StoreService storeService,
                             DataDbSidecarGateway dataDbSidecarGateway) {
         this.s3Config = s3Config;
+        this.viewMapper = viewMapper;
         this.minioClient = minioClient;
         this.queryMapper = queryMapper;
         this.tableService = tableService;
@@ -76,8 +79,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     public QueryResultDto execute(Long databaseId, ExecuteStatementDto statement, Principal principal, Long page,
                                   Long size, SortType sortDirection, String sortColumn)
             throws DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, QueryStoreException,
-            ColumnParseException, UserNotFoundException, DatabaseConnectionException, TableMalformedException,
-            KeycloakRemoteException, AccessDeniedException, QueryNotFoundException {
+            ColumnParseException, UserNotFoundException, TableMalformedException, QueryNotFoundException {
         if (statement.getStatement().contains(";")) {
             log.error("Failed to execute query: contains ';'");
             throw new QueryMalformedException("Failed to execute query: contains ';'");
@@ -137,7 +139,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             return connection.prepareStatement(statement);
         } catch (SQLException e) {
             log.error("Failed to prepare statement: {}", e.getMessage());
-            throw new QueryMalformedException("Failed to prepare statement", e);
+            throw new QueryMalformedException("Failed to prepare statement: " + e.getMessage(), e);
         }
     }
 
@@ -156,7 +158,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             return queryMapper.resultListToQueryResultDto(columns, resultSet);
         } catch (SQLException e) {
             log.error("Failed to execute and map time-versioned query: {}", e.getMessage());
-            throw new TableMalformedException("Failed to execute and map time-versioned query", e);
+            throw new TableMalformedException("Failed to execute and map time-versioned query: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -176,7 +178,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             return queryMapper.resultSetToNumber(resultSet);
         } catch (SQLException e) {
             log.error("Failed to map object: {}", e.getMessage());
-            throw new TableMalformedException("Failed to map object", e);
+            throw new TableMalformedException("Failed to map object: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -185,21 +187,35 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Override
     @Transactional(readOnly = true)
     public QueryResultDto tableFindAll(Long databaseId, Long tableId, Instant timestamp, Long page,
-                                       Long size, Principal principal) throws TableNotFoundException, DatabaseNotFoundException,
-            ImageNotSupportedException, TableMalformedException, QueryMalformedException {
+                                       Long size, Principal principal) throws TableNotFoundException,
+            DatabaseNotFoundException, TableMalformedException, QueryMalformedException, ImageNotSupportedException {
         /* find */
         final Table table = tableService.find(databaseId, tableId);
         /* run query */
-        String statement = queryMapper.tableToRawFindAllQuery(table, timestamp, size, page);
-        return executeNonPersistent(databaseId, statement, table.getColumns());
+        return executeNonPersistent(databaseId, queryMapper.tableToRawFindAllQuery(table, timestamp, size, page),
+                table.getColumns());
     }
 
     @Override
     @Transactional(readOnly = true)
     public QueryResultDto viewFindAll(Long databaseId, View view, Long page, Long size, Principal principal)
             throws DatabaseNotFoundException, QueryMalformedException, TableMalformedException {
+        /* find */
+        final Database database = databaseService.find(databaseId);
         /* run query */
-        return executeNonPersistent(databaseId, view.getQuery(), view.getColumns());
+        final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(),
+                database.getContainer(), database);
+        try {
+            final Connection connection = dataSource.getConnection();
+            final PreparedStatement preparedStatement = viewMapper.viewToSelectAll(connection, view, page, size);
+            final ResultSet resultSet = preparedStatement.executeQuery();
+            return queryMapper.resultListToQueryResultDto(view.getColumns(), resultSet);
+        } catch (SQLException e) {
+            log.error("Failed to map object: {}", e.getMessage());
+            throw new TableMalformedException("Failed to map object: " + e.getMessage(), e);
+        } finally {
+            dataSource.close();
+        }
     }
 
     @Override
@@ -215,9 +231,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
 
     @Override
     @Transactional
-    public Long viewCount(Long databaseId, View view, Principal principal)
-            throws DatabaseNotFoundException, ImageNotSupportedException,
-            QueryMalformedException, QueryStoreException, TableMalformedException {
+    public Long viewCount(Long databaseId, View view, Principal principal) throws DatabaseNotFoundException,
+            ImageNotSupportedException, QueryMalformedException, QueryStoreException, TableMalformedException {
         /* find */
         final String statement = queryMapper.viewToRawCountAllQuery(view);
         return executeCountNonPersistent(databaseId, statement);
@@ -241,14 +256,15 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             preparedStatement.executeUpdate();
         } catch (SQLException e) {
             log.error("Failed to execute query and/or export file: {}", e.getMessage());
-            throw new FileStorageException("Failed to execute query and/or export file", e);
+            throw new FileStorageException("Failed to execute query and/or export file: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
         return retrieveBlobAsResource(database.getContainer(), filename);
     }
 
-    private ExportResource retrieveBlobAsResource(Container container, String filename) throws DataDbSidecarException, FileStorageException {
+    private ExportResource retrieveBlobAsResource(Container container, String filename) throws DataDbSidecarException,
+            FileStorageException {
         /* upload from sidecar into blob storage */
         dataDbSidecarGateway.exportFile(container.getSidecarHost(), container.getSidecarPort(), filename);
         /* export file from blob storage */
@@ -262,8 +278,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
         } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException |
                  NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException |
                  InternalException e) {
-            log.error("Failed to find object {} in bucket {}", filename, s3Config.getS3ExportBucket());
-            throw new FileStorageException("Failed to find object " + filename + " in bucket " + s3Config.getS3ExportBucket());
+            log.error("Failed to find object {} in bucket {}: {}", filename, s3Config.getS3ExportBucket(), e.getMessage());
+            throw new FileStorageException("Failed to find object " + filename + " in bucket " + s3Config.getS3ExportBucket() + ": " + e.getMessage());
         }
     }
 
@@ -271,14 +287,14 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Transactional(readOnly = true)
     public ExportResource findOne(Long databaseId, Long queryId, Principal principal)
             throws DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, QueryStoreException,
-            QueryNotFoundException, QueryMalformedException, DatabaseConnectionException, UserNotFoundException, DataDbSidecarException {
+            QueryNotFoundException, QueryMalformedException, DataDbSidecarException {
         return findOne(databaseId, queryId, principal, RandomStringUtils.randomAlphabetic(40) + ".csv");
     }
 
     @Transactional(readOnly = true)
     public ExportResource findOne(Long databaseId, Long queryId, Principal principal, String filename)
             throws DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, QueryStoreException,
-            QueryNotFoundException, QueryMalformedException, DatabaseConnectionException, UserNotFoundException, DataDbSidecarException {
+            QueryNotFoundException, QueryMalformedException, DataDbSidecarException {
         /* find */
         final Database database = databaseService.find(databaseId);
         final Query query = storeService.findOne(databaseId, queryId, principal);
@@ -291,7 +307,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             preparedStatement.executeUpdate();
         } catch (SQLException e) {
             log.error("Failed to execute query: {}", e.getMessage());
-            throw new QueryStoreException("Failed to execute query", e);
+            throw new QueryStoreException("Failed to execute query: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -316,13 +332,13 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             preparedStatement.executeUpdate();
         } catch (DateTimeParseException e) {
             log.error("Failed to parse date: {}", e.getMessage());
-            throw new TableMalformedException("Failed to parse date", e);
+            throw new TableMalformedException("Failed to parse date: " + e.getMessage(), e);
         } catch (NumberFormatException e) {
             log.error("Failed to parse number: {}", e.getMessage());
-            throw new TableMalformedException("Failed to parse number", e);
+            throw new TableMalformedException("Failed to parse number: " + e.getMessage(), e);
         } catch (Exception e) {
             log.error("Database failed to accept tuple: {}", e.getMessage());
-            throw new TableMalformedException("Database failed to accept tuple", e);
+            throw new TableMalformedException("Database failed to accept tuple: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -332,7 +348,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Transactional
     public void delete(Long databaseId, Long tableId, TableCsvDeleteDto data, Principal principal)
             throws ImageNotSupportedException, TableMalformedException, DatabaseNotFoundException,
-            TableNotFoundException, DatabaseConnectionException, QueryMalformedException, UserNotFoundException {
+            TableNotFoundException, QueryMalformedException {
         /* find */
         final Database database = databaseService.find(databaseId);
         final Table table = tableService.find(databaseId, tableId);
@@ -347,7 +363,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             preparedStatement.executeUpdate();
         } catch (SQLException e) {
             log.error("Failed to delete tuples: {}", e.getMessage());
-            throw new TableMalformedException("Failed to delete tuples", e);
+            throw new TableMalformedException("Failed to delete tuples: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -356,8 +372,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Override
     @Transactional
     public void insert(Long databaseId, Long tableId, ImportDto data, Principal principal)
-            throws TableMalformedException, DatabaseNotFoundException, TableNotFoundException, QueryMalformedException,
-            DataDbSidecarException {
+            throws TableMalformedException, DatabaseNotFoundException, TableNotFoundException, DataDbSidecarException {
         /* find */
         final Database database = databaseService.find(databaseId);
         final Table table = tableService.find(databaseId, tableId);
@@ -370,8 +385,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             final Connection connection = dataSource.getConnection();
             queryMapper.importCsvQuery(connection, table, data);
         } catch (SQLException e) {
-            log.error("Failed to import .csv: {}", e.getMessage());
-            throw new TableMalformedException("Failed to import .csv", e);
+            log.error("Failed to import csv: {}", e.getMessage());
+            throw new TableMalformedException("Failed to import csv: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java
index 411e6cc1fa3f933f667983463e41817d0b39a236..d3078999fd77103143d8abc49cb51fa2582fd8b9 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryStoreServiceImpl.java
@@ -31,7 +31,7 @@ public class QueryStoreServiceImpl extends HibernateConnector implements QuerySt
     @Override
     @Transactional(rollbackFor = DatabaseMalformedException.class)
     public void create(Long databaseId, Principal principal) throws DatabaseNotFoundException,
-            DatabaseConnectionException, DatabaseMalformedException, UserNotFoundException, QueryStoreException {
+            DatabaseMalformedException, UserNotFoundException, QueryStoreException {
         final Database database = databaseService.findById(databaseId);
         /* create */
         final ComboPooledDataSource dataSource = getPrivilegedDataSource(database.getContainer().getImage(), database.getContainer(), database);
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/SemanticServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/SemanticServiceImpl.java
index cd3871cb482dd8596fd0bf5064fe3999ddccfc50..5ca35a87374177b473d2e1e8de00e3d07b88486a 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/SemanticServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/SemanticServiceImpl.java
@@ -74,7 +74,7 @@ public class SemanticServiceImpl implements SemanticService {
                 .findFirst();
         if (optional.isEmpty()) {
             log.error("Failed to find unit with uri {} in metadata database", uri);
-            throw new UnitNotFoundException("Failed to find unit with uri " + uri + " in metadata database");
+            throw new UnitNotFoundException("Failed to find unit with uri " + uri);
         }
         return optional.get();
     }
@@ -94,7 +94,7 @@ public class SemanticServiceImpl implements SemanticService {
                 .findFirst();
         if (optional.isEmpty()) {
             log.error("Failed to find concept with uri {} in metadata database", uri);
-            throw new ConceptNotFoundException("Failed to find concept with uri " + uri + " in metadata database");
+            throw new ConceptNotFoundException("Failed to find concept with uri " + uri);
         }
         return optional.get();
     }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java
index 743529122a43023d200b971e981e53992fc63471..df8df65792718d259b73b91ca75901ff2f20502d 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java
@@ -7,6 +7,7 @@ import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.StoreMapper;
 import at.tuwien.querystore.Query;
+import at.tuwien.repository.mdb.IdentifierRepository;
 import at.tuwien.service.DatabaseService;
 import at.tuwien.service.StoreService;
 import at.tuwien.service.UserService;
@@ -28,19 +29,21 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
     private final StoreMapper storeMapper;
     private final UserService userService;
     private final DatabaseService databaseService;
+    private final IdentifierRepository identifierRepository;
 
     @Autowired
-    public StoreServiceImpl(StoreMapper storeMapper, UserService userService, DatabaseService databaseService) {
+    public StoreServiceImpl(StoreMapper storeMapper, UserService userService, DatabaseService databaseService,
+                            IdentifierRepository identifierRepository) {
         this.storeMapper = storeMapper;
         this.userService = userService;
         this.databaseService = databaseService;
+        this.identifierRepository = identifierRepository;
     }
 
     @Override
     @Transactional(readOnly = true)
     public List<Query> findAll(Long databaseId, Boolean persisted, Principal principal)
-            throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException,
-            ContainerNotFoundException, DatabaseConnectionException, TableMalformedException, UserNotFoundException {
+            throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException {
         /* find */
         final Database database = databaseService.find(databaseId);
         if (!database.getContainer().getImage().getName().equals("mariadb")) {
@@ -62,7 +65,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
             return queries;
         } catch (SQLException e) {
             log.error("Failed to find queries in database with id {}: {}", databaseId, e.getMessage());
-            throw new QueryStoreException("Failed to find queries in database with id " + database);
+            throw new QueryStoreException("Failed to find queries in database with id " + databaseId + ": " + e.getMessage());
         } finally {
             dataSource.close();
         }
@@ -87,12 +90,12 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
             final ResultSet resultSet = preparedStatement.executeQuery();
             if (!resultSet.next()) {
                 log.error("Query not found with id {} in database with id {}", queryId, databaseId);
-                throw new QueryNotFoundException("Query not found with id " + queryId + "  in database with id " + databaseId);
+                throw new QueryNotFoundException("Query not found with id " + queryId + " in database with id " + databaseId);
             }
             return storeMapper.resultSetToQuery(resultSet);
         } catch (SQLException e) {
             log.error("Failed to retrieve first row for query with id {}: {}", queryId, e.getMessage());
-            throw new QueryStoreException("Failed to retrieve first row for query with id " + queryId);
+            throw new QueryStoreException("Failed to retrieve first row for query with id " + queryId + ": " + e.getMessage());
         } finally {
             dataSource.close();
         }
@@ -101,8 +104,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
     @Override
     @Transactional(readOnly = true)
     public Query insert(Long databaseId, ExecuteStatementDto metadata, Principal principal)
-            throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException,
-            UserNotFoundException, DatabaseConnectionException, KeycloakRemoteException, AccessDeniedException,
+            throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException,
             QueryNotFoundException {
         /* find */
         final Database database = databaseService.find(databaseId);
@@ -137,7 +139,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
             return query;
         } catch (SQLException e) {
             log.error("Failed to execute query: {}", e.getMessage());
-            throw new QueryStoreException("Failed to execute query", e);
+            throw new QueryStoreException("Failed to execute query: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -146,7 +148,12 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
     @Override
     @Transactional
     public Query persist(Long databaseId, Long queryId, QueryPersistDto data) throws DatabaseNotFoundException,
-            ImageNotSupportedException, QueryStoreException {
+            ImageNotSupportedException, QueryStoreException, IdentifierAlreadyPublishedException {
+        /* check */
+        if (!data.getPersist() && !identifierRepository.findByDatabaseIdAndQueryId(databaseId, queryId).isEmpty()) {
+            log.error("Failed to de-persist query with id {} in database with id {}: identifier already attached", queryId, databaseId);
+            throw new IdentifierAlreadyPublishedException("Failed to de-persist query with id " + queryId + " in database with id " + databaseId + ": identifier already attached");
+        }
         /* find */
         final Database database = databaseService.find(databaseId);
         if (!database.getContainer().getImage().getName().equals("mariadb")) {
@@ -198,7 +205,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
                 log.debug("delete stale queries affected {} rows", affected);
             } catch (SQLException e) {
                 log.error("Failed to delete stale queries in database with id {}: {}", database.getId(), e.getMessage());
-                throw new QueryStoreException("Failed to delete stale queries in database with id " + database.getId(), e);
+                throw new QueryStoreException("Failed to delete stale queries in database with id " + database.getId() + ": " + e.getMessage(), e);
             } finally {
                 dataSource.close();
             }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
index 8ca16099652fd0ec07921e6131391ec03b527b8d..3201ad9ea0e7b8ea839da97ed6a0b67352309e4d 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
@@ -116,7 +116,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
             return queryMapper.resultListToTableHistoryDto(resultSet);
         } catch (SQLException e) {
             log.error("Failed to map table history: {}", e.getMessage());
-            throw new QueryStoreException("Failed to map table history", e);
+            throw new QueryStoreException("Failed to map table history: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
@@ -209,10 +209,9 @@ public class TableServiceImpl extends HibernateConnector implements TableService
 
     @Override
     @Transactional
-    public TableColumn update(Long databaseId, Long tableId, Long columnId,
-                              ColumnSemanticsUpdateDto updateDto, String authorization)
-            throws TableNotFoundException, DatabaseNotFoundException, TableMalformedException,
-            SemanticEntityNotFoundException, QueryMalformedException {
+    public TableColumn update(Long databaseId, Long tableId, Long columnId, ColumnSemanticsUpdateDto updateDto,
+                              String authorization) throws TableNotFoundException, DatabaseNotFoundException,
+            TableMalformedException {
         final Table table = find(databaseId, tableId);
         final TableColumn column = findColumn(table, columnId);
         /* assign */
@@ -266,7 +265,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
             tableMapper.tableToDropTableRawQuery(connection, table);
         } catch (SQLException e) {
             log.error("Failed to drop table: {}", e.getMessage());
-            throw new TableMalformedException("Failed to drop table", e);
+            throw new TableMalformedException("Failed to drop table: " + e.getMessage(), e);
         } finally {
             dataSource.close();
         }
diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
index d7c40db36f7fc4a09090d76eae9f8c125289c740..581239b2950acebee4ed7f2476f17b5d0ae5782b 100644
--- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
+++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
@@ -53,8 +53,7 @@ public class UserServiceImpl implements UserService {
     }
 
     @Override
-    public User create(SignupRequestDto data, UUID id) throws UserAlreadyExistsException, AccessDeniedException,
-            KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException {
+    public User create(SignupRequestDto data, UUID id) {
         /* create at authentication service */
         final User entity = User.builder()
                 .id(id)
diff --git a/dbrepo-metadata-service/test/pom.xml b/dbrepo-metadata-service/test/pom.xml
index 91e81274874fdc3b17700e31d53d905a841b2c6a..6d9e3d6e0efb638413d09784698d21b25ef26ca4 100644
--- a/dbrepo-metadata-service/test/pom.xml
+++ b/dbrepo-metadata-service/test/pom.xml
@@ -6,11 +6,11 @@
     <parent>
         <groupId>at.tuwien</groupId>
         <artifactId>dbrepo-metadata-service</artifactId>
-        <version>1.3.0</version>
+        <version>latest</version>
     </parent>
 
     <artifactId>dbrepo-metadata-service-test</artifactId>
-    <version>1.3.0</version>
+    <version>latest</version>
     <name>dbrepo-metadata-service-test</name>
 
     <dependencies>
diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
index a32cd2b2f724e9072b58447353f31124748b2e00..f4d85aa196fc07d53198a0d3f169e0895d7f9c70 100644
--- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -302,7 +302,6 @@ public abstract class BaseTest {
     public final static UserDto USER_1_DTO = UserDto.builder()
             .id(USER_1_ID)
             .username(USER_1_USERNAME)
-            .email(USER_1_EMAIL)
             .firstname(USER_1_FIRSTNAME)
             .lastname(USER_1_LASTNAME)
             .attributes(USER_1_ATTRIBUTES_DTO)
@@ -409,7 +408,6 @@ public abstract class BaseTest {
     public final static UserDto USER_2_DTO = UserDto.builder()
             .id(USER_2_ID)
             .username(USER_2_USERNAME)
-            .email(USER_2_EMAIL)
             .firstname(USER_2_FIRSTNAME)
             .lastname(USER_2_LASTNAME)
             .name(USER_2_NAME)
@@ -495,7 +493,6 @@ public abstract class BaseTest {
     public final static UserDto USER_3_DTO = UserDto.builder()
             .id(USER_3_ID)
             .username(USER_3_USERNAME)
-            .email(USER_3_EMAIL)
             .firstname(USER_3_FIRSTNAME)
             .lastname(USER_3_LASTNAME)
             .name(USER_3_NAME)
@@ -572,7 +569,6 @@ public abstract class BaseTest {
     public final static UserDto USER_4_DTO = UserDto.builder()
             .id(USER_4_ID)
             .username(USER_4_USERNAME)
-            .email(USER_4_EMAIL)
             .firstname(USER_4_FIRSTNAME)
             .lastname(USER_4_LASTNAME)
             .attributes(USER_4_ATTRIBUTES_DTO)
@@ -615,7 +611,6 @@ public abstract class BaseTest {
     public final static UserDto USER_5_DTO = UserDto.builder()
             .id(USER_5_ID)
             .username(USER_5_USERNAME)
-            .email(USER_5_EMAIL)
             .firstname(USER_5_FIRSTNAME)
             .lastname(USER_5_LASTNAME)
             .build();
@@ -661,7 +656,6 @@ public abstract class BaseTest {
     public final static UserDto USER_6_DTO = UserDto.builder()
             .id(USER_6_ID)
             .username(USER_6_USERNAME)
-            .email(USER_6_EMAIL)
             .firstname(USER_6_FIRSTNAME)
             .lastname(USER_6_LASTNAME)
             .build();
@@ -831,7 +825,7 @@ public abstract class BaseTest {
 
     public final static Long CONTAINER_1_ID = 1L;
     public final static ContainerImage CONTAINER_1_IMAGE = IMAGE_1;
-    public final static ImageBriefDto CONTAINER_1_IMAGE_BRIEF_DTO = IMAGE_1_BRIEF_DTO;
+    public final static ImageDto CONTAINER_1_IMAGE_DTO = IMAGE_1_DTO;
     public final static String CONTAINER_1_NAME = "u01";
     public final static String CONTAINER_1_INTERNALNAME = "dbrepo-userdb-u01";
     public final static String CONTAINER_1_IP = "127.0.0.1";
@@ -868,7 +862,7 @@ public abstract class BaseTest {
             .id(CONTAINER_1_ID)
             .name(CONTAINER_1_NAME)
             .internalName(CONTAINER_1_INTERNALNAME)
-            .image(CONTAINER_1_IMAGE_BRIEF_DTO)
+            .image(CONTAINER_1_IMAGE_DTO)
             .created(CONTAINER_1_CREATED)
             .host(CONTAINER_1_HOST)
             .port(CONTAINER_1_PORT)
@@ -886,7 +880,7 @@ public abstract class BaseTest {
 
     public final static Long CONTAINER_2_ID = 2L;
     public final static ContainerImage CONTAINER_2_IMAGE = IMAGE_1;
-    public final static ImageBriefDto CONTAINER_2_IMAGE_BRIEF_DTO = IMAGE_1_BRIEF_DTO;
+    public final static ImageDto CONTAINER_2_IMAGE_DTO = IMAGE_1_DTO;
     public final static String CONTAINER_2_NAME = "u02";
     public final static String CONTAINER_2_INTERNALNAME = "dbrepo-userdb-u02";
     public final static String CONTAINER_2_IP = "172.30.0.6";
@@ -917,7 +911,7 @@ public abstract class BaseTest {
             .id(CONTAINER_2_ID)
             .name(CONTAINER_2_NAME)
             .internalName(CONTAINER_2_INTERNALNAME)
-            .image(CONTAINER_2_IMAGE_BRIEF_DTO)
+            .image(CONTAINER_2_IMAGE_DTO)
             .created(CONTAINER_2_CREATED)
             .host(CONTAINER_2_HOST)
             .port(CONTAINER_2_PORT)
@@ -1126,6 +1120,210 @@ public abstract class BaseTest {
             .owner(USER_4_BRIEF_DTO)
             .build();
 
+    public final static TableCreateDto TABLE_0_CREATE_DTO = TableCreateDto.builder()
+            .name("full")
+            .description("full example")
+            .constraints(ConstraintsCreateDto.builder()
+                    .uniques(List.of())
+                    .foreignKeys(List.of())
+                    .build())
+            .columns(List.of(ColumnCreateDto.builder()
+                            .name("col1a")
+                            .type(ColumnTypeDto.CHAR)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col1b")
+                            .type(ColumnTypeDto.CHAR)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .size(50L)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col2a")
+                            .type(ColumnTypeDto.VARCHAR)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col2b")
+                            .type(ColumnTypeDto.VARCHAR)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .size(1024L)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col3")
+                            .type(ColumnTypeDto.BINARY)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col4")
+                            .type(ColumnTypeDto.VARBINARY)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .size(200L)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col5")
+                            .type(ColumnTypeDto.TINYBLOB)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col6")
+                            .type(ColumnTypeDto.TINYTEXT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col7")
+                            .type(ColumnTypeDto.TEXT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col8")
+                            .type(ColumnTypeDto.BLOB)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col9")
+                            .type(ColumnTypeDto.MEDIUMTEXT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col10")
+                            .type(ColumnTypeDto.MEDIUMBLOB)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col11")
+                            .type(ColumnTypeDto.LONGTEXT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col12")
+                            .type(ColumnTypeDto.LONGBLOB)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col13")
+                            .type(ColumnTypeDto.ENUM)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .enums(List.of("val1", "val2"))
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col14")
+                            .type(ColumnTypeDto.SET)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .sets(List.of("val1", "val2"))
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col15")
+                            .type(ColumnTypeDto.BIT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col16")
+                            .type(ColumnTypeDto.TINYINT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col17")
+                            .type(ColumnTypeDto.BOOL)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col18")
+                            .type(ColumnTypeDto.SMALLINT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col19")
+                            .type(ColumnTypeDto.MEDIUMINT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col20")
+                            .type(ColumnTypeDto.INT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col21")
+                            .type(ColumnTypeDto.BIGINT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col22")
+                            .type(ColumnTypeDto.FLOAT)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col23")
+                            .type(ColumnTypeDto.DOUBLE)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col24")
+                            .type(ColumnTypeDto.DECIMAL)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col25")
+                            .type(ColumnTypeDto.DATE)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .dfid(IMAGE_DATE_1_ID)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col26")
+                            .type(ColumnTypeDto.DATETIME)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .dfid(IMAGE_DATE_3_ID)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col27")
+                            .type(ColumnTypeDto.TIMESTAMP)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .dfid(IMAGE_DATE_3_ID)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col28")
+                            .type(ColumnTypeDto.TIME)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .dfid(IMAGE_DATE_4_ID)
+                            .build(),
+                    ColumnCreateDto.builder()
+                            .name("col29")
+                            .type(ColumnTypeDto.YEAR)
+                            .nullAllowed(true)
+                            .primaryKey(false)
+                            .build()))
+            .build();
+
     public final static Long TABLE_1_ID = 1L;
     public final static String TABLE_1_NAME = "Weather AUS";
     public final static String TABLE_1_INTERNALNAME = "weather_aus";
@@ -2424,7 +2622,7 @@ public abstract class BaseTest {
     public final static String QUERY_1_RESULT_HASH = "8358c8ade4849d2094ab5bb29127afdae57e6bb5acb1db7af603813d406c467a";
     public final static Instant QUERY_1_CREATED = Instant.ofEpochSecond(1677648377L);
     public final static Instant QUERY_1_EXECUTION = Instant.now();
-    public final static Boolean QUERY_1_PERSISTED = false;
+    public final static Boolean QUERY_1_PERSISTED = true;
 
     public final static Query QUERY_1 = Query.builder()
             .id(QUERY_1_ID)
@@ -2434,14 +2632,13 @@ public abstract class BaseTest {
             .resultNumber(QUERY_1_RESULT_NUMBER)
             .created(QUERY_1_CREATED)
             .executed(QUERY_1_EXECUTION)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .isPersisted(QUERY_1_PERSISTED)
             .build();
 
     public final static QueryDto QUERY_1_DTO = QueryDto.builder()
             .id(QUERY_1_ID)
-            .cid(QUERY_1_CONTAINER_ID)
-            .dbid(QUERY_1_DATABASE_ID)
+            .databaseId(QUERY_1_DATABASE_ID)
             .query(QUERY_1_STATEMENT)
             .queryHash(QUERY_1_QUERY_HASH)
             .resultHash(QUERY_1_RESULT_HASH)
@@ -2453,8 +2650,7 @@ public abstract class BaseTest {
 
     public final static QueryBriefDto QUERY_1_BRIEF_DTO = QueryBriefDto.builder()
             .id(QUERY_1_ID)
-            .cid(QUERY_1_CONTAINER_ID)
-            .dbid(QUERY_1_DATABASE_ID)
+            .databaseId(QUERY_1_DATABASE_ID)
             .query(QUERY_1_STATEMENT)
             .queryHash(QUERY_1_QUERY_HASH)
             .resultHash(QUERY_1_RESULT_HASH)
@@ -2484,20 +2680,20 @@ public abstract class BaseTest {
             .resultNumber(QUERY_2_RESULT_NUMBER)
             .created(QUERY_2_CREATED)
             .executed(QUERY_2_EXECUTION)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .isPersisted(QUERY_2_PERSISTED)
             .build();
 
     public final static QueryDto QUERY_2_DTO = QueryDto.builder()
             .id(QUERY_2_ID)
-            .cid(QUERY_2_CONTAINER_ID)
-            .dbid(QUERY_2_DATABASE_ID)
+            .databaseId(QUERY_2_DATABASE_ID)
             .query(QUERY_2_STATEMENT)
             .queryNormalized(QUERY_2_STATEMENT)
             .resultNumber(QUERY_2_RESULT_NUMBER)
             .resultHash(QUERY_2_RESULT_HASH)
             .lastModified(QUERY_2_LAST_MODIFIED)
             .created(QUERY_2_CREATED)
+            .createdBy(USER_1_ID)
             .queryHash(QUERY_2_QUERY_HASH)
             .execution(QUERY_2_EXECUTION)
             .build();
@@ -2521,21 +2717,21 @@ public abstract class BaseTest {
             .resultHash(QUERY_3_RESULT_HASH)
             .created(QUERY_3_CREATED)
             .executed(QUERY_3_EXECUTION)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .resultNumber(QUERY_3_RESULT_NUMBER)
             .isPersisted(QUERY_3_PERSISTED)
             .build();
 
     public final static QueryDto QUERY_3_DTO = QueryDto.builder()
             .id(QUERY_3_ID)
-            .cid(QUERY_3_CONTAINER_ID)
-            .dbid(QUERY_3_DATABASE_ID)
+            .databaseId(QUERY_3_DATABASE_ID)
             .query(QUERY_3_STATEMENT)
             .queryNormalized(QUERY_3_STATEMENT)
             .resultNumber(QUERY_3_RESULT_NUMBER)
             .resultHash(QUERY_3_RESULT_HASH)
             .lastModified(QUERY_3_LAST_MODIFIED)
             .created(QUERY_3_CREATED)
+            .createdBy(USER_1_ID)
             .queryHash(QUERY_3_QUERY_HASH)
             .execution(QUERY_3_EXECUTION)
             .build();
@@ -2562,7 +2758,7 @@ public abstract class BaseTest {
             .executed(QUERY_4_EXECUTION)
             .isPersisted(QUERY_4_PERSISTED)
             .resultNumber(QUERY_4_RESULT_NUMBER)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .build();
     public final static List<Map<String, Object>> QUERY_4_RESULT_RESULT = List.of(
             new HashMap<>() {{
@@ -2593,14 +2789,14 @@ public abstract class BaseTest {
 
     public final static QueryDto QUERY_4_DTO = QueryDto.builder()
             .id(QUERY_4_ID)
-            .cid(QUERY_4_CONTAINER_ID)
-            .dbid(QUERY_4_DATABASE_ID)
+            .databaseId(QUERY_4_DATABASE_ID)
             .query(QUERY_4_STATEMENT)
             .queryNormalized(QUERY_4_STATEMENT)
             .resultNumber(QUERY_4_RESULT_NUMBER)
             .resultHash(QUERY_4_RESULT_HASH)
             .lastModified(QUERY_4_LAST_MODIFIED)
             .created(QUERY_4_CREATED)
+            .createdBy(USER_1_ID)
             .queryHash(QUERY_4_QUERY_HASH)
             .execution(QUERY_4_EXECUTION)
             .build();
@@ -2624,14 +2820,13 @@ public abstract class BaseTest {
             .resultHash(QUERY_5_RESULT_HASH)
             .created(QUERY_5_CREATED)
             .executed(QUERY_5_EXECUTION)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .isPersisted(QUERY_5_PERSISTED)
             .build();
 
     public final static QueryDto QUERY_5_DTO = QueryDto.builder()
             .id(QUERY_5_ID)
-            .cid(QUERY_5_CONTAINER_ID)
-            .dbid(QUERY_5_DATABASE_ID)
+            .databaseId(QUERY_5_DATABASE_ID)
             .query(QUERY_5_STATEMENT)
             .queryNormalized(QUERY_5_STATEMENT)
             .resultNumber(QUERY_5_RESULT_NUMBER)
@@ -2661,20 +2856,20 @@ public abstract class BaseTest {
             .resultHash(QUERY_6_RESULT_HASH)
             .created(QUERY_6_CREATED)
             .executed(QUERY_6_EXECUTION)
-            .createdBy(USER_1_USERNAME)
+            .createdBy(USER_1_ID)
             .isPersisted(QUERY_6_PERSISTED)
             .build();
 
     public final static QueryDto QUERY_6_DTO = QueryDto.builder()
             .id(QUERY_6_ID)
-            .cid(QUERY_6_CONTAINER_ID)
-            .dbid(QUERY_6_DATABASE_ID)
+            .databaseId(QUERY_6_DATABASE_ID)
             .query(QUERY_6_STATEMENT)
             .queryNormalized(QUERY_6_STATEMENT)
             .resultNumber(QUERY_6_RESULT_NUMBER)
             .resultHash(QUERY_6_RESULT_HASH)
             .lastModified(QUERY_6_LAST_MODIFIED)
             .created(QUERY_6_CREATED)
+            .createdBy(USER_1_ID)
             .queryHash(QUERY_6_QUERY_HASH)
             .execution(QUERY_6_EXECUTION)
             .build();
@@ -6092,6 +6287,7 @@ public abstract class BaseTest {
     public final static String IDENTIFIER_2_QUERY_HASH = QUERY_1_QUERY_HASH;
     public final static String IDENTIFIER_2_RESULT_HASH = QUERY_1_RESULT_HASH;
     public final static String IDENTIFIER_2_QUERY = QUERY_1_STATEMENT;
+    public final static Long IDENTIFIER_2_QUERY_ID = QUERY_1_ID;
     public final static String IDENTIFIER_2_NORMALIZED = QUERY_1_STATEMENT;
     public final static Long IDENTIFIER_2_RESULT_NUMBER = QUERY_1_RESULT_NUMBER;
     public final static String IDENTIFIER_2_PUBLISHER = "Swedish Government";
@@ -6100,6 +6296,7 @@ public abstract class BaseTest {
 
     public final static Identifier IDENTIFIER_2 = Identifier.builder()
             .id(IDENTIFIER_2_ID)
+            .queryId(IDENTIFIER_2_QUERY_ID)
             .databaseId(IDENTIFIER_2_DATABASE_ID)
             .descriptions(List.of())
             .titles(List.of())
@@ -6125,6 +6322,7 @@ public abstract class BaseTest {
 
     public final static IdentifierDto IDENTIFIER_2_DTO = IdentifierDto.builder()
             .id(IDENTIFIER_2_ID)
+            .queryId(IDENTIFIER_2_QUERY_ID)
             .databaseId(IDENTIFIER_2_DATABASE_ID)
             .descriptions(List.of())
             .titles(List.of())
@@ -6149,6 +6347,7 @@ public abstract class BaseTest {
 
     public final static IdentifierSaveDto IDENTIFIER_2_DTO_REQUEST = IdentifierSaveDto.builder()
             .databaseId(IDENTIFIER_2_DATABASE_ID)
+            .queryId(IDENTIFIER_2_QUERY_ID)
             .descriptions(List.of())
             .titles(List.of())
             .relatedIdentifiers(List.of())
diff --git a/dbrepo-search-db/init/indices/database.json b/dbrepo-search-db/init/indices/database.json
index 5af0540921eec23181c3af7beec4015233d4e3a5..35be7c5ae43bafe791adc58b90023287e7160402 100644
--- a/dbrepo-search-db/init/indices/database.json
+++ b/dbrepo-search-db/init/indices/database.json
@@ -1,1148 +1,1210 @@
 {
   "aliases": {},
   "mappings": {
-      "properties": {
-        "accesses": {
-          "properties": {
-            "created": {
-              "type": "long"
-            },
-            "hdbid": {
-              "type": "long"
-            },
-            "huserid": {
-              "type": "text",
-              "fields": {
-                "keyword": {
-                  "type": "keyword",
-                  "ignore_above": 256
+    "properties": {
+      "contact": {
+        "type": "object",
+        "properties": {
+          "firstname": {
+            "type": "keyword"
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "lastname": {
+            "type": "keyword"
+          },
+          "name": {
+            "type": "keyword"
+          },
+          "qualified_name": {
+            "type": "keyword"
+          },
+          "username": {
+            "type": "keyword"
+          }
+        }
+      },
+      "container": {
+        "type": "object",
+        "properties": {
+          "created": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "host": {
+            "type": "keyword"
+          },
+          "id": {
+            "type": "long"
+          },
+          "image": {
+            "properties": {
+              "date_formats": {
+                "properties": {
+                  "created_at": {
+                    "type": "date"
+                  },
+                  "database_format": {
+                    "type": "text",
+                    "fields": {
+                      "keyword": {
+                        "type": "keyword",
+                        "ignore_above": 256
+                      }
+                    }
+                  },
+                  "has_time": {
+                    "type": "boolean"
+                  },
+                  "id": {
+                    "type": "long"
+                  },
+                  "unix_format": {
+                    "type": "text",
+                    "fields": {
+                      "keyword": {
+                        "type": "keyword",
+                        "ignore_above": 256
+                      }
+                    }
+                  }
                 }
-              }
-            },
-            "type": {
-              "type": "text",
-              "fields": {
-                "keyword": {
-                  "type": "keyword",
-                  "ignore_above": 256
+              },
+              "default_port": {
+                "type": "long"
+              },
+              "dialect": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
                 }
-              }
-            }
-          }
-        },
-        "contact": {
-          "type": "nested",
-          "properties": {
-            "firstname": {
-              "type": "keyword"
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "lastname": {
-              "type": "keyword"
-            },
-            "name": {
-              "type": "keyword"
-            },
-            "qualified_name": {
-              "type": "keyword"
-            },
-            "username": {
-              "type": "keyword"
-            }
-          }
-        },
-        "container": {
-          "type": "nested",
-          "properties": {
-            "created": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "host": {
-              "type": "keyword"
-            },
-            "id": {
-              "type": "long"
-            },
-            "image": {
-              "type": "nested",
-              "properties": {
-                "id": {
-                  "type": "keyword"
-                },
-                "name": {
-                  "type": "keyword"
-                },
-                "version": {
-                  "type": "keyword"
+              },
+              "id": {
+                "type": "long"
+              },
+              "jdbc_method": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
+                }
+              },
+              "name": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
+                }
+              },
+              "version": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
                 }
               }
-            },
-            "internal_name": {
-              "type": "keyword"
-            },
-            "name": {
-              "type": "keyword"
-            },
-            "port": {
-              "type": "integer"
-            },
-            "sidecar_host": {
-              "type": "keyword"
-            },
-            "sidecar_port": {
-              "type": "integer"
-            },
-            "ui_host": {
-              "type": "keyword"
-            },
-            "ui_port": {
-              "type": "integer"
             }
+          },
+          "internal_name": {
+            "type": "keyword"
+          },
+          "name": {
+            "type": "keyword"
+          },
+          "port": {
+            "type": "integer"
+          },
+          "sidecar_host": {
+            "type": "keyword"
+          },
+          "sidecar_port": {
+            "type": "integer"
+          },
+          "ui_host": {
+            "type": "keyword"
+          },
+          "ui_port": {
+            "type": "integer"
           }
-        },
-        "created": {
-          "type": "date",
-          "format": "date_optional_time||epoch_millis"
-        },
-        "description": {
-          "type": "text"
-        },
-        "exchange_name": {
-          "type": "keyword"
-        },
-        "exchange_type": {
-          "type": "keyword"
-        },
-        "id": {
-          "type": "keyword"
-        },
-        "identifiers": {
-          "type": "nested",
-          "properties": {
-            "created": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "creator": {
-              "type": "nested",
-              "properties": {
-                "firstname": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "keyword"
-                },
-                "name": {
-                  "type": "keyword"
-                },
-                "qualified_name": {
-                  "type": "keyword"
-                },
-                "username": {
-                  "type": "keyword"
-                }
+        }
+      },
+      "created": {
+        "type": "date",
+        "format": "date_optional_time||epoch_millis"
+      },
+      "description": {
+        "type": "text"
+      },
+      "exchange_name": {
+        "type": "keyword"
+      },
+      "exchange_type": {
+        "type": "keyword"
+      },
+      "id": {
+        "type": "keyword"
+      },
+      "identifiers": {
+        "type": "object",
+        "properties": {
+          "created": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "creators": {
+            "type": "object",
+            "properties": {
+              "affiliation": {
+                "type": "keyword"
+              },
+              "affiliation_identifier": {
+                "type": "keyword"
+              },
+              "affiliation_identifier_scheme": {
+                "type": "keyword"
+              },
+              "affiliation_identifier_scheme_uri": {
+                "type": "keyword"
+              },
+              "creator_name": {
+                "type": "text"
+              },
+              "firstname": {
+                "type": "text"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "lastname": {
+                "type": "text"
+              },
+              "name_identifier": {
+                "type": "keyword"
+              },
+              "name_identifier_scheme": {
+                "type": "keyword"
+              },
+              "name_identifier_scheme_uri": {
+                "type": "keyword"
+              },
+              "name_type": {
+                "type": "keyword"
               }
-            },
-            "creators": {
-              "type": "nested",
-              "properties": {
-                "affiliation": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier_scheme": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier_scheme_uri": {
-                  "type": "keyword"
-                },
-                "creator_name": {
-                  "type": "text"
-                },
-                "firstname": {
-                  "type": "text"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "text"
-                },
-                "name_identifier": {
-                  "type": "keyword"
-                },
-                "name_identifier_scheme": {
-                  "type": "keyword"
-                },
-                "name_identifier_scheme_uri": {
-                  "type": "keyword"
-                },
-                "name_type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "database_id": {
+            "type": "keyword"
+          },
+          "descriptions": {
+            "type": "object",
+            "properties": {
+              "description": {
+                "type": "text"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
               }
-            },
-            "database_id": {
-              "type": "keyword"
-            },
-            "descriptions": {
-              "type": "nested",
-              "properties": {
-                "description": {
-                  "type": "text"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "doi": {
+            "type": "keyword"
+          },
+          "execution": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "funders": {
+            "type": "object",
+            "properties": {
+              "award_number": {
+                "type": "keyword"
+              },
+              "award_title": {
+                "type": "keyword"
+              },
+              "funder_identifier": {
+                "type": "keyword"
+              },
+              "funder_identifier_type": {
+                "type": "keyword"
+              },
+              "funder_name": {
+                "type": "keyword"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "scheme_uri": {
+                "type": "keyword"
               }
-            },
-            "doi": {
-              "type": "keyword"
-            },
-            "execution": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "funders": {
-              "type": "nested",
-              "properties": {
-                "award_number": {
-                  "type": "keyword"
-                },
-                "award_title": {
-                  "type": "keyword"
-                },
-                "funder_identifier": {
-                  "type": "keyword"
-                },
-                "funder_identifier_type": {
-                  "type": "keyword"
-                },
-                "funder_name": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "scheme_uri": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "language": {
+            "type": "keyword"
+          },
+          "licenses": {
+            "type": "object",
+            "properties": {
+              "identifier": {
+                "type": "keyword"
+              },
+              "uri": {
+                "type": "keyword"
               }
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "language": {
-              "type": "keyword"
-            },
-            "licenses": {
-              "type": "nested"
-            },
-            "publication_day": {
-              "type": "integer"
-            },
-            "publication_month": {
-              "type": "integer"
-            },
-            "publication_year": {
-              "type": "integer"
-            },
-            "publisher": {
-              "type": "text"
-            },
-            "query": {
-              "type": "text"
-            },
-            "query_hash": {
-              "type": "text"
-            },
-            "query_id": {
-              "type": "keyword"
-            },
-            "query_normalized": {
-              "type": "text"
-            },
-            "related_identifiers": {
-              "type": "nested",
-              "properties": {
-                "created": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "relation": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                },
-                "value": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "publication_day": {
+            "type": "integer"
+          },
+          "publication_month": {
+            "type": "integer"
+          },
+          "publication_year": {
+            "type": "integer"
+          },
+          "publisher": {
+            "type": "text"
+          },
+          "query": {
+            "type": "text"
+          },
+          "query_hash": {
+            "type": "text"
+          },
+          "query_id": {
+            "type": "keyword"
+          },
+          "query_normalized": {
+            "type": "text"
+          },
+          "related_identifiers": {
+            "type": "object",
+            "properties": {
+              "created": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "relation": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
+              },
+              "value": {
+                "type": "keyword"
               }
-            },
-            "result_hash": {
-              "type": "text"
-            },
-            "result_number": {
-              "type": "long"
-            },
-            "table_id": {
-              "type": "keyword"
-            },
-            "titles": {
-              "type": "nested",
-              "properties": {
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "title": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "result_hash": {
+            "type": "text"
+          },
+          "result_number": {
+            "type": "long"
+          },
+          "table_id": {
+            "type": "keyword"
+          },
+          "titles": {
+            "type": "object",
+            "properties": {
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "title": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
               }
-            },
-            "type": {
-              "type": "keyword"
-            },
-            "view_id": {
-              "type": "keyword"
             }
+          },
+          "type": {
+            "type": "keyword"
+          },
+          "view_id": {
+            "type": "keyword"
           }
-        },
-        "internal_name": {
-          "type": "keyword"
-        },
-        "is_public": {
-          "type": "boolean"
-        },
-        "name": {
-          "type": "keyword"
-        },
-        "owner": {
-          "type": "nested",
-          "properties": {
-            "firstname": {
-              "type": "keyword"
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "lastname": {
-              "type": "keyword"
-            },
-            "name": {
-              "type": "keyword"
-            },
-            "qualified_name": {
-              "type": "keyword"
-            },
-            "username": {
-              "type": "keyword"
-            }
+        }
+      },
+      "internal_name": {
+        "type": "keyword"
+      },
+      "is_public": {
+        "type": "boolean"
+      },
+      "name": {
+        "type": "keyword"
+      },
+      "owner": {
+        "type": "object",
+        "properties": {
+          "firstname": {
+            "type": "keyword"
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "lastname": {
+            "type": "keyword"
+          },
+          "name": {
+            "type": "keyword"
+          },
+          "qualified_name": {
+            "type": "keyword"
+          },
+          "username": {
+            "type": "keyword"
           }
-        },
-        "subsets": {
-          "type": "nested",
-          "properties": {
-            "created": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "creator": {
-              "type": "nested",
-              "properties": {
-                "firstname": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "keyword"
-                },
-                "name": {
-                  "type": "keyword"
-                },
-                "qualified_name": {
-                  "type": "keyword"
-                },
-                "username": {
-                  "type": "keyword"
-                }
+        }
+      },
+      "subsets": {
+        "type": "object",
+        "properties": {
+          "created": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "creators": {
+            "type": "object",
+            "properties": {
+              "affiliation": {
+                "type": "keyword"
+              },
+              "affiliation_identifier": {
+                "type": "keyword"
+              },
+              "affiliation_identifier_scheme": {
+                "type": "keyword"
+              },
+              "affiliation_identifier_scheme_uri": {
+                "type": "keyword"
+              },
+              "creator_name": {
+                "type": "text"
+              },
+              "firstname": {
+                "type": "text"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "lastname": {
+                "type": "text"
+              },
+              "name_identifier": {
+                "type": "keyword"
+              },
+              "name_identifier_scheme": {
+                "type": "keyword"
+              },
+              "name_identifier_scheme_uri": {
+                "type": "keyword"
+              },
+              "name_type": {
+                "type": "keyword"
               }
-            },
-            "creators": {
-              "type": "nested",
-              "properties": {
-                "affiliation": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier_scheme": {
-                  "type": "keyword"
-                },
-                "affiliation_identifier_scheme_uri": {
-                  "type": "keyword"
-                },
-                "creator_name": {
-                  "type": "text"
-                },
-                "firstname": {
-                  "type": "text"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "text"
-                },
-                "name_identifier": {
-                  "type": "keyword"
-                },
-                "name_identifier_scheme": {
-                  "type": "keyword"
-                },
-                "name_identifier_scheme_uri": {
-                  "type": "keyword"
-                },
-                "name_type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "database_id": {
+            "type": "keyword"
+          },
+          "descriptions": {
+            "type": "object",
+            "properties": {
+              "description": {
+                "type": "text"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
               }
-            },
-            "database_id": {
-              "type": "keyword"
-            },
-            "descriptions": {
-              "type": "nested",
-              "properties": {
-                "description": {
-                  "type": "text"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "doi": {
+            "type": "keyword"
+          },
+          "execution": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "funders": {
+            "type": "object",
+            "properties": {
+              "award_number": {
+                "type": "keyword"
+              },
+              "award_title": {
+                "type": "keyword"
+              },
+              "funder_identifier": {
+                "type": "keyword"
+              },
+              "funder_identifier_type": {
+                "type": "keyword"
+              },
+              "funder_name": {
+                "type": "keyword"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "scheme_uri": {
+                "type": "keyword"
               }
-            },
-            "doi": {
-              "type": "keyword"
-            },
-            "execution": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "funders": {
-              "type": "nested",
-              "properties": {
-                "award_number": {
-                  "type": "keyword"
-                },
-                "award_title": {
-                  "type": "keyword"
-                },
-                "funder_identifier": {
-                  "type": "keyword"
-                },
-                "funder_identifier_type": {
-                  "type": "keyword"
-                },
-                "funder_name": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "scheme_uri": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "language": {
+            "type": "keyword"
+          },
+          "licenses": {
+            "type": "object",
+            "properties": {
+              "identifier": {
+                "type": "keyword"
+              },
+              "uri": {
+                "type": "keyword"
               }
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "language": {
-              "type": "keyword"
-            },
-            "licenses": {
-              "type": "nested"
-            },
-            "publication_day": {
-              "type": "integer"
-            },
-            "publication_month": {
-              "type": "integer"
-            },
-            "publication_year": {
-              "type": "integer"
-            },
-            "publisher": {
-              "type": "text"
-            },
-            "query": {
-              "type": "text"
-            },
-            "query_hash": {
-              "type": "text"
-            },
-            "query_id": {
-              "type": "keyword"
-            },
-            "query_normalized": {
-              "type": "text"
-            },
-            "related_identifiers": {
-              "type": "nested",
-              "properties": {
-                "created": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "relation": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                },
-                "value": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "publication_day": {
+            "type": "integer"
+          },
+          "publication_month": {
+            "type": "integer"
+          },
+          "publication_year": {
+            "type": "integer"
+          },
+          "publisher": {
+            "type": "text"
+          },
+          "query": {
+            "type": "text"
+          },
+          "query_hash": {
+            "type": "text"
+          },
+          "query_id": {
+            "type": "keyword"
+          },
+          "query_normalized": {
+            "type": "text"
+          },
+          "related_identifiers": {
+            "type": "object",
+            "properties": {
+              "created": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "relation": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
+              },
+              "value": {
+                "type": "keyword"
               }
-            },
-            "result_hash": {
-              "type": "text"
-            },
-            "result_number": {
-              "type": "long"
-            },
-            "table_id": {
-              "type": "keyword"
-            },
-            "titles": {
-              "type": "nested",
-              "properties": {
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "title": {
-                  "type": "keyword"
-                },
-                "type": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "result_hash": {
+            "type": "text"
+          },
+          "result_number": {
+            "type": "long"
+          },
+          "table_id": {
+            "type": "keyword"
+          },
+          "titles": {
+            "type": "object",
+            "properties": {
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "title": {
+                "type": "keyword"
+              },
+              "type": {
+                "type": "keyword"
               }
-            },
-            "type": {
-              "type": "keyword"
-            },
-            "view_id": {
-              "type": "keyword"
             }
+          },
+          "type": {
+            "type": "keyword"
+          },
+          "view_id": {
+            "type": "keyword"
           }
-        },
-        "tables": {
-          "type": "nested",
-          "properties": {
-            "constraints": {
-              "type": "nested",
-              "properties": {
-                "foreign_keys": {
-                  "type": "nested",
-                  "properties": {
-                    "on_delete": {
-                      "type": "keyword"
-                    },
-                    "on_update": {
-                      "type": "keyword"
-                    }
+        }
+      },
+      "tables": {
+        "type": "object",
+        "properties": {
+          "columns": {
+            "properties": {
+              "auto_generated": {
+                "type": "boolean"
+              },
+              "column_type": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
                   }
-                },
-                "uniques": {
-                  "type": "nested",
-                  "properties": {
-                    "id": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "concept": {
+                "type": "object",
+                "properties": {
+                  "created": {
+                    "type": "date"
+                  },
+                  "id": {
+                    "type": "long"
+                  },
+                  "uri": {
+                    "type": "keyword"
+                  }
+                }
+              },
+              "database_id": {
+                "type": "long"
+              },
+              "data_length": {
+                "type": "long"
+              },
+              "description": {
+                "type": "text"
+              },
+              "id": {
+                "type": "long"
+              },
+              "internal_name": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
+                }
+              },
+              "is_null_allowed": {
+                "type": "boolean"
+              },
+              "is_primary_key": {
+                "type": "boolean"
+              },
+              "is_public": {
+                "type": "boolean"
+              },
+              "name": {
+                "type": "text",
+                "fields": {
+                  "keyword": {
+                    "type": "keyword",
+                    "ignore_above": 256
+                  }
+                }
+              },
+              "num_rows": {
+                "type": "long"
+              },
+              "max_data_length": {
+                "type": "long"
+              },
+              "mean": {
+                "type": "double"
+              },
+              "median": {
+                "type": "double"
+              },
+              "std_dev": {
+                "type": "double"
+              },
+              "size": {
+                "type": "long"
+              },
+              "table_id": {
+                "type": "long"
+              },
+              "unit": {
+                "type": "object",
+                "properties": {
+                  "created": {
+                    "type": "date"
+                  },
+                  "id": {
+                    "type": "long"
+                  },
+                  "uri": {
+                    "type": "keyword"
                   }
                 }
+              },
+              "val_min": {
+                "type": "double"
+              },
+              "val_max": {
+                "type": "double"
               }
-            },
-            "created": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "creator": {
-              "type": "nested",
-              "properties": {
-                "firstname": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "keyword"
-                },
-                "name": {
-                  "type": "keyword"
-                },
-                "qualified_name": {
-                  "type": "keyword"
-                },
-                "username": {
-                  "type": "keyword"
+            }
+          },
+          "constraints": {
+            "type": "object",
+            "properties": {
+              "foreign_keys": {
+                "type": "object",
+                "properties": {
+                  "on_delete": {
+                    "type": "keyword"
+                  },
+                  "on_update": {
+                    "type": "keyword"
+                  }
+                }
+              },
+              "uniques": {
+                "type": "object",
+                "properties": {
+                  "id": {
+                    "type": "keyword"
+                  }
                 }
               }
-            },
-            "database_id": {
-              "type": "keyword"
-            },
-            "description": {
-              "type": "text"
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "identifiers": {
-              "type": "nested",
-              "properties": {
-                "created": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "creator": {
-                  "type": "nested",
-                  "properties": {
-                    "firstname": {
-                      "type": "keyword"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "lastname": {
-                      "type": "keyword"
-                    },
-                    "name": {
-                      "type": "keyword"
-                    },
-                    "qualified_name": {
-                      "type": "keyword"
-                    },
-                    "username": {
-                      "type": "keyword"
-                    }
+            }
+          },
+          "created": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "database_id": {
+            "type": "keyword"
+          },
+          "description": {
+            "type": "text"
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "identifiers": {
+            "type": "object",
+            "properties": {
+              "created": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "creators": {
+                "type": "object",
+                "properties": {
+                  "affiliation": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier_scheme": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier_scheme_uri": {
+                    "type": "keyword"
+                  },
+                  "creator_name": {
+                    "type": "text"
+                  },
+                  "firstname": {
+                    "type": "text"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "lastname": {
+                    "type": "text"
+                  },
+                  "name_identifier": {
+                    "type": "keyword"
+                  },
+                  "name_identifier_scheme": {
+                    "type": "keyword"
+                  },
+                  "name_identifier_scheme_uri": {
+                    "type": "keyword"
+                  },
+                  "name_type": {
+                    "type": "keyword"
                   }
-                },
-                "creators": {
-                  "type": "nested",
-                  "properties": {
-                    "affiliation": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier_scheme": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier_scheme_uri": {
-                      "type": "keyword"
-                    },
-                    "creator_name": {
-                      "type": "text"
-                    },
-                    "firstname": {
-                      "type": "text"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "lastname": {
-                      "type": "text"
-                    },
-                    "name_identifier": {
-                      "type": "keyword"
-                    },
-                    "name_identifier_scheme": {
-                      "type": "keyword"
-                    },
-                    "name_identifier_scheme_uri": {
-                      "type": "keyword"
-                    },
-                    "name_type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "database_id": {
+                "type": "keyword"
+              },
+              "descriptions": {
+                "type": "object",
+                "properties": {
+                  "description": {
+                    "type": "text"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "language": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
                   }
-                },
-                "database_id": {
-                  "type": "keyword"
-                },
-                "descriptions": {
-                  "type": "nested",
-                  "properties": {
-                    "description": {
-                      "type": "text"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "language": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "doi": {
+                "type": "keyword"
+              },
+              "execution": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "funders": {
+                "type": "object",
+                "properties": {
+                  "award_number": {
+                    "type": "keyword"
+                  },
+                  "award_title": {
+                    "type": "keyword"
+                  },
+                  "funder_identifier": {
+                    "type": "keyword"
+                  },
+                  "funder_identifier_type": {
+                    "type": "keyword"
+                  },
+                  "funder_name": {
+                    "type": "keyword"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "scheme_uri": {
+                    "type": "keyword"
                   }
-                },
-                "doi": {
-                  "type": "keyword"
-                },
-                "execution": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "funders": {
-                  "type": "nested",
-                  "properties": {
-                    "award_number": {
-                      "type": "keyword"
-                    },
-                    "award_title": {
-                      "type": "keyword"
-                    },
-                    "funder_identifier": {
-                      "type": "keyword"
-                    },
-                    "funder_identifier_type": {
-                      "type": "keyword"
-                    },
-                    "funder_name": {
-                      "type": "keyword"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "scheme_uri": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "licenses": {
+                "type": "object",
+                "properties": {
+                  "identifier": {
+                    "type": "keyword"
+                  },
+                  "uri": {
+                    "type": "keyword"
                   }
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "licenses": {
-                  "type": "nested"
-                },
-                "publication_day": {
-                  "type": "integer"
-                },
-                "publication_month": {
-                  "type": "integer"
-                },
-                "publication_year": {
-                  "type": "integer"
-                },
-                "publisher": {
-                  "type": "text"
-                },
-                "query": {
-                  "type": "text"
-                },
-                "query_hash": {
-                  "type": "text"
-                },
-                "query_id": {
-                  "type": "keyword"
-                },
-                "query_normalized": {
-                  "type": "text"
-                },
-                "related_identifiers": {
-                  "type": "nested",
-                  "properties": {
-                    "created": {
-                      "type": "date",
-                      "format": "date_optional_time||epoch_millis"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "relation": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    },
-                    "value": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "publication_day": {
+                "type": "integer"
+              },
+              "publication_month": {
+                "type": "integer"
+              },
+              "publication_year": {
+                "type": "integer"
+              },
+              "publisher": {
+                "type": "text"
+              },
+              "query": {
+                "type": "text"
+              },
+              "query_hash": {
+                "type": "text"
+              },
+              "query_id": {
+                "type": "keyword"
+              },
+              "query_normalized": {
+                "type": "text"
+              },
+              "related_identifiers": {
+                "type": "object",
+                "properties": {
+                  "created": {
+                    "type": "date",
+                    "format": "date_optional_time||epoch_millis"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "relation": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
+                  },
+                  "value": {
+                    "type": "keyword"
                   }
-                },
-                "result_hash": {
-                  "type": "text"
-                },
-                "result_number": {
-                  "type": "long"
-                },
-                "table_id": {
-                  "type": "keyword"
-                },
-                "titles": {
-                  "type": "nested",
-                  "properties": {
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "language": {
-                      "type": "keyword"
-                    },
-                    "title": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "result_hash": {
+                "type": "text"
+              },
+              "result_number": {
+                "type": "long"
+              },
+              "table_id": {
+                "type": "keyword"
+              },
+              "titles": {
+                "type": "object",
+                "properties": {
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "language": {
+                    "type": "keyword"
+                  },
+                  "title": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
                   }
-                },
-                "type": {
-                  "type": "keyword"
-                },
-                "view_id": {
-                  "type": "keyword"
                 }
+              },
+              "type": {
+                "type": "keyword"
+              },
+              "view_id": {
+                "type": "keyword"
               }
-            },
-            "internal_name": {
-              "type": "keyword"
-            },
-            "is_public": {
-              "type": "boolean"
-            },
-            "is_versioned": {
-              "type": "boolean"
-            },
-            "name": {
-              "type": "keyword"
-            },
-            "owner": {
-              "type": "nested",
-              "properties": {
-                "firstname": {
-                  "type": "keyword"
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "lastname": {
-                  "type": "keyword"
-                },
-                "name": {
-                  "type": "keyword"
-                },
-                "qualified_name": {
-                  "type": "keyword"
-                },
-                "username": {
-                  "type": "keyword"
-                }
+            }
+          },
+          "internal_name": {
+            "type": "keyword"
+          },
+          "is_public": {
+            "type": "boolean"
+          },
+          "is_versioned": {
+            "type": "boolean"
+          },
+          "name": {
+            "type": "keyword"
+          },
+          "owner": {
+            "type": "object",
+            "properties": {
+              "firstname": {
+                "type": "keyword"
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "lastname": {
+                "type": "keyword"
+              },
+              "name": {
+                "type": "keyword"
+              },
+              "qualified_name": {
+                "type": "keyword"
+              },
+              "username": {
+                "type": "keyword"
               }
-            },
-            "queue_name": {
-              "type": "keyword"
-            },
-            "queue_type": {
-              "type": "keyword"
-            },
-            "routing_key": {
-              "type": "keyword"
             }
+          },
+          "queue_name": {
+            "type": "keyword"
+          },
+          "queue_type": {
+            "type": "keyword"
+          },
+          "routing_key": {
+            "type": "keyword"
           }
-        },
-        "views": {
-          "type": "nested",
-          "properties": {
-            "created": {
-              "type": "date",
-              "format": "date_optional_time||epoch_millis"
-            },
-            "database_id": {
-              "type": "keyword"
-            },
-            "id": {
-              "type": "keyword"
-            },
-            "identifiers": {
-              "type": "nested",
-              "properties": {
-                "created": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "creator": {
-                  "type": "nested",
-                  "properties": {
-                    "firstname": {
-                      "type": "keyword"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "lastname": {
-                      "type": "keyword"
-                    },
-                    "name": {
-                      "type": "keyword"
-                    },
-                    "qualified_name": {
-                      "type": "keyword"
-                    },
-                    "username": {
-                      "type": "keyword"
-                    }
+        }
+      },
+      "views": {
+        "type": "object",
+        "properties": {
+          "created": {
+            "type": "date",
+            "format": "date_optional_time||epoch_millis"
+          },
+          "database_id": {
+            "type": "keyword"
+          },
+          "id": {
+            "type": "keyword"
+          },
+          "identifiers": {
+            "type": "object",
+            "properties": {
+              "created": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "creators": {
+                "type": "object",
+                "properties": {
+                  "affiliation": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier_scheme": {
+                    "type": "keyword"
+                  },
+                  "affiliation_identifier_scheme_uri": {
+                    "type": "keyword"
+                  },
+                  "creator_name": {
+                    "type": "text"
+                  },
+                  "firstname": {
+                    "type": "text"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "lastname": {
+                    "type": "text"
+                  },
+                  "name_identifier": {
+                    "type": "keyword"
+                  },
+                  "name_identifier_scheme": {
+                    "type": "keyword"
+                  },
+                  "name_identifier_scheme_uri": {
+                    "type": "keyword"
+                  },
+                  "name_type": {
+                    "type": "keyword"
                   }
-                },
-                "creators": {
-                  "type": "nested",
-                  "properties": {
-                    "affiliation": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier_scheme": {
-                      "type": "keyword"
-                    },
-                    "affiliation_identifier_scheme_uri": {
-                      "type": "keyword"
-                    },
-                    "creator_name": {
-                      "type": "text"
-                    },
-                    "firstname": {
-                      "type": "text"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "lastname": {
-                      "type": "text"
-                    },
-                    "name_identifier": {
-                      "type": "keyword"
-                    },
-                    "name_identifier_scheme": {
-                      "type": "keyword"
-                    },
-                    "name_identifier_scheme_uri": {
-                      "type": "keyword"
-                    },
-                    "name_type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "database_id": {
+                "type": "keyword"
+              },
+              "descriptions": {
+                "type": "object",
+                "properties": {
+                  "description": {
+                    "type": "text"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "language": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
                   }
-                },
-                "database_id": {
-                  "type": "keyword"
-                },
-                "descriptions": {
-                  "type": "nested",
-                  "properties": {
-                    "description": {
-                      "type": "text"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "language": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "doi": {
+                "type": "keyword"
+              },
+              "execution": {
+                "type": "date",
+                "format": "date_optional_time||epoch_millis"
+              },
+              "funders": {
+                "type": "object",
+                "properties": {
+                  "award_number": {
+                    "type": "keyword"
+                  },
+                  "award_title": {
+                    "type": "keyword"
+                  },
+                  "funder_identifier": {
+                    "type": "keyword"
+                  },
+                  "funder_identifier_type": {
+                    "type": "keyword"
+                  },
+                  "funder_name": {
+                    "type": "keyword"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "scheme_uri": {
+                    "type": "keyword"
                   }
-                },
-                "doi": {
-                  "type": "keyword"
-                },
-                "execution": {
-                  "type": "date",
-                  "format": "date_optional_time||epoch_millis"
-                },
-                "funders": {
-                  "type": "nested",
-                  "properties": {
-                    "award_number": {
-                      "type": "keyword"
-                    },
-                    "award_title": {
-                      "type": "keyword"
-                    },
-                    "funder_identifier": {
-                      "type": "keyword"
-                    },
-                    "funder_identifier_type": {
-                      "type": "keyword"
-                    },
-                    "funder_name": {
-                      "type": "keyword"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "scheme_uri": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "id": {
+                "type": "keyword"
+              },
+              "language": {
+                "type": "keyword"
+              },
+              "licenses": {
+                "type": "object",
+                "properties": {
+                  "identifier": {
+                    "type": "keyword"
+                  },
+                  "uri": {
+                    "type": "keyword"
                   }
-                },
-                "id": {
-                  "type": "keyword"
-                },
-                "language": {
-                  "type": "keyword"
-                },
-                "licenses": {
-                  "type": "nested"
-                },
-                "publication_day": {
-                  "type": "integer"
-                },
-                "publication_month": {
-                  "type": "integer"
-                },
-                "publication_year": {
-                  "type": "integer"
-                },
-                "publisher": {
-                  "type": "text"
-                },
-                "query": {
-                  "type": "text"
-                },
-                "query_hash": {
-                  "type": "text"
-                },
-                "query_id": {
-                  "type": "keyword"
-                },
-                "query_normalized": {
-                  "type": "text"
-                },
-                "related_identifiers": {
-                  "type": "nested",
-                  "properties": {
-                    "created": {
-                      "type": "date",
-                      "format": "date_optional_time||epoch_millis"
-                    },
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "relation": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    },
-                    "value": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "publication_day": {
+                "type": "integer"
+              },
+              "publication_month": {
+                "type": "integer"
+              },
+              "publication_year": {
+                "type": "integer"
+              },
+              "publisher": {
+                "type": "text"
+              },
+              "query": {
+                "type": "text"
+              },
+              "query_hash": {
+                "type": "text"
+              },
+              "query_id": {
+                "type": "keyword"
+              },
+              "query_normalized": {
+                "type": "text"
+              },
+              "related_identifiers": {
+                "type": "object",
+                "properties": {
+                  "created": {
+                    "type": "date",
+                    "format": "date_optional_time||epoch_millis"
+                  },
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "relation": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
+                  },
+                  "value": {
+                    "type": "keyword"
                   }
-                },
-                "result_hash": {
-                  "type": "text"
-                },
-                "result_number": {
-                  "type": "long"
-                },
-                "table_id": {
-                  "type": "keyword"
-                },
-                "titles": {
-                  "type": "nested",
-                  "properties": {
-                    "id": {
-                      "type": "keyword"
-                    },
-                    "language": {
-                      "type": "keyword"
-                    },
-                    "title": {
-                      "type": "keyword"
-                    },
-                    "type": {
-                      "type": "keyword"
-                    }
+                }
+              },
+              "result_hash": {
+                "type": "text"
+              },
+              "result_number": {
+                "type": "long"
+              },
+              "table_id": {
+                "type": "keyword"
+              },
+              "titles": {
+                "type": "object",
+                "properties": {
+                  "id": {
+                    "type": "keyword"
+                  },
+                  "language": {
+                    "type": "keyword"
+                  },
+                  "title": {
+                    "type": "keyword"
+                  },
+                  "type": {
+                    "type": "keyword"
                   }
-                },
-                "type": {
-                  "type": "keyword"
-                },
-                "view_id": {
-                  "type": "keyword"
                 }
+              },
+              "type": {
+                "type": "keyword"
+              },
+              "view_id": {
+                "type": "keyword"
               }
-            },
-            "initial_view": {
-              "type": "boolean"
-            },
-            "internal_name": {
-              "type": "keyword"
-            },
-            "is_public": {
-              "type": "boolean"
-            },
-            "name": {
-              "type": "keyword"
-            },
-            "query": {
-              "type": "text"
-            },
-            "query_hash": {
-              "type": "keyword"
             }
+          },
+          "initial_view": {
+            "type": "boolean"
+          },
+          "internal_name": {
+            "type": "keyword"
+          },
+          "is_public": {
+            "type": "boolean"
+          },
+          "name": {
+            "type": "keyword"
+          },
+          "query": {
+            "type": "text"
+          },
+          "query_hash": {
+            "type": "keyword"
           }
         }
       }
-    },
+    }
+  },
   "settings": {
     "index": {
       "number_of_shards": "1",
diff --git a/dbrepo-search-service/Dockerfile b/dbrepo-search-service/Dockerfile
index bb0ea12c68bf4194dd8e085cce48d8f05a7ddfcc..f5acfd093b2770325a20d81b33f1c15c44dafeae 100644
--- a/dbrepo-search-service/Dockerfile
+++ b/dbrepo-search-service/Dockerfile
@@ -27,4 +27,6 @@ ENV LOG_LEVEL=info
 RUN chown -R alpine:alpine ./
 USER alpine
 
+EXPOSE 4000
+
 ENTRYPOINT ["sh", "./scripts/docker-entrypoint.sh"]
diff --git a/dbrepo-search-service/README.md b/dbrepo-search-service/README.md
index 4ee261b34ab74cd175dc722bb93d47105a80a88e..a05a200d2d3dd938d3fd2667c9b1581874df484c 100644
--- a/dbrepo-search-service/README.md
+++ b/dbrepo-search-service/README.md
@@ -1,33 +1,14 @@
-# Search service
+# Search Service
 
-🚧 WIP 🚧
+## Actuator
 
-The dbrepo search service is used to enable searching for
-entries in the opensearch databse.
+- Health: http://localhost:5000/api/search/health
+- Prometheus: http://localhost:5000/metrics
 
-## Running the app
-Test the app locally:
-```shell
-pipenv install && pipenv run flask run --debug --port 4000
-```
+## Swagger UI Endpoints
 
-## Overview
-Here's an overview about the different endpoints available at this service:
-(`<index>` has to be one of the following indices:
-table, user, database, column, identifier, concept, unit, view)
+- Swagger UI: http://localhost:5000/swagger-ui/
 
----
-`/api/search/<index>` :
-returns all entries for a given index
+## OpenAPI Endpoints
 
----
-`/api/search/<index>/fields`:
-returns all the fields that are saved in a given entry
-
----
-`/api/search`:
-this is the main endpoint for searching entries in the opensearch db. 
-You can specify a search term, a time period
-and certain fields that should match a certain value.
-
-ToDo: Continue
\ No newline at end of file
+- OpenAPI v3 as .json: http://localhost:5000/api-search.json
\ No newline at end of file
diff --git a/dbrepo-search-service/app/__init__.py b/dbrepo-search-service/app/__init__.py
index 71269f940a393e5b2f180c0ccab9bf4904a323d8..c8cd7d40738d4e15ac0065ac73b64dfbd126b7a3 100644
--- a/dbrepo-search-service/app/__init__.py
+++ b/dbrepo-search-service/app/__init__.py
@@ -52,7 +52,7 @@ def create_app(config_class=Config):
             {
                 "endpoint": "api-search",
                 "route": "/api-search.json",
-                "rule_filter": lambda rule: rule.endpoint.startswith('actuator'),
+                "rule_filter": lambda rule: True,
                 "model_filter": lambda tag: True,  # all in
             }
         ],
@@ -66,7 +66,7 @@ def create_app(config_class=Config):
         "info": {
             "title": "Database Repository Search Service API",
             "description": "Service that searches the search database",
-            "version": "1.3.0",
+            "version": "$TAG",
             "contact": {
                 "name": "Prof. Andreas Rauber",
                 "email": "andreas.rauber@tuwien.ac.at"
diff --git a/dbrepo-search-service/app/api/routes.py b/dbrepo-search-service/app/api/routes.py
index 5f98a66762e38df95ae4d3b8291ddcf88c07d5d6..72c6134b4e615c8f01e3a484a76cbfbc008e4a9c 100644
--- a/dbrepo-search-service/app/api/routes.py
+++ b/dbrepo-search-service/app/api/routes.py
@@ -52,13 +52,12 @@ def general_filter(index, results):
 
 
 @api_bp.route("/health", methods=["GET"], endpoint="actuator_health")
-@swag_from("us-yml/get_health")  # ToDo: get the SWAG right
+@swag_from("../../us-yml/get_health.yml")
 def health():
     return {"status": "UP"}
 
 
 @api_bp.route("/api/search/<string:index>", methods=["GET"], endpoint="search_get_index")
-@swag_from("us-yml")  # ToDo: get the SWAG right
 def get_index(index):
     """
     returns all entries in a specific index
@@ -72,7 +71,6 @@ def get_index(index):
         }, 404  # ToDo: replace with better error handling
     results = query_index_by_term_opensearch("*", "contains")
     results = general_filter(index, results)
-    total_number_of_results = len(results)
 
     results_per_page = min(request.args.get("results_per_page", 50, type=int), 500)
     max_pages = math.ceil(len(results) / results_per_page)
@@ -82,6 +80,7 @@ def get_index(index):
 
 
 @api_bp.route("/api/search/<string:type>/fields", methods=["GET"], endpoint="search_get_index_fields")
+@swag_from("../../us-yml/get_fields.yml")
 def get_fields(type):
     """
     returns a list of attributes of the data for a specific index.
@@ -91,7 +90,7 @@ def get_fields(type):
     logging.info(f'Searching in index database for type: {type}')
     if type not in available_types:
         return {
-            "results": {},
+            "results": {},  # FIXME this can't be right
         }, 404
     fields = get_fields_for_index(type)
     logging.debug(f'get fields for type {type} resulted in {len(fields)} field(s)')
@@ -99,6 +98,7 @@ def get_fields(type):
 
 
 @api_bp.route("/api/search", methods=["POST"], endpoint="search_fuzzy_search")
+@swag_from("../../us-yml/post_fuzzy_search.yml")
 def post_fuzzy_search():
     """
     Main endpoint for fuzzy searching.
@@ -112,11 +112,14 @@ def post_fuzzy_search():
     req_body = request.json
     logging.debug(f"search request body: {req_body}")
     search_term = req_body.get("search_term")
-    response = general_search(None, search_term, None, None, None)
-    return {"results": response}, 200
+    results = general_search(None, search_term, None, None, None)
+    if "hits" in results and "hits" in results["hits"]:
+        results = [hit["_source"] for hit in results["hits"]["hits"]]
+    return {"results": results}, 200
 
 
 @api_bp.route("/api/search/<string:type>", methods=["POST"], endpoint="search_general_search")
+@swag_from("../../us-yml/post_general_search.yml")
 def post_general_search(type):
     """
     Main endpoint for fuzzy searching.
@@ -151,20 +154,25 @@ def post_general_search(type):
     if type == 'table':
         tmp = []
         for database in response:
-            for table in database["tables"]:
-                table["is_public"] = database["is_public"]
-                tmp.append(table)
+            if database["tables"] is not None:
+                for table in database["tables"]:
+                    table["is_public"] = database["is_public"]
+                    tmp.append(table)
         response = tmp
     if type == 'identifier':
         tmp = []
         for database in response:
-            for identifier in database['identifiers']:
-                tmp.append(identifier)
-            for identifier in database['subsets']:
-                tmp.append(identifier)
-            for table in database['tables']:
-                for identifier in table['identifiers']:
+            if database["identifiers"] is not None:
+                for identifier in database['identifiers']:
+                    tmp.append(identifier)
+            if database["subsets"] is not None:
+                for identifier in database['subsets']:
                     tmp.append(identifier)
+            if database["tables"] is not None:
+                for table in database['tables']:
+                    if database["identifiers"] is not None:
+                        for identifier in table['identifiers']:
+                            tmp.append(identifier)
         for view in [x for xs in response for x in xs["views"]]:
             if 'identifier' in view:
                 tmp.append(view['identifier'])
diff --git a/dbrepo-search-service/app/opensearch_client.py b/dbrepo-search-service/app/opensearch_client.py
index 27be6168ecaa89eb6e802fd333a74f015b70801a..056cef8feecbca7783505b5be688394a149b4358 100644
--- a/dbrepo-search-service/app/opensearch_client.py
+++ b/dbrepo-search-service/app/opensearch_client.py
@@ -211,15 +211,9 @@ def general_search(type=None, search_term=None, t1=None, t2=None, field_value_pa
             else:
                 if '.' in key:
                     logging.debug(f'key {key} is nested: use nested query')
-                    index = key.split('.')[0]
                     musts.append({
-                        "nested": {
-                            "path": index,
-                            "query": {
-                                "term": {
-                                    key: value
-                                }
-                            }
+                        "match": {
+                            key: value
                         }
                     })
                 else:
diff --git a/dbrepo-search-service/us-yml/get_fields.yml b/dbrepo-search-service/us-yml/get_fields.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6ff4c879741babf74f6a72d403b564d9e0acb1ce
--- /dev/null
+++ b/dbrepo-search-service/us-yml/get_fields.yml
@@ -0,0 +1,37 @@
+tags:
+  - search-endpoint
+summary: Get searchable fields
+operationId: get_fields
+parameters:
+  - in: path
+    name: type
+    schema:
+      type: string
+      enum: [ database, table, view, column, user, identifier, concept, unit ]
+    required: true
+    description: The search type.
+responses:
+  "200":
+    description: "List of fields"
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            results:
+              type: array
+              items:
+                type: object
+                properties:
+                  attr_name:
+                    type: "string"
+                    example: "name"
+                  attr_friendly_name:
+                    type: "string"
+                    example: "Name"
+                  type:
+                    type: "string"
+                    example: "string"
+                    description: OpenSearch data types.
+  "404":
+    description: Invalid type.
diff --git a/dbrepo-search-service/us-yml/post_fuzzy_search.yml b/dbrepo-search-service/us-yml/post_fuzzy_search.yml
new file mode 100644
index 0000000000000000000000000000000000000000..09769209f14148a3069f28fd9c27e18ffdf42fb5
--- /dev/null
+++ b/dbrepo-search-service/us-yml/post_fuzzy_search.yml
@@ -0,0 +1,31 @@
+tags:
+  - search-endpoint
+summary: Performs a fuzzy search
+operationId: post_fuzzy_search
+description: Performs a fuzzy search
+consumes:
+  - application/json
+produces:
+  - application/json
+parameters:
+  - in: "body"
+    name: "body"
+    required: true
+    schema:
+      type: "object"
+      properties:
+        search_term:
+          type: "string"
+          example: "air quality"
+responses:
+  200:
+    description: OK, contains the elements formatted as an array of JSON arrays
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            results:
+              type: array
+              items:
+                type: object
diff --git a/dbrepo-search-service/us-yml/post_general_search.yml b/dbrepo-search-service/us-yml/post_general_search.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a57f1337080361c18ebf0fa21ae4b17d976b93cc
--- /dev/null
+++ b/dbrepo-search-service/us-yml/post_general_search.yml
@@ -0,0 +1,50 @@
+tags:
+  - search-endpoint
+summary: Performs a general search
+operationId: post_general_search
+description: Performs a general search
+consumes:
+  - application/json
+produces:
+  - application/json
+parameters:
+  - in: path
+    name: type
+    schema:
+      type: string
+      enum: [ database, table, view, column, user, identifier, concept, unit ]
+    required: true
+    description: The search type.
+  - in: "body"
+    name: "body"
+    required: true
+    schema:
+      type: "object"
+      properties:
+        search_term:
+          type: "string"
+          example: "air quality"
+        field_value_pairs:
+          type: "object"
+        t1:
+          type: "integer"
+          example: 0
+        t2:
+          type: "integer"
+          example: 100
+responses:
+  200:
+    description: OK, contains the elements formatted as an array of JSON arrays
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            results:
+              type: array
+              items:
+                type: object
+            type:
+              type: string
+              enum: [ database, table, view, column, user, identifier, concept, unit ]
+              description: "Same as the requested type"
diff --git a/dbrepo-ui/api/authentication.service.js b/dbrepo-ui/api/authentication.service.js
index 776aca523bf5768604687c5f705609b2094e0f56..035a8106202043cdb98f4ac36dc3c063f1d3aefb 100644
--- a/dbrepo-ui/api/authentication.service.js
+++ b/dbrepo-ui/api/authentication.service.js
@@ -3,7 +3,6 @@ import store from '@/store'
 import qs from 'qs'
 import UserMapper from '@/api/user.mapper'
 import axios from 'axios'
-import AuthenticationMapper from '@/api/authentication.mapper'
 
 /**
  * Service class for interaction with Authentication Service in the back end.
@@ -100,22 +99,6 @@ class AuthenticationService {
         })
     })
   }
-
-  refreshToken () {
-    const refreshToken = store().state.refreshToken
-    if (AuthenticationMapper.isExpiredToken(refreshToken)) {
-      /* refresh token expired */
-      console.error('Refresh token expired:', AuthenticationMapper.tokenToExpiryDate(refreshToken))
-      return false
-    }
-    this.authenticateToken(refreshToken)
-      .then((response) => {
-        store().commit('SET_TOKEN', response.access_token)
-        store().commit('SET_REFRESH_TOKEN', response.refresh_token)
-        console.debug('new access token expires:', AuthenticationMapper.tokenToExpiryDate(refreshToken))
-        return false
-      })
-  }
 }
 
 export default new AuthenticationService()
diff --git a/dbrepo-ui/api/identifier.mapper.js b/dbrepo-ui/api/identifier.mapper.js
index 868535f88d2b9ec96a3a797b1eba27ffe503d5f0..1d0da950aacc43bb38d2eb23ea3b11443bcefbf4 100644
--- a/dbrepo-ui/api/identifier.mapper.js
+++ b/dbrepo-ui/api/identifier.mapper.js
@@ -219,13 +219,23 @@ class IdentifierMapper {
     const identifier = database.identifiers[0]
     const partIdentifiers = []
     if (database.subsets.length > 0) {
-      database.subsets.forEach((s) => { if (s.identifiers.length > 0) { s.identifiers.forEach(i => partIdentifiers.push(i)) } })
+      database.subsets.forEach((s) => {
+        partIdentifiers.push(s)
+      })
     }
     if (database.tables.length > 0) {
-      database.tables.forEach((t) => { if (t.identifiers.length > 0) { t.identifiers.forEach(i => partIdentifiers.push(i)) } })
+      database.tables.forEach((t) => {
+        if (t.identifiers.length > 0) {
+          t.identifiers.forEach(i => partIdentifiers.push(i))
+        }
+      })
     }
     if (database.views.length > 0) {
-      database.views.forEach((v) => { if (v.identifiers.length > 0) { v.identifiers.forEach(i => partIdentifiers.push(i)) } })
+      database.views.forEach((v) => {
+        if (v.identifiers.length > 0) {
+          v.identifiers.forEach(i => partIdentifiers.push(i))
+        }
+      })
     }
     return {
       '@context': 'https://schema.org/',
diff --git a/dbrepo-ui/api/identifier.service.js b/dbrepo-ui/api/identifier.service.js
index a214c6d9e7c6a5590bee4ff8fd0be3618ceaf5ce..8d799be3f2d218f42bf8a10e89454b74bccdb25b 100644
--- a/dbrepo-ui/api/identifier.service.js
+++ b/dbrepo-ui/api/identifier.service.js
@@ -17,8 +17,27 @@ class IdentifierService {
     })
   }
 
-  find (id) {
-    return this.findAccept(id, 'application/json')
+  retrieve (url) {
+    return new Promise((resolve, reject) => {
+      if (url === null) {
+        reject(Error)
+      }
+      api.get(`/api/identifier/retrieve?url=${url}`, { headers: { Accept: 'application/json' } })
+        .then((response) => {
+          const { status, data } = response
+          if (status === 200) {
+            console.debug('response metadata', data)
+            resolve(data)
+          } else {
+            console.error('response metadata', response)
+            reject(response)
+          }
+        })
+        .catch((error) => {
+          displayError('Failed to load identifier', error)
+          reject(error)
+        })
+    })
   }
 
   retrieve (url) {
diff --git a/dbrepo-ui/api/query.service.js b/dbrepo-ui/api/query.service.js
index 5029b562ae80013b9f8e7a6a6ca9800183eac679..c2b456ddc37331c1f878c0ffdbcc288ffa03b6c9 100644
--- a/dbrepo-ui/api/query.service.js
+++ b/dbrepo-ui/api/query.service.js
@@ -30,9 +30,9 @@ class QueryService {
     })
   }
 
-  persist (databaseId, queryId) {
+  persist (databaseId, queryId, persist) {
     return new Promise((resolve, reject) => {
-      api.put(`/api/database/${databaseId}/query/${queryId}`, { persist: true }, { headers: { Accept: 'application/json' } })
+      api.put(`/api/database/${databaseId}/query/${queryId}`, { persist }, { headers: { Accept: 'application/json' } })
         .then((response) => {
           const query = response.data
           console.debug('response query', query)
diff --git a/dbrepo-ui/components/UserBadge.vue b/dbrepo-ui/components/UserBadge.vue
new file mode 100644
index 0000000000000000000000000000000000000000..130b47636d54045ce9150f919c9e0037eccfdddc
--- /dev/null
+++ b/dbrepo-ui/components/UserBadge.vue
@@ -0,0 +1,63 @@
+<template>
+  <p class="mb-0">
+    <OrcidIcon v-if="hasOrcid" :orcid="orcid" />
+    <span v-if="isSelf">
+      <v-badge inline content="you" color="code">{{ creatorName }}</v-badge>
+    </span>
+    <span v-else v-text="creatorName" />
+  </p>
+</template>
+<script>
+import OrcidIcon from '@/components/icons/OrcidIcon.vue'
+import UserMapper from '@/api/user.mapper'
+
+export default {
+  components: {
+    OrcidIcon
+  },
+  props: {
+    user: {
+      type: Object,
+      default () {
+        return {
+          id: null,
+          attributes: {
+            orcid: null
+          }
+        }
+      }
+    },
+    otherUser: {
+      type: Object,
+      default () {
+        return {
+          id: null
+        }
+      }
+    }
+  },
+  computed: {
+    hasOrcid () {
+      if (!this.user || !this.user.attributes || !this.user.attributes.orcid) {
+        return false
+      }
+      return true
+    },
+    orcid () {
+      if (!this.hasOrcid) {
+        return false
+      }
+      return this.user.attributes.orcid
+    },
+    creatorName () {
+      return UserMapper.userToFullName(this.user)
+    },
+    isSelf () {
+      if (!this.otherUser) {
+        return false
+      }
+      return this.user.id === this.otherUser.id
+    }
+  }
+}
+</script>
diff --git a/dbrepo-ui/components/UserToolbar.vue b/dbrepo-ui/components/UserToolbar.vue
index 878a48085952cbb9774cba87e61aad394b419bfe..47e925add6e215794ef92f77231345910d4dc74c 100644
--- a/dbrepo-ui/components/UserToolbar.vue
+++ b/dbrepo-ui/components/UserToolbar.vue
@@ -12,7 +12,7 @@
       <v-tab to="/user/authentication">
         Authentication
       </v-tab>
-      <v-tab v-if="canHandleMessages" to="/user/developer">
+      <v-tab to="/user/developer">
         Developer
       </v-tab>
     </v-tabs>
@@ -33,21 +33,6 @@ export default {
     },
     roles () {
       return this.$store.state.roles
-    },
-    canCreateMessage () {
-      if (!this.roles) {
-        return false
-      }
-      return this.roles.includes('create-maintenance-message')
-    },
-    canModifyMessage () {
-      if (!this.roles) {
-        return false
-      }
-      return this.roles.includes('modify-maintenance-message')
-    },
-    canHandleMessages () {
-      return this.canCreateMessage || this.canModifyMessage
     }
   }
 }
diff --git a/dbrepo-ui/components/DatabaseList.vue b/dbrepo-ui/components/database/DatabaseList.vue
similarity index 81%
rename from dbrepo-ui/components/DatabaseList.vue
rename to dbrepo-ui/components/database/DatabaseList.vue
index c1d6c6db2ae9d3d60adb0d08c5c5cc685bb7b1fe..6d2aa141b08c6e2086d108b55157ec321405cd98 100644
--- a/dbrepo-ui/components/DatabaseList.vue
+++ b/dbrepo-ui/components/database/DatabaseList.vue
@@ -1,9 +1,23 @@
 <template>
   <div>
-    <v-progress-linear v-if="loadingDatabases" :indeterminate="!error" />
     <v-card v-if="!$vuetify.theme.dark && databases.length> 0" flat tile>
       <v-divider class="mx-4" />
     </v-card>
+    <div v-if="loading">
+      <v-card v-for="(idx) in [1,2,3]" :key="idx" flat tile>
+        <v-divider class="mx-4" />
+        <v-card-subtitle class="db-subtitle">
+          <v-skeleton-loader type="text" :style="randomWidth(100,300)" />
+          <v-skeleton-loader type="text" class="pt-2" :style="randomWidth(100,200)" />
+        </v-card-subtitle>
+        <v-card-text class="db-description">
+          <v-skeleton-loader type="chip" />
+          <v-skeleton-loader type="text" class="pt-4" :style="randomWidth(800,1000)" />
+          <v-skeleton-loader type="text" :style="randomWidth(800,1000)" />
+          <v-skeleton-loader type="text" :style="randomWidth(600,1000)" />
+        </v-card-text>
+      </v-card>
+    </div>
     <v-card
       v-for="(database, idx) in databases"
       :key="idx"
@@ -72,11 +86,16 @@ export default {
       default: () => {
         return []
       }
+    },
+    loading: {
+      type: Boolean,
+      default: () => {
+        return true
+      }
     }
   },
   data () {
     return {
-      loadingDatabases: false,
       loadingCreate: false,
       createDbDialog: false,
       searchQuery: null,
@@ -150,11 +169,14 @@ export default {
       }
       return database.identifiers[0]
     },
-    formatLanguage
+    formatLanguage,
+    randomWidth (min, max) {
+      const width = Math.random() * (max - min) + min
+      return `width: ${width}px !important;`
+    }
   }
 }
 </script>
-
 <style>
 .v-chip:not(:first-child) {
   margin-left: 8px;
@@ -165,4 +187,7 @@ export default {
 .db-tags {
   margin-bottom: 8px;
 }
+.skeleton-small > div {
+  width: 100px !important;
+}
 </style>
diff --git a/dbrepo-ui/components/DatabaseToolbar.vue b/dbrepo-ui/components/database/DatabaseToolbar.vue
similarity index 75%
rename from dbrepo-ui/components/DatabaseToolbar.vue
rename to dbrepo-ui/components/database/DatabaseToolbar.vue
index 3b68b23fe3f3a03190c9a5914d42e4c1c2d1bb11..3f6147b44851cb7fb895c7d1b5cfabce1d60f2dd 100644
--- a/dbrepo-ui/components/DatabaseToolbar.vue
+++ b/dbrepo-ui/components/database/DatabaseToolbar.vue
@@ -2,7 +2,11 @@
   <div v-if="database">
     <v-toolbar flat>
       <v-toolbar-title>
+<<<<<<<< HEAD:dbrepo-ui/components/DatabaseToolbar.vue
         <span v-if="$vuetify.breakpoint.lgAndUp">{{ database.name }}</span>
+========
+        <span v-if="$vuetify.breakpoint.lgAndUp" v-text="database.name" />
+>>>>>>>> master:dbrepo-ui/components/database/DatabaseToolbar.vue
         <v-tooltip bottom>
           <template v-slot:activator="{ on, attrs }">
             <v-icon
@@ -29,6 +33,7 @@
       <v-spacer />
       <v-toolbar-title>
         <v-btn v-if="canImportCsv" class="mb-1" :to="`/database/${$route.params.database_id}/table/import`">
+<<<<<<<< HEAD:dbrepo-ui/components/DatabaseToolbar.vue
           <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-cloud-upload</v-icon> Import .csv
         </v-btn>
         <DownloadButton
@@ -48,6 +53,21 @@
         </v-btn>
         <v-btn v-if="canCreateIdentifier" color="primary" class="mb-1" :to="`/database/${$route.params.database_id}/persist`">
           <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-identifier</v-icon> Get PID
+========
+          <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import&nbsp;</span> csv
+        </v-btn>
+        <v-btn v-if="canCreateSubset" color="secondary" class="mb-1 white--text" :to="`/database/${$route.params.database_id}/query/create`">
+          <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create&nbsp;</span> Subset
+        </v-btn>
+        <v-btn v-if="canCreateView" color="secondary" class="mb-1 white--text" :to="`/database/${$route.params.database_id}/view/create`">
+          <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-view-carousel-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create&nbsp;</span> View
+        </v-btn>
+        <v-btn v-if="canCreateTable" color="secondary" class="mb-1" :to="`/database/${$route.params.database_id}/table/create`">
+          <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-table-large-plus</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create&nbsp;</span> Table
+        </v-btn>
+        <v-btn v-if="canCreateIdentifier" color="primary" class="mb-1" :to="`/database/${$route.params.database_id}/persist`">
+          <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-identifier</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get&nbsp;</span> PID
+>>>>>>>> master:dbrepo-ui/components/database/DatabaseToolbar.vue
         </v-btn>
       </v-toolbar-title>
       <template v-slot:extension>
@@ -74,12 +94,13 @@
 </template>
 
 <script>
-import DownloadButton from '@/components/identifier/DownloadButton'
-
 export default {
+<<<<<<<< HEAD:dbrepo-ui/components/DatabaseToolbar.vue
   components: {
     DownloadButton
   },
+========
+>>>>>>>> master:dbrepo-ui/components/database/DatabaseToolbar.vue
   data () {
     return {
       tab: null,
diff --git a/dbrepo-ui/components/identifier/Persist.vue b/dbrepo-ui/components/identifier/Persist.vue
index 9c8bc22c37d97f8ec9259d480eda3654919622c0..e95f644bde687eebe789c19652f5873f2dd946ed 100644
--- a/dbrepo-ui/components/identifier/Persist.vue
+++ b/dbrepo-ui/components/identifier/Persist.vue
@@ -411,7 +411,7 @@
                     @focusout="retrieveFunder(funder)" />
                 </v-col>
                 <v-col cols="4" class="mt-5">
-                  <v-btn v-if="i > 0" color="error" small @click="deleteFunder(i)">
+                  <v-btn color="error" small @click="deleteFunder(i)">
                     Remove
                   </v-btn>
                 </v-col>
@@ -813,9 +813,6 @@ export default {
       this.identifier.creators.splice(index, 1)
     },
     deleteFunder (index) {
-      if (index === 0) {
-        return
-      }
       this.identifier.funders.splice(index, 1)
     },
     deleteTitle (index) {
@@ -844,6 +841,9 @@ export default {
             this.$router.push(this.backTo)
             this.$toast.success(this.prefix + ' successfully persisted')
           })
+          .catch(() => {
+            this.loading = false
+          })
           .finally(() => {
             this.loading = false
           })
@@ -855,6 +855,9 @@ export default {
             await this.$toast.success(this.prefix + ' successfully persisted')
             await this.$router.push(this.backTo)
           })
+          .catch(() => {
+            this.loading = false
+          })
           .finally(() => {
             this.loading = false
           })
@@ -866,6 +869,9 @@ export default {
         .then((licenses) => {
           this.licenses = licenses
         })
+        .catch(() => {
+          this.loading = false
+        })
         .finally(() => {
           this.loading = false
         })
diff --git a/dbrepo-ui/components/query/Results.vue b/dbrepo-ui/components/query/Results.vue
index 3249f99e18ba8a3889862865a95024fd48f16ff5..f9fa1cebd1337c502ba5faabf9f9a4f5c6438095 100644
--- a/dbrepo-ui/components/query/Results.vue
+++ b/dbrepo-ui/components/query/Results.vue
@@ -1,11 +1,14 @@
 <template>
-  <v-data-table
-    flat
-    :headers="headers"
-    :items="result.rows"
-    :loading="loading > 0"
-    :options.sync="options"
-    :server-items-length="total" />
+  <div>
+    <v-data-table
+      flat
+      :headers="headers"
+      :items="result.rows"
+      :loading="loading > 0"
+      :options.sync="options"
+      :footer-props="footerProps"
+      :server-items-length="total" />
+  </div>
 </template>
 
 <script>
@@ -36,6 +39,10 @@ export default {
         page: 1,
         itemsPerPage: 10
       },
+      footerProps: {
+        showFirstLastPage: true,
+        itemsPerPageOptions: [10, 25, 50, 100]
+      },
       total: -1
     }
   },
@@ -71,10 +78,11 @@ export default {
         statement: sql,
         timestamp
       }
-      QueryService.execute(this.$route.params.database_id, payload, 0, this.options.itemsPerPage)
+      QueryService.execute(this.$route.params.database_id, payload, this.options.page - 1, this.options.itemsPerPage)
         .then((result) => {
           this.mapResults(result)
           parent.resultId = result.id
+          this.id = result.id
         })
         .finally(() => {
           this.loading--
@@ -86,7 +94,7 @@ export default {
       }
       this.loading++
       if (this.type === 'query') {
-        QueryService.reExecuteQuery(this.$route.params.database_id, id, 0, this.options.itemsPerPage)
+        QueryService.reExecuteQuery(this.$route.params.database_id, id, this.options.page - 1, this.options.itemsPerPage)
           .then((result) => {
             this.mapResults(result)
             this.id = id
@@ -95,7 +103,7 @@ export default {
             this.loading--
           })
       } else {
-        QueryService.reExecuteView(this.$route.params.database_id, id, 0, this.options.itemsPerPage)
+        QueryService.reExecuteView(this.$route.params.database_id, id, this.options.page - 1, this.options.itemsPerPage)
           .then((result) => {
             this.mapResults(result)
             this.id = id
diff --git a/dbrepo-ui/components/QueryList.vue b/dbrepo-ui/components/query/SubsetList.vue
similarity index 86%
rename from dbrepo-ui/components/QueryList.vue
rename to dbrepo-ui/components/query/SubsetList.vue
index 00e6934e1a93c241ec517669e5d6bf95aadde28b..9a75e6f14270e645c55128c373956785ad4ce05d 100644
--- a/dbrepo-ui/components/QueryList.vue
+++ b/dbrepo-ui/components/query/SubsetList.vue
@@ -20,7 +20,7 @@
                 <pre>{{ item.query }}</pre>
               </v-list-item-subtitle>
             </v-list-item-content>
-            <v-list-item-action v-if="item.identifier">
+            <v-list-item-action v-if="item.identifiers.length > 0">
               <v-tooltip left>
                 <template v-slot:activator="{ on, attrs }">
                   <v-icon color="primary" v-bind="attrs" v-on="on">mdi-identifier</v-icon>
@@ -39,6 +39,7 @@
 import { formatTimestampUTCLabel } from '@/utils'
 import QueryService from '@/api/query.service'
 import IdentifierService from '@/api/identifier.service'
+import IdentifierMapper from '@/api/identifier.mapper'
 
 export default {
   data () {
@@ -88,7 +89,7 @@ export default {
           this.queries = queries
         })
         .catch((error) => {
-          if (error.response.status === 405) {
+          if (error.response.status === 403 || error.response.status === 405) {
             this.isAuthorizationError = true
             return
           }
@@ -101,20 +102,16 @@ export default {
         })
     },
     title (query) {
-      if (!query.identifier || !('titles' in query.identifier)) {
+      if (query.identifiers.length === 0) {
         return formatTimestampUTCLabel(query.created)
       }
-      const enTitle = query.identifier.titles.filter(t => t.language).filter(t => t.language === 'en')
-      if (enTitle.length !== 1) {
-        return query.identifier.titles[0].title
-      }
-      return enTitle[0].title
+      return IdentifierMapper.identifierPreferEnglishTitle(query.identifiers[0])
     },
     link (query) {
       return `/database/${this.$route.params.database_id}/query/${query.id}/info`
     },
-    clazz (queryOrIdentifier) {
-      if ('query_id' in queryOrIdentifier || queryOrIdentifier.identifier) {
+    clazz (query) {
+      if (query.identifiers.length > 0) {
         return 'primary--text'
       }
       return null
diff --git a/dbrepo-ui/components/query/SubsetToolbar.vue b/dbrepo-ui/components/query/SubsetToolbar.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3f6f76a030bdc54c7af28edd82283793c406a80b
--- /dev/null
+++ b/dbrepo-ui/components/query/SubsetToolbar.vue
@@ -0,0 +1,205 @@
+<template>
+  <div>
+    <v-toolbar flat>
+      <v-toolbar-title>
+        <v-btn id="back-btn" class="mr-2" :to="`/database/${$route.params.database_id}/query`">
+          <v-icon left>mdi-arrow-left</v-icon>
+        </v-btn>
+      </v-toolbar-title>
+      <v-toolbar-title v-if="identifier" v-text="title" />
+      <v-spacer />
+      <v-toolbar-title>
+        <v-btn v-if="canPersistQuery" :loading="loadingSave" class="mb-1" @click.stop="save">
+          <v-icon left>mdi-content-save-outline</v-icon> Save
+        </v-btn>
+        <v-btn v-if="canForgetQuery" :loading="loadingSave" class="mb-1" @click.stop="forget">
+          <v-icon left>mdi-trash-can-outline</v-icon> Soft-Delete
+        </v-btn>
+        <v-btn v-if="result_visibility && subset && subset.result_number" class="mb-1" :loading="downloadLoading" @click.stop="downloadSubset">
+          <v-icon left>mdi-download</v-icon> Data .csv
+        </v-btn>
+        <DownloadButton v-if="identifier" :pid="identifier.id" class="mb-1">
+          <v-icon left>mdi-code-tags</v-icon> PID .xml
+        </DownloadButton>
+        <v-btn v-if="canGetPid" class="mb-1" color="primary" :disabled="!executionUTC" :to="`/database/${$route.params.database_id}/query/${$route.params.query_id}/persist`">
+          <v-icon left>mdi-content-save-outline</v-icon> Get PID
+        </v-btn>
+      </v-toolbar-title>
+    </v-toolbar>
+    <v-tabs v-model="tab" color="primary">
+      <v-tab :to="`/database/${$route.params.database_id}/query/${$route.params.query_id}/info`">
+        Info
+      </v-tab>
+      <v-tab :to="`/database/${$route.params.database_id}/query/${$route.params.query_id}/data`">
+        Data
+      </v-tab>
+    </v-tabs>
+  </div>
+</template>
+
+<script>
+import UserUtils from '@/api/user.utils'
+import QueryService from '@/api/query.service'
+import DownloadButton from '@/components/identifier/DownloadButton.vue'
+import IdentifierMapper from '@/api/identifier.mapper'
+import { formatTimestampUTCLabel } from '@/utils'
+
+export default {
+  components: {
+    DownloadButton
+  },
+  data () {
+    return {
+      tab: null,
+      loading: false,
+      loadingSave: false,
+      downloadLoading: false,
+      subset: null
+    }
+  },
+  computed: {
+    pid () {
+      return this.$route.query.pid
+    },
+    database () {
+      return this.$store.state.database
+    },
+    access () {
+      return this.$store.state.access
+    },
+    user () {
+      return this.$store.state.user
+    },
+    roles () {
+      return this.$store.state.roles
+    },
+    identifiers () {
+      if (!this.database || !this.database.subsets || this.database.subsets.length === 0) {
+        return []
+      }
+      return this.database.subsets.filter(s => s.query_id === Number(this.$route.params.query_id))
+    },
+    identifier () {
+      /* mount pid */
+      if (this.pid) {
+        const filter = this.identifiers.filter(i => i.id === Number(this.pid))
+        if (filter.length > 0) {
+          const identifier = filter[0]
+          console.debug('identifier set according to route pid', identifier)
+          return identifier
+        }
+      }
+      const identifier = this.identifiers[0]
+      console.debug('defaulted to latest identifier', identifier)
+      return identifier
+    },
+    canPersistQuery () {
+      if (this.loading || !this.subset || this.subset.is_persisted) {
+        return false
+      }
+      return UserUtils.hasReadAccess(this.access)
+    },
+    canForgetQuery () {
+      if (this.loading || !this.subset || !this.subset.is_persisted) {
+        return false
+      }
+      if (this.subset.identifiers.length > 0) {
+        return false
+      }
+      return UserUtils.hasReadAccess(this.access)
+    },
+    executionUTC () {
+      if (!this.subset) {
+        return null
+      }
+      return formatTimestampUTCLabel(this.subset.created)
+    },
+    result_visibility () {
+      if (!this.database) {
+        return false
+      }
+      if (this.database.is_public) {
+        return true
+      }
+      return this.subset.creator.username === this.username
+    },
+    canGetPid () {
+      if (!this.user || !this.subset || !this.database) {
+        return false
+      }
+      return this.database.owner.id === this.user.id || (this.subset.creator.id === this.user.id && UserUtils.hasReadAccess(this.access))
+    },
+    title () {
+      if (!this.identifier) {
+        return null
+      }
+      return IdentifierMapper.identifierPreferEnglishTitle(this.identifier)
+    }
+  },
+  mounted () {
+    /* load subset metadata */
+    if (!this.subset) {
+      this.loadSubset()
+    }
+  },
+  methods: {
+    save () {
+      this.loadingSave = true
+      QueryService.persist(this.$route.params.database_id, this.$route.params.query_id, true)
+        .then((subset) => {
+          this.subset = subset
+        })
+        .catch(() => {
+          this.loadingSave = false
+        })
+        .finally(() => {
+          this.loadingSave = false
+        })
+    },
+    forget () {
+      this.loadingSave = true
+      QueryService.persist(this.$route.params.database_id, this.$route.params.query_id, false)
+        .then((subset) => {
+          this.subset = subset
+        })
+        .catch(() => {
+          this.loadingSave = false
+        })
+        .finally(() => {
+          this.loadingSave = false
+        })
+    },
+    loadSubset () {
+      this.loading = true
+      QueryService.findOne(this.$route.params.database_id, this.$route.params.query_id)
+        .then((subset) => {
+          this.subset = subset
+        })
+        .catch(() => {
+          this.loading = false
+        })
+        .finally(() => {
+          this.loading = false
+        })
+    },
+    downloadSubset () {
+      this.downloadLoading = true
+      QueryService.exportSubset(this.$route.params.database_id, this.$route.params.query_id)
+        .then((data) => {
+          const url = window.URL.createObjectURL(new Blob([data]))
+          const link = document.createElement('a')
+          link.href = url
+          link.setAttribute('download', 'subset.csv')
+          document.body.appendChild(link)
+          link.click()
+        })
+        .catch(() => {
+          this.downloadLoading = false
+        })
+        .finally(() => {
+          this.downloadLoading = false
+        })
+    }
+  }
+}
+</script>
diff --git a/dbrepo-ui/components/search/AdvancedSearch.vue b/dbrepo-ui/components/search/AdvancedSearch.vue
index ac02bdf2e12eeb66a69ee9ab4f05f576302e834c..7457f753e756598f326acfdfd64b2d66db0fdcdb 100644
--- a/dbrepo-ui/components/search/AdvancedSearch.vue
+++ b/dbrepo-ui/components/search/AdvancedSearch.vue
@@ -37,9 +37,6 @@
                 label="Internal Name" />
             </v-col>
           </v-row>
-          <v-row v-if="loadingFields" dense>
-            <v-progress-circular color="primary" indeterminate />
-          </v-row>
           <v-row v-if="!loadingFields && renderedFields" dense>
             <v-col v-for="field in renderedFields" :key="`f-${field.attr_name}`" cols="3">
               <v-select
@@ -99,37 +96,37 @@
                 clearable />
             </v-col>
           </v-row>
-          <p v-if="isEligibleConceptOrUnitSearch" class="mt-4">
+          <p v-if="isEligibleUnitIndependentSearch" class="mt-4">
             If you select a <code>concept</code> and <code>unit</code>, you can search across columns regardless of their
             unit of measurement.
           </p>
-          <v-row v-if="isEligibleConceptOrUnitSearch" dense>
-            <v-col cols="3">
+          <v-row v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" dense>
+            <v-col v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" cols="3">
               <v-select
-                v-model="advancedSearchData['concept.uri']"
+                v-model="advancedSearchData['tables.columns.concept.uri']"
                 clearable
                 :items="concepts"
                 item-text="name"
                 item-value="uri"
                 label="Concept" />
             </v-col>
-            <v-col cols="3">
+            <v-col v-if="isEligibleConceptOrUnitSearch || isEligibleUnitIndependentSearch" cols="3">
               <v-select
-                v-model="advancedSearchData['unit.uri']"
+                v-model="advancedSearchData['tables.columns.unit.uri']"
                 clearable
                 :items="units"
                 item-text="name"
                 item-value="uri"
                 label="Unit" />
             </v-col>
-            <v-col cols="3">
+            <v-col v-if="isEligibleUnitIndependentSearch" cols="3">
               <v-text-field
                 v-model="advancedSearchData['t1']"
                 clearable
                 type="number"
                 label="Start Value" />
             </v-col>
-            <v-col cols="3">
+            <v-col v-if="isEligibleUnitIndependentSearch" cols="3">
               <v-text-field
                 v-model="advancedSearchData['t2']"
                 clearable
@@ -224,6 +221,9 @@ export default {
       }
     },
     isEligibleConceptOrUnitSearch () {
+      return ['column', 'database'].includes(this.searchType)
+    },
+    isEligibleUnitIndependentSearch () {
       return ['column'].includes(this.searchType)
     },
     isEligibleYearRangeSearch () {
diff --git a/dbrepo-ui/components/TableList.vue b/dbrepo-ui/components/table/TableList.vue
similarity index 100%
rename from dbrepo-ui/components/TableList.vue
rename to dbrepo-ui/components/table/TableList.vue
diff --git a/dbrepo-ui/components/TableSchema.vue b/dbrepo-ui/components/table/TableSchema.vue
similarity index 94%
rename from dbrepo-ui/components/TableSchema.vue
rename to dbrepo-ui/components/table/TableSchema.vue
index 4714f76275fef000439ed373a582883ff861d26f..9fa120f44bf03fae3f044f9edd8eee22860d2303 100644
--- a/dbrepo-ui/components/TableSchema.vue
+++ b/dbrepo-ui/components/table/TableSchema.vue
@@ -14,7 +14,7 @@
               v-model="c.name"
               required
               :rules="[v => !!v || $t('Required')]"
-              :error-messages="needsSequence && c.name === 'id' ? ['Column needs to be declared as primary key'] : []"
+              :error-messages="needsSequence && c.name.toLowerCase() === 'id' ? ['Column needs to be declared as primary key'] : []"
               label="Name *" />
           </v-col>
           <v-col cols="2">
@@ -67,7 +67,7 @@
               :error-messages="dErrorMessages(c)"
               label="d *" />
           </v-col>
-          <v-col v-if="hasDate(c)" cols="1">
+          <v-col v-if="hasDate(c)" cols="2">
             <v-select
               v-model="c.dfid"
               required
@@ -118,7 +118,6 @@
 </template>
 
 <script>
-import DatabaseService from '@/api/database.service'
 import QueryMapper from '@/api/query.mapper'
 
 export default {
@@ -139,7 +138,6 @@ export default {
   data () {
     return {
       loading: false,
-      dateFormats: [],
       valid: true,
       finished: false,
       tableColumns: [],
@@ -147,13 +145,19 @@ export default {
     }
   },
   computed: {
+    database () {
+      return this.$store.state.database
+    },
     needsSequence () {
       return this.columns.filter(c => c.primary_key).length === 0
+    },
+    dateFormats () {
+      if (!this.database || !('container' in this.database) || !('image' in this.database.container) || !('date_formats' in this.database.container.image)) {
+        return []
+      }
+      return this.database.container.image.date_formats
     }
   },
-  mounted () {
-    this.loadDateFormats()
-  },
   methods: {
     shift (column) {
       if (!this.columns || this.columns.length === 0) {
@@ -171,14 +175,6 @@ export default {
       }
       return shift
     },
-    async loadDateFormats () {
-      try {
-        const database = await DatabaseService.findOne(this.$route.params.database_id)
-        this.dateFormats = database.image.date_formats
-      } finally {
-        this.loading = false
-      }
-    },
     submit () {
       this.finished = true
       this.loading = true
diff --git a/dbrepo-ui/components/TableToolbar.vue b/dbrepo-ui/components/table/TableToolbar.vue
similarity index 87%
rename from dbrepo-ui/components/TableToolbar.vue
rename to dbrepo-ui/components/table/TableToolbar.vue
index 05fca69bbe93792aa6ba9d90a53e747d89db69a3..4deb12f3f902ccba38e7ea9f9bd941a48d5e7431 100644
--- a/dbrepo-ui/components/TableToolbar.vue
+++ b/dbrepo-ui/components/table/TableToolbar.vue
@@ -7,33 +7,33 @@
         </v-btn>
       </v-toolbar-title>
       <v-toolbar-title>
-        {{ table.name }}
+        <span v-if="$vuetify.breakpoint.lgAndUp" v-text="table.name" />
       </v-toolbar-title>
       <v-spacer />
       <v-toolbar-title>
         <v-btn v-if="canAddTuple" class="mb-1" @click="addTuple">
-          <v-icon left>mdi-plus</v-icon> Add
+          <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-plus</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Add</span>
         </v-btn>
         <v-btn v-if="canEditTuple" color="warning" class="mb-1 black--text" @click="editTuple">
-          <v-icon left>mdi-pencil</v-icon> Edit
+          <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-pencil</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Edit</span>
         </v-btn>
         <v-btn v-if="canDeleteTuple" color="error" class="mb-1" :loading="loadingDelete" @click="deleteItems">
-          <v-icon left>mdi-delete</v-icon> Delete <span v-if="selection.length > 1">&nbsp;{{ selection.length }}</span>
+          <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-delete</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Delete</span>
         </v-btn>
         <v-btn v-if="canImportCsv" class="mb-1" :to="`/database/${$route.params.database_id}/table/${$route.params.table_id}/import`">
-          <v-icon left>mdi-cloud-upload</v-icon> Import .csv
+          <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import&nbsp;</span> csv
         </v-btn>
         <v-btn v-if="canExecuteQuery" class="mb-1" :to="`/database/${$route.params.database_id}/query/create?tid=${$route.params.table_id}`" color="secondary">
-          <v-icon left>mdi-wrench</v-icon> Create Subset
+          <v-icon left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create&nbsp;</span> Subset
         </v-btn>
         <v-btn v-if="canCreateView" class="mb-1" :to="`/database/${$route.params.database_id}/view/create?tid=${$route.params.table_id}`" color="secondary">
-          <v-icon left>mdi-view-carousel</v-icon> Create View
+          <v-icon left>mdi-view-carousel</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create&nbsp;</span> View
         </v-btn>
         <v-btn v-if="canDropTable" class="mb-1" color="error" @click="dropTableDialog = true">
-          <v-icon left>mdi-delete</v-icon> Drop Table
+          <v-icon left>mdi-delete</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Drop&nbsp;</span> Table
         </v-btn>
         <v-btn v-if="canGetPid" class="mb-1" color="primary" :to="`/database/${$route.params.database_id}/table/${$route.params.table_id}/persist`">
-          <v-icon left>mdi-content-save-outline</v-icon> Get PID
+          <v-icon left>mdi-content-save-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get&nbsp;</span> PID
         </v-btn>
       </v-toolbar-title>
     </v-toolbar>
@@ -63,11 +63,11 @@
 </template>
 
 <script>
-import EditTuple from '@/components/dialogs/EditTuple'
+import EditTuple from '@/components/dialogs/EditTuple.vue'
 import TableService from '@/api/table.service'
 import UserUtils from '@/api/user.utils'
 import DatabaseUtils from '@/api/database.utils'
-import DropTable from '@/components/dialogs/DropTable'
+import DropTable from '@/components/dialogs/DropTable.vue'
 import TableUtils from '@/api/table.utils'
 
 export default {
diff --git a/dbrepo-ui/components/ViewList.vue b/dbrepo-ui/components/view/ViewList.vue
similarity index 100%
rename from dbrepo-ui/components/ViewList.vue
rename to dbrepo-ui/components/view/ViewList.vue
diff --git a/dbrepo-ui/components/view/ViewToolbar.vue b/dbrepo-ui/components/view/ViewToolbar.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f4e4efbf783f168a32a372d47a581a1caca1dc3a
--- /dev/null
+++ b/dbrepo-ui/components/view/ViewToolbar.vue
@@ -0,0 +1,125 @@
+<template>
+  <div v-if="view">
+    <v-toolbar flat>
+      <v-toolbar-title>
+        <v-btn id="back-btn" class="mr-2" :to="`/database/${$route.params.database_id}/view`">
+          <v-icon left>mdi-arrow-left</v-icon>
+        </v-btn>
+      </v-toolbar-title>
+      <v-toolbar-title v-text="title" />
+      <v-spacer />
+      <v-toolbar-title>
+        <v-btn v-if="canDeleteView" class="mb-1" :loading="loadingDelete" color="error" @click="deleteView">
+          <v-icon left>mdi-delete</v-icon> Delete
+        </v-btn>
+        <v-btn v-if="canCreatePid" class="mb-1" color="primary" :to="`/database/${$route.params.database_id}/view/${$route.params.view_id}/persist`">
+          <v-icon left>mdi-content-save-outline</v-icon> Get PID
+        </v-btn>
+      </v-toolbar-title>
+    </v-toolbar>
+    <v-tabs v-model="tab" color="primary">
+      <v-tab :to="`/database/${$route.params.database_id}/view/${$route.params.view_id}/info`">
+        Info
+      </v-tab>
+      <v-tab :to="`/database/${$route.params.database_id}/view/${$route.params.view_id}/data`">
+        Data
+      </v-tab>
+    </v-tabs>
+  </div>
+</template>
+
+<script>
+import UserUtils from '@/api/user.utils'
+import DatabaseService from '@/api/database.service'
+import IdentifierMapper from '@/api/identifier.mapper'
+
+export default {
+  components: {
+  },
+  data () {
+    return {
+      tab: null,
+      loading: false,
+      loadingDelete: false
+    }
+  },
+  computed: {
+    pid () {
+      return this.$route.query.pid
+    },
+    database () {
+      return this.$store.state.database
+    },
+    view () {
+      if (!this.database) {
+        return null
+      }
+      return this.database.views.filter(v => v.id === Number(this.$route.params.view_id))[0]
+    },
+    canDeleteView () {
+      if (!this.roles || !this.user || !this.view || !this.view.creator) {
+        return false
+      }
+      return this.roles.includes('delete-database-view') && this.view.creator.id === this.user.id
+    },
+    canCreatePid () {
+      if (!this.roles || !this.user || !this.view) {
+        return false
+      }
+      return this.roles.includes('create-identifier') && UserUtils.hasReadAccess(this.access)
+    },
+    access () {
+      return this.$store.state.access
+    },
+    user () {
+      return this.$store.state.user
+    },
+    roles () {
+      return this.$store.state.roles
+    },
+    identifiers () {
+      if (!this.view) {
+        return []
+      }
+      return this.view.identifiers.filter(s => s.view_id === Number(this.$route.params.view_id))
+    },
+    identifier () {
+      /* mount pid */
+      if (this.pid) {
+        const filter = this.identifiers.filter(i => i.id === Number(this.pid))
+        if (filter.length > 0) {
+          const identifier = filter[0]
+          console.debug('identifier set according to route pid', identifier)
+          return identifier
+        }
+      }
+      const identifier = this.identifiers[0]
+      console.debug('defaulted to latest identifier', identifier)
+      return identifier
+    },
+    title () {
+      if (!this.view) {
+        return null
+      }
+      if (!this.identifier) {
+        return this.view.name
+      }
+      return IdentifierMapper.identifierPreferEnglishTitle(this.identifier)
+    }
+  },
+  methods: {
+    deleteView () {
+      this.loadingDelete = true
+      DatabaseService.deleteView(this.$route.params.database_id, this.$route.params.view_id)
+        .then(async () => {
+          this.$toast.success('Successfully deleted view!')
+          await this.$store.dispatch('reloadDatabase')
+          await this.$router.push(`/database/${this.$route.params.database_id}/view`)
+        })
+        .finally(() => {
+          this.loadingDelete = false
+        })
+    }
+  }
+}
+</script>
diff --git a/dbrepo-ui/dbrepo.config.json b/dbrepo-ui/dbrepo.config.json
index bebad3e73d7f86e968a2a85f3daaee517955a738..ceebfb9792f18c038f610e391947b38568f37473 100644
--- a/dbrepo-ui/dbrepo.config.json
+++ b/dbrepo-ui/dbrepo.config.json
@@ -82,12 +82,12 @@
         {
           "text": "Release Notes",
           "blank": true,
-          "href": "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/blob/dev/CHANGELOG.md"
+          "href": "https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/blob/master/CHANGELOG.md"
         },
         {
           "text": "Online Documentation",
           "blank": true,
-          "href": "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/latest/"
+          "href": "https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.4/"
         },
         {
           "text": "Sourcecode Documentation",
@@ -105,9 +105,9 @@
           "href": "https://test.dbrepo.tuwien.ac.at/"
         },
         {
-          "text": "Demo Instance (Docker Compose)",
+          "text": "Pilot Instance (Docker Compose)",
           "blank": true,
-          "href": "https://dbrepo2.ec.tuwien.ac.at/"
+          "href": "https://dbrepo1.ec.tuwien.ac.at/"
         },
         {
           "text": "Paper",
diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue
index d52ff87dd60acced367f8749b2c8c7be076979e0..533bb01c5eb64bb213354e13fdde6d5a9ed0ab7e 100644
--- a/dbrepo-ui/layouts/default.vue
+++ b/dbrepo-ui/layouts/default.vue
@@ -132,8 +132,6 @@
 <script>
 import DatabaseService from '@/api/database.service'
 import TableService from '@/api/table.service'
-import AuthenticationService from '@/api/authentication.service'
-import AuthenticationMapper from '@/api/authentication.mapper'
 import DatabaseMapper from '@/api/database.mapper'
 import IdentifierMapper from '@/api/identifier.mapper'
 
@@ -227,7 +225,6 @@ export default {
   },
   mounted () {
     this.initEnvironment()
-    this.attemptRefreshToken()
     this.$store.dispatch('reloadMessages')
     this.$store.dispatch('reloadOntologies')
     if (this.$route.query && this.$route.query.q) {
@@ -313,17 +310,6 @@ export default {
       if (this.locale) {
         this.$i18n.locale = this.locale
       }
-    },
-    attemptRefreshToken () {
-      if (!this.$store.state.token || !this.$store.state.refreshToken) {
-        return
-      }
-      if (AuthenticationMapper.isExpiredToken(this.$store.state.refreshToken)) {
-        console.error('Refresh token is expired: trigger logout of user')
-        this.$store.dispatch('logout')
-      } else {
-        AuthenticationService.refreshToken()
-      }
     }
   },
   head () {
diff --git a/dbrepo-ui/package.json b/dbrepo-ui/package.json
index 04b7cc1b28731a8667a8daaa31a277f62f48e1d3..3c3f9616b97fea7de5fb27729480f8e6f3397dbc 100644
--- a/dbrepo-ui/package.json
+++ b/dbrepo-ui/package.json
@@ -41,7 +41,7 @@
     "jwt-decode": "^3.1.2",
     "knex": "^0.95.6",
     "lodash": "^4.17.21",
-    "moment": "^2.29.1",
+    "moment": "^2.30.1",
     "multer": "^1.4.2",
     "node-fetch": "^2.6.1",
     "nuxt": "^2.15.8",
diff --git a/dbrepo-ui/pages/database/_database_id/admin.vue b/dbrepo-ui/pages/database/_database_id/admin.vue
index 2ed10ade81a25c2b34882aa6c8a7ae146e4e5a5e..6087219f5bc828480a11a117e6855f5bb846d512 100644
--- a/dbrepo-ui/pages/database/_database_id/admin.vue
+++ b/dbrepo-ui/pages/database/_database_id/admin.vue
@@ -37,7 +37,7 @@
 </template>
 
 <script>
-import DatabaseToolbar from '@/components/DatabaseToolbar.vue'
+import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue'
 import DatabaseService from '@/api/database.service'
 
 export default {
diff --git a/dbrepo-ui/pages/database/_database_id/info.vue b/dbrepo-ui/pages/database/_database_id/info.vue
index 299c55470ee8a6918e3a68a3b9559ec656d64ec4..284395ed0e7e5aa39bdec7363ee80b16ba085c97 100644
--- a/dbrepo-ui/pages/database/_database_id/info.vue
+++ b/dbrepo-ui/pages/database/_database_id/info.vue
@@ -19,19 +19,20 @@
                   <v-list-item-title>
                     Database Visibility
                   </v-list-item-title>
-                  <v-list-item-content v-if="!loading" v-text="`${database.is_public ? 'Public' : 'Private'}`" />
+                  <v-list-item-content v-if="database" v-text="`${database.is_public ? 'Public' : 'Private'}`" />
+                  <v-list-item-title class="mt-2">
+                    Database Name
+                  </v-list-item-title>
+                  <v-list-item-content v-if="database" v-text="database.name" />
                   <v-list-item-title class="mt-2">
                     Database Internal Name
                   </v-list-item-title>
-                  <v-list-item-content v-if="!loading" v-text="internal_name" />
+                  <v-list-item-content v-if="database" v-text="database.internal_name" />
                   <v-list-item-title class="mt-2">
                     Database Owner
                   </v-list-item-title>
-                  <v-list-item-content v-if="!loading">
-                    <p class="mb-0">
-                      <OrcidIcon v-if="database.owner.attributes.orcid" :orcid="database.owner.attributes.orcid" />
-                      <span v-text="owner" />
-                    </p>
+                  <v-list-item-content>
+                    <UserBadge v-if="database" :user="database.owner" :other-user="user" />
                   </v-list-item-content>
                   <v-list-item-title class="mt-2">
                     Database Creation
@@ -57,11 +58,8 @@
                   <v-list-item-title v-if="contact" class="mt-2">
                     Database Contact
                   </v-list-item-title>
-                  <v-list-item-content v-if="contact">
-                    <p class="mb-0">
-                      <OrcidIcon v-if="database.contact.attributes.orcid" :orcid="database.contact.attributes.orcid" />
-                      <span v-text="contact" />
-                    </p>
+                  <v-list-item-content>
+                    <UserBadge v-if="database.contact" :user="database.contact" :other-user="user" />
                   </v-list-item-content>
                 </v-list-item-content>
               </v-list-item>
@@ -103,19 +101,19 @@
 </template>
 
 <script>
-import DatabaseToolbar from '@/components/DatabaseToolbar'
+import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue'
 import { formatTimestampUTCLabel } from '@/utils'
 import DatabaseMapper from '@/api/database.mapper'
 import Summary from '@/components/identifier/Summary'
 import Select from '@/components/identifier/Select'
-import OrcidIcon from '@/components/icons/OrcidIcon.vue'
+import UserBadge from '@/components/UserBadge.vue'
 
 export default {
   components: {
-    OrcidIcon,
     DatabaseToolbar,
     Summary,
-    Select
+    Select,
+    UserBadge
   },
   data () {
     return {
diff --git a/dbrepo-ui/pages/database/_database_id/query/_query_id/data.vue b/dbrepo-ui/pages/database/_database_id/query/_query_id/data.vue
index edcfa2bca50dd1f333047a08eafefa590dd341fd..9e1f8e3c5da3e88b8f6f11f951f8fd2020d8a828 100644
--- a/dbrepo-ui/pages/database/_database_id/query/_query_id/data.vue
+++ b/dbrepo-ui/pages/database/_database_id/query/_query_id/data.vue
@@ -20,11 +20,13 @@
 
 <script>
 import QueryResults from '@/components/query/Results'
+import SubsetToolbar from '@/components/query/SubsetToolbar'
 import QueryService from '@/api/query.service'
 import { formatTimestampUTCLabel } from '@/utils'
 
 export default {
   components: {
+    SubsetToolbar,
     QueryResults
   },
   data () {
diff --git a/dbrepo-ui/pages/database/_database_id/query/_query_id/info.vue b/dbrepo-ui/pages/database/_database_id/query/_query_id/info.vue
index 18554f07a6d70bfc79e7e01bae72529731c8a162..69ab9fe5e6ce6df3881898bcc7a07b252bd2e52e 100644
--- a/dbrepo-ui/pages/database/_database_id/query/_query_id/info.vue
+++ b/dbrepo-ui/pages/database/_database_id/query/_query_id/info.vue
@@ -14,40 +14,53 @@
         <v-list dense>
           <v-list-item>
             <v-list-item-content>
+              <v-list-item-title>
+                Subset Visibility
+              </v-list-item-title>
+              <v-list-item-content>
+                <v-skeleton-loader v-if="!database" type="text" class="skeleton-small" />
+                <span v-if="database" v-text="database.is_public ? 'Public' : 'Private'" />
+              </v-list-item-content>
+              <v-list-item-title>
+                Subset Creator
+              </v-list-item-title>
+              <v-list-item-content>
+                <v-skeleton-loader v-if="!subset" type="text" class="skeleton-small" />
+                <UserBadge v-if="subset" :user="subset.creator" :other-user="user" />
+              </v-list-item-content>
               <v-list-item-title>
                 Subset Query
               </v-list-item-title>
               <v-list-item-content>
-                <pre>{{ subset.query }}</pre>
+                <v-skeleton-loader v-if="!subset" type="text" />
+                <pre v-if="subset">{{ subset.query }}</pre>
               </v-list-item-content>
               <v-list-item-title class="mt-2">
                 Subset Query Hash
               </v-list-item-title>
               <v-list-item-content>
-                <pre>sha256:{{ subset.query_hash }}</pre>
+                <v-skeleton-loader v-if="!subset" type="text" />
+                <pre v-if="subset">sha256:{{ subset.query_hash }}</pre>
               </v-list-item-content>
               <v-list-item-title class="mt-2">
                 Subset Creation
               </v-list-item-title>
               <v-list-item-content>
+                <v-skeleton-loader v-if="!executionUTC" type="text" class="skeleton-small" />
                 <span v-if="executionUTC">{{ executionUTC }}</span>
               </v-list-item-content>
-              <v-list-item-title>
-                Subset Visibility
-              </v-list-item-title>
-              <v-list-item-content>
-                {{ database.is_public ? 'Public' : 'Private' }}
-              </v-list-item-content>
               <v-list-item-title class="mt-2">
                 Subset Hash
               </v-list-item-title>
               <v-list-item-content>
+                <v-skeleton-loader v-if="!subset" type="text" />
                 <pre v-if="subset">{{ result_hash }}</pre>
               </v-list-item-content>
               <v-list-item-title class="mt-2">
                 Subset Count
               </v-list-item-title>
               <v-list-item-content>
+                <v-skeleton-loader v-if="!subset" type="text" class="skeleton-xsmall" />
                 <span v-if="subset">{{ subset.result_number }}</span>
               </v-list-item-content>
             </v-list-item-content>
@@ -84,17 +97,20 @@
 </template>
 <script>
 import Summary from '@/components/identifier/Summary'
-import SubsetToolbar from '@/components/SubsetToolbar'
+import SubsetToolbar from '@/components/query/SubsetToolbar.vue'
 import QueryService from '@/api/query.service'
 import Select from '@/components/identifier/Select'
 import { formatTimestampUTCLabel } from '@/utils'
+import UserMapper from '@/api/user.mapper'
+import UserBadge from '@/components/UserBadge.vue'
 
 export default {
   name: 'QueryShow',
   components: {
     Select,
     Summary,
-    SubsetToolbar
+    SubsetToolbar,
+    UserBadge
   },
   data () {
     return {
@@ -112,10 +128,7 @@ export default {
       downloadLoading: false,
       error: false,
       promises: [],
-      subset: {
-        query: null,
-        query_hash: null
-      }
+      subset: null
     }
   },
   computed: {
@@ -135,7 +148,7 @@ export default {
       if (!this.database || !this.database.subsets || this.database.subsets.length === 0) {
         return []
       }
-      return this.database.subsets
+      return this.database.subsets.filter(s => s.query_id === Number(this.$route.params.query_id))
     },
     hasIdentifier () {
       return this.identifiers.length > 0
@@ -194,6 +207,15 @@ export default {
         .finally(() => {
           this.loadingSubset = false
         })
+    },
+    isCreator (subset) {
+      if (!this.user) {
+        return false
+      }
+      return subset.creator.id === this.user.id
+    },
+    formatCreator (creator) {
+      return UserMapper.userToFullName(creator)
     }
   }
 }
diff --git a/dbrepo-ui/pages/database/_database_id/query/index.vue b/dbrepo-ui/pages/database/_database_id/query/index.vue
index 936eecf58b973c8e5476bc2ce772459cf234614b..d8222f23f9f9beeb4c86f1a310a3fefc3e50a4e2 100644
--- a/dbrepo-ui/pages/database/_database_id/query/index.vue
+++ b/dbrepo-ui/pages/database/_database_id/query/index.vue
@@ -1,16 +1,16 @@
 <template>
   <div>
     <DatabaseToolbar v-model="db" />
-    <QueryList />
+    <SubsetList />
     <v-breadcrumbs :items="items" class="pa-0 mt-2" />
   </div>
 </template>
 
 <script>
-import QueryList from '@/components/QueryList.vue'
+import SubsetList from '@/components/query/SubsetList.vue'
 export default {
   components: {
-    QueryList
+    SubsetList
   },
   data () {
     return {
diff --git a/dbrepo-ui/pages/database/_database_id/settings.vue b/dbrepo-ui/pages/database/_database_id/settings.vue
index ad47064ab66fda4ca9cd0e5b8bf1c9ccc2520dbc..8734d197c9ed18bad2e77ed70983ec36ae994136 100644
--- a/dbrepo-ui/pages/database/_database_id/settings.vue
+++ b/dbrepo-ui/pages/database/_database_id/settings.vue
@@ -96,7 +96,7 @@
 </template>
 
 <script>
-import DatabaseToolbar from '@/components/DatabaseToolbar.vue'
+import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue'
 import EditAccess from '@/components/dialogs/EditAccess.vue'
 import DatabaseService from '@/api/database.service'
 import UserService from '@/api/user.service'
diff --git a/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue b/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue
index d56052f6242db342b7819780aa75456272dc61f6..c663a38827699e4d6bb262d9e4db8979ae6e2298 100644
--- a/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue
@@ -50,7 +50,7 @@
 </template>
 <script>
 import TimeTravel from '@/components/dialogs/TimeTravel.vue'
-import TableToolbar from '@/components/TableToolbar.vue'
+import TableToolbar from '@/components/table/TableToolbar.vue'
 import TableService from '@/api/table.service'
 import { formatTimestampUTC, formatDateUTC, formatTimestamp, formatBinaryStream } from '@/utils'
 
@@ -66,7 +66,8 @@ export default {
       editTupleDialog: false,
       total: -1,
       footerProps: {
-        'items-per-page-options': [10, 20, 30, 40, 50]
+        showFirstLastPage: true,
+        itemsPerPageOptions: [10, 25, 50, 100]
       },
       downloadLoading: false,
       dateMenu: false,
diff --git a/dbrepo-ui/pages/database/_database_id/table/_table_id/info.vue b/dbrepo-ui/pages/database/_database_id/table/_table_id/info.vue
index 18a42daa7e3ed301640e1d8f0c17c9a9c34d161c..d4b0620414afd29196250e01d1c8b150fa1b7b67 100644
--- a/dbrepo-ui/pages/database/_database_id/table/_table_id/info.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/_table_id/info.vue
@@ -28,7 +28,8 @@
                 Table Owner
               </v-list-item-title>
               <v-list-item-content>
-                <span v-if="table && table.creator">{{ formatCreator(table.owner) }} <span v-if="is_owner(table)" style="flex:none;">&nbsp;(you)</span></span>
+                <v-skeleton-loader v-if="!table" type="text" class="skeleton-small" />
+                <UserBadge v-if="table" :user="table.creator" :other-user="user" />
               </v-list-item-content>
               <v-list-item-title v-if="table && table.created" class="mt-2">
                 Table Creation
@@ -105,17 +106,18 @@
   </div>
 </template>
 <script>
-import TableToolbar from '@/components/TableToolbar'
-import UserMapper from '@/api/user.mapper'
+import TableToolbar from '@/components/table/TableToolbar.vue'
 import Select from '@/components/identifier/Select'
 import Summary from '@/components/identifier/Summary'
 import { formatTimestampUTCLabel } from '@/utils'
+import UserBadge from '@/components/UserBadge.vue'
 
 export default {
   components: {
     Summary,
     Select,
-    TableToolbar
+    TableToolbar,
+    UserBadge
   },
   data () {
     return {
@@ -226,15 +228,6 @@ export default {
     }
   },
   methods: {
-    formatCreator (creator) {
-      return UserMapper.userToFullName(creator)
-    },
-    is_owner (table) {
-      if (!this.user) {
-        return false
-      }
-      return table.owner.id === this.user.id
-    },
     amqpBadgeText (port) {
       if (port === 5672) {
         return 'insecure'
@@ -264,4 +257,16 @@ export default {
 .v-card__text {
   font-size: initial;
 }
+.skeleton-large > div {
+  width: 400px !important;
+}
+.skeleton-medium > div {
+  width: 200px !important;
+}
+.skeleton-small > div {
+  width: 100px !important;
+}
+.skeleton-xsmall > div {
+  width: 50px !important;
+}
 </style>
diff --git a/dbrepo-ui/pages/database/_database_id/table/_table_id/schema.vue b/dbrepo-ui/pages/database/_database_id/table/_table_id/schema.vue
index 51135aeaa4ac49151bacfaa771dc1b32bfc4e74a..ccddb4a1d8cf971268ad1d8b4c2da547ec7a110d 100644
--- a/dbrepo-ui/pages/database/_database_id/table/_table_id/schema.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/_table_id/schema.vue
@@ -80,7 +80,7 @@
   </div>
 </template>
 <script>
-import TableToolbar from '@/components/TableToolbar.vue'
+import TableToolbar from '@/components/table/TableToolbar.vue'
 import TableService from '@/api/table.service'
 
 export default {
diff --git a/dbrepo-ui/pages/database/_database_id/table/create.vue b/dbrepo-ui/pages/database/_database_id/table/create.vue
index 6b2da528ad33bf5818c6b7b000da13ea35482a62..b71ed9e01bd896ec9e55e6717d4700e18fa389b2 100644
--- a/dbrepo-ui/pages/database/_database_id/table/create.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/create.vue
@@ -56,7 +56,7 @@
 </template>
 
 <script>
-import TableSchema from '@/components/TableSchema.vue'
+import TableSchema from '@/components/table/TableSchema.vue'
 import { notEmpty } from '@/utils'
 import TableService from '@/api/table.service'
 import TableMapper from '@/api/table.mapper'
diff --git a/dbrepo-ui/pages/database/_database_id/table/import.vue b/dbrepo-ui/pages/database/_database_id/table/import.vue
index fe4c47bdb1614cc56effd63f21e538e53d1a15a1..adc353bedae47e6e407a04acef396e74cc3db710 100644
--- a/dbrepo-ui/pages/database/_database_id/table/import.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/import.vue
@@ -203,7 +203,7 @@
 </template>
 <script>
 import { notEmpty, isNonNegativeInteger } from '@/utils'
-import TableSchema from '@/components/TableSchema.vue'
+import TableSchema from '@/components/table/TableSchema.vue'
 import TableService from '@/api/table.service'
 import AnalyseService from '@/api/analyse.service'
 import DatabaseService from '@/api/database.service'
diff --git a/dbrepo-ui/pages/database/_database_id/table/index.vue b/dbrepo-ui/pages/database/_database_id/table/index.vue
index 0aca945e2f8d7047d866a3fae5f6b87d45d80b9d..61cc58d23a2704f50443eb2832c6275b4dc33641 100644
--- a/dbrepo-ui/pages/database/_database_id/table/index.vue
+++ b/dbrepo-ui/pages/database/_database_id/table/index.vue
@@ -8,8 +8,8 @@
   </div>
 </template>
 <script>
-import TableList from '@/components/TableList.vue'
-import DatabaseToolbar from '@/components/DatabaseToolbar.vue'
+import TableList from '@/components/table/TableList.vue'
+import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue'
 
 export default {
   name: 'Tables',
diff --git a/dbrepo-ui/pages/database/_database_id/view/_view_id/info.vue b/dbrepo-ui/pages/database/_database_id/view/_view_id/info.vue
index 48c8b03d861beb9ba54dbc630b2251a896948699..60b74bc0a03e69b2abc2b18c92a60b6c5ae5a676 100644
--- a/dbrepo-ui/pages/database/_database_id/view/_view_id/info.vue
+++ b/dbrepo-ui/pages/database/_database_id/view/_view_id/info.vue
@@ -20,29 +20,29 @@
                     Query Statement
                   </v-list-item-title>
                   <v-list-item-content>
-                    <v-skeleton-loader v-if="!view.query" type="text" />
-                    <v-skeleton-loader v-if="!view.query" type="text" class="skeleton-large" />
-                    <pre v-if="view.query">{{ view.query }}</pre>
+                    <v-skeleton-loader v-if="!view" type="text" class="skeleton-large" />
+                    <pre v-if="view">{{ view.query }}</pre>
                   </v-list-item-content>
-                  <v-list-item-title v-if="canViewView" class="mt-2">
+                  <v-list-item-title class="mt-2">
                     View Creator
                   </v-list-item-title>
-                  <v-list-item-content v-if="canViewView">
-                    <span v-if="creator">{{ creator }}</span>
+                  <v-list-item-content>
+                    <v-skeleton-loader v-if="!view" type="text" class="skeleton-small" />
+                    <UserBadge v-if="view" :user="view.creator" :other-user="user" />
                   </v-list-item-content>
                   <v-list-item-title class="mt-2">
                     View Creation
                   </v-list-item-title>
                   <v-list-item-content>
-                    <v-skeleton-loader v-if="!view.created" type="text" class="skeleton-medium" />
+                    <v-skeleton-loader v-if="!view" type="text" class="skeleton-medium" />
                     <span v-if="view.created">{{ formatUTC(view.created) }}</span>
                   </v-list-item-content>
                   <v-list-item-title>
                     View Visibility
                   </v-list-item-title>
                   <v-list-item-content>
-                    <v-skeleton-loader v-if="view.is_public === null" type="text" class="skeleton-xsmall" />
-                    <span v-if="view.is_public !== null">{{ view.is_public ? 'Public' : 'Private' }}</span>
+                    <v-skeleton-loader v-if="!view" type="text" class="skeleton-xsmall" />
+                    <span v-if="view" v-text="view.is_public ? 'Public' : 'Private'" />
                   </v-list-item-content>
                 </v-list-item-content>
               </v-list-item>
@@ -83,17 +83,18 @@
 </template>
 <script>
 import { formatTimestampUTCLabel } from '@/utils'
-import ViewToolbar from '@/components/ViewToolbar.vue'
+import ViewToolbar from '@/components/view/ViewToolbar.vue'
 import UserMapper from '@/api/user.mapper'
-import UserUtils from '@/api/user.utils'
 import Summary from '@/components/identifier/Summary.vue'
 import Select from '@/components/identifier/Select.vue'
+import UserBadge from '@/components/UserBadge.vue'
 
 export default {
   components: {
     Select,
     Summary,
-    ViewToolbar
+    ViewToolbar,
+    UserBadge
   },
   data () {
     return {
@@ -151,10 +152,6 @@ export default {
     pid () {
       return this.$route.query.pid
     },
-    canViewView () {
-      /* is private */
-      return UserUtils.hasReadAccess(this.access)
-    },
     hasIdentifier () {
       return this.identifiers.length > 0
     },
@@ -162,6 +159,7 @@ export default {
       if (!this.view) {
         return null
       }
+      console.debug('====>', this.view)
       return UserMapper.userToFullName(this.view.creator)
     }
   },
@@ -189,4 +187,16 @@ pre {
 #back-btn::before {
   opacity: 0;
 }
+.skeleton-large > div {
+  width: 400px !important;
+}
+.skeleton-medium > div {
+  width: 200px !important;
+}
+.skeleton-small > div {
+  width: 100px !important;
+}
+.skeleton-xsmall > div {
+  width: 50px !important;
+}
 </style>
diff --git a/dbrepo-ui/pages/database/_database_id/view/index.vue b/dbrepo-ui/pages/database/_database_id/view/index.vue
index 86e2e37566d79503e2b62b69822d0674584b800e..cc932e4b6513845719ea27bdaae6e96bb4823c47 100644
--- a/dbrepo-ui/pages/database/_database_id/view/index.vue
+++ b/dbrepo-ui/pages/database/_database_id/view/index.vue
@@ -8,8 +8,8 @@
   </div>
 </template>
 <script>
-import DatabaseToolbar from '@/components/DatabaseToolbar.vue'
-import ViewList from '@/components/ViewList.vue'
+import DatabaseToolbar from '@/components/database/DatabaseToolbar.vue'
+import ViewList from '@/components/view/ViewList.vue'
 
 export default {
   name: 'Views',
diff --git a/dbrepo-ui/pages/index.vue b/dbrepo-ui/pages/index.vue
index 4ef1ceba380b90c5012d374fc262c8a2a4a657a8..9776777fc3b38b5a90e786c2f655cade4057f7db 100644
--- a/dbrepo-ui/pages/index.vue
+++ b/dbrepo-ui/pages/index.vue
@@ -24,7 +24,7 @@
         </div>
       </v-card-text>
     </v-card>
-    <DatabaseList ref="databases" :databases="databases" />
+    <DatabaseList ref="databases" :loading="loadingDatabases" :databases="databases" />
     <v-dialog
       v-model="createDbDialog"
       persistent
@@ -35,7 +35,7 @@
 </template>
 
 <script>
-import DatabaseList from '@/components/DatabaseList'
+import DatabaseList from '@/components/database/DatabaseList.vue'
 import CreateDB from '@/components/dialogs/CreateDB'
 import DatabaseService from '@/api/database.service'
 
@@ -47,6 +47,7 @@ export default {
   data () {
     return {
       loading: false,
+      loadingDatabases: false,
       createDbDialog: null,
       databases: []
     }
diff --git a/dbrepo-ui/pages/search/index.vue b/dbrepo-ui/pages/search/index.vue
index 266cd6ce57e8eb570d473916011cf5d7b88591dd..696bbe6d0515b6afcd31b2fb151cddcb1b3ce15f 100644
--- a/dbrepo-ui/pages/search/index.vue
+++ b/dbrepo-ui/pages/search/index.vue
@@ -1,7 +1,10 @@
 <template>
   <div>
     <v-toolbar flat tile>
-      <v-toolbar-title v-text="header" />
+      <v-toolbar-title>
+        <v-skeleton-loader v-if="loading || !header" type="text" class="skeleton-small" />
+        <span v-if="!loading && header" v-text="header" />
+      </v-toolbar-title>
       <v-spacer />
       <v-toolbar-title>
         <v-btn v-if="canCreateDatabase" color="primary" name="create-database" @click.stop="createDbDialog = true">
@@ -12,7 +15,7 @@
     <v-card flat tile>
       <AdvancedSearch ref="adv" @search-result="onSearchResult" />
     </v-card>
-    <DatabaseList v-if="isDatabaseSearch" :databases="results.results" />
+    <DatabaseList v-if="isDatabaseSearch" :loading="loading" :databases="results.results" />
     <div v-else>
       <v-card
         v-for="(result, idx) in results.results"
@@ -82,7 +85,7 @@ export default {
     },
     header () {
       if (!this.results || !this.results.results) {
-        return '0 results'
+        return null
       }
       if (this.results.results.length !== 1) {
         return `${this.results.results.length} results`
@@ -120,11 +123,9 @@ export default {
       SearchService.search(null, { search_term: this.query })
         .then((response) => {
           this.results = response
-        })
-        .catch(() => {
           this.loading = false
         })
-        .finally(() => {
+        .catch(() => {
           this.loading = false
         })
     },
@@ -132,6 +133,9 @@ export default {
       if (!item) {
         return false
       }
+      if ('exchange_name' in item) {
+        return true
+      }
       return this.results.type === 'database'
     },
     isConcept (item) {
diff --git a/dbrepo-ui/pages/user/developer.vue b/dbrepo-ui/pages/user/developer.vue
index 7825e5624307bd69ddea0c086d411adf3afd5e22..2d14d40011a3f68fa1d98e2790c9e6854fe82469 100644
--- a/dbrepo-ui/pages/user/developer.vue
+++ b/dbrepo-ui/pages/user/developer.vue
@@ -1,9 +1,9 @@
 <template>
-  <div v-if="canHandleMessages">
+  <div>
     <UserToolbar />
     <v-tabs-items v-model="tab">
       <v-tab-item>
-        <v-card flat tile>
+        <v-card v-if="canHandleMessages" flat tile>
           <v-card-title>Maintenance Messages</v-card-title>
           <v-data-table
             :headers="headers"
@@ -28,6 +28,40 @@
             </v-btn>
           </v-card-text>
         </v-card>
+        <v-divider v-if="canHandleMessages" />
+        <v-card flat tile>
+          <v-card-title>Token Information</v-card-title>
+          <v-card-text>
+            <v-row dense>
+              <v-col xl="4">
+                <v-text-field
+                  v-model="token"
+                  disabled
+                  label="Access Token" />
+              </v-col>
+              <v-col xl="2">
+                <v-text-field
+                  v-model="tokenExpiry"
+                  disabled
+                  :label="tokenExpiryLabel" />
+              </v-col>
+            </v-row>
+            <v-row dense>
+              <v-col xl="4">
+                <v-text-field
+                  v-model="refreshToken"
+                  disabled
+                  label="Refresh Token" />
+              </v-col>
+              <v-col xl="2">
+                <v-text-field
+                  v-model="refreshTokenExpiry"
+                  disabled
+                  :label="refreshTokenExpiryLabel" />
+              </v-col>
+            </v-row>
+          </v-card-text>
+        </v-card>
       </v-tab-item>
     </v-tabs-items>
     <v-dialog
@@ -43,7 +77,8 @@
 import UserToolbar from '@/components/UserToolbar'
 import MetadataService from '@/api/metadata.service'
 import EditMaintenanceMessage from '@/components/dialogs/EditMaintenanceMessage'
-import { isActiveMessage } from '@/utils'
+import { formatTimestampUTCLabel, isActiveMessage, timestampsToHumanDifference } from '@/utils'
+import AuthenticationMapper from '@/api/authentication.mapper'
 
 export default {
   components: {
@@ -69,6 +104,33 @@ export default {
     token () {
       return this.$store.state.token
     },
+    tokenExpiry () {
+      if (!this.token) {
+        return null
+      }
+      return formatTimestampUTCLabel(AuthenticationMapper.tokenToExpiryDate(this.token))
+    },
+    tokenExpiryLabel () {
+      if (!this.token) {
+        return 'Expiry Date'
+      }
+      return `Expiry Date (${timestampsToHumanDifference(Date.now(), AuthenticationMapper.tokenToExpiryDate(this.token))})`
+    },
+    refreshToken () {
+      return this.$store.state.refreshToken
+    },
+    refreshTokenExpiry () {
+      if (!this.refreshToken) {
+        return null
+      }
+      return formatTimestampUTCLabel(AuthenticationMapper.tokenToExpiryDate(this.refreshToken))
+    },
+    refreshTokenExpiryLabel () {
+      if (!this.refreshToken) {
+        return 'Expiry Date'
+      }
+      return `Expiry Date (${timestampsToHumanDifference(Date.now(), AuthenticationMapper.tokenToExpiryDate(this.refreshToken))})`
+    },
     user () {
       return this.$store.state.user
     },
diff --git a/dbrepo-ui/plugins/axios.js b/dbrepo-ui/plugins/axios.js
index aca6db132348c8d56175ac9dab9623ec4c8186fa..6405d7bd358b87fa9be5ae83502126945d007e8a 100644
--- a/dbrepo-ui/plugins/axios.js
+++ b/dbrepo-ui/plugins/axios.js
@@ -2,15 +2,46 @@ import Vue from 'vue'
 import store from '@/store'
 import api from '@/api'
 import VueAxios from 'vue-axios'
+import AuthenticationMapper from '@/api/authentication.mapper'
+import AuthenticationService from '@/api/authentication.service'
 
-api.interceptors.request.use((config) => {
-  const token = store().state.token
-  if (!token) {
-    return config
-  }
-  console.debug('interceptor inject authorization header for url', config.url)
-  config.headers.Authorization = `Bearer ${store().state.token}`
-  return config
-})
+/**
+ * Attempts to refresh the access token with the refresh token (if not expired).
+ * Success: stores the new access-refresh token pair in the store.
+ * Error: deletes the access-refresh token pair in the store.
+ * https://stackoverflow.com/questions/44985708/axios-request-interceptor-wait-until-ajax-call-finishes
+ */
+api.interceptors.request.use(config =>
+  new Promise((resolve, reject) => {
+    const token = store().state.token
+    const refreshToken = store().state.refreshToken
+    if (!store().state.token || !refreshToken) {
+      resolve(config)
+    } else if (AuthenticationMapper.isExpiredToken(token)) {
+      if (AuthenticationMapper.isExpiredToken(refreshToken)) {
+        console.warn('Refresh token is expired: trigger logout of user')
+        store().dispatch('logout')
+        resolve(config)
+      }
+      AuthenticationService.authenticateToken(refreshToken)
+        .then((response) => {
+          store().commit('SET_TOKEN', response.access_token)
+          store().commit('SET_REFRESH_TOKEN', response.refresh_token)
+          console.debug('new access token expires:', AuthenticationMapper.tokenToExpiryDate(response.access_token))
+          config.headers.Authorization = `Bearer ${response.access_token}`
+          resolve(config)
+        })
+        .catch((error) => {
+          if (error.response.data.error === 'invalid_grant') {
+            store().dispatch('logout')
+          }
+          reject(error)
+        })
+    } else {
+      config.headers.Authorization = `Bearer ${store().state.token}`
+      resolve(config)
+    }
+  })
+)
 
 Vue.use(VueAxios, api)
diff --git a/dbrepo-ui/utils/index.js b/dbrepo-ui/utils/index.js
index fbfb4a19c534c45976dae3e22a4ed65acd118e94..3e08f463448d549aa1ab6d455fa3c3b8046557e8 100644
--- a/dbrepo-ui/utils/index.js
+++ b/dbrepo-ui/utils/index.js
@@ -1,4 +1,5 @@
 const { format } = require('date-fns')
+const moment = require('moment')
 
 function notEmpty (str) {
   return typeof str === 'string' && str.trim().length > 0
@@ -1013,22 +1014,6 @@ function formatLanguage (code) {
   return filter[0].name
 }
 
-function isOrcid (orcid) {
-  if (!orcid || orcid.startsWith('http')) {
-    return false
-  }
-  const input = orcid.replace('-', '')
-  let total = 0
-  for (let i = 0; i < input.length; i++) {
-    const digit = Number(input.charAt(i))
-    total = (total + digit) * 2
-  }
-  const remainder = total % 11
-  const result = (12 - remainder) % 11
-  const checksum = result === 10 ? 'X' : String(result)
-  return orcid.charAt(orcid.length - 1) === checksum
-}
-
 function isActiveMessage (message) {
   if (!message) {
     return false
@@ -1055,6 +1040,12 @@ function timestampToTimeZonedTimestamp (str) {
   return format(new Date(str), 'yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'')
 }
 
+function timestampsToHumanDifference (date1, date2) {
+  const date = moment(date1)
+  const other = moment(date2)
+  return moment.duration(other.diff(date)).humanize(true)
+}
+
 module.exports = {
   notEmpty,
   formatTimestamp,
@@ -1065,10 +1056,10 @@ module.exports = {
   formatYearUTC,
   formatMonthUTC,
   formatDayUTC,
-  isOrcid,
   isActiveMessage,
   timestampToTimeZonedTimestamp,
   formatBinaryStream,
   languages,
-  formatLanguage
+  formatLanguage,
+  timestampsToHumanDifference
 }
diff --git a/dbrepo-ui/yarn.lock b/dbrepo-ui/yarn.lock
index d5a3920df7018fd57ec7b47837ff13f92cd42e7f..75274723ac8a0e6cef84b8198c89930765f5a6f0 100644
--- a/dbrepo-ui/yarn.lock
+++ b/dbrepo-ui/yarn.lock
@@ -9491,10 +9491,10 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
-moment@^2.29.1:
-  version "2.29.4"
-  resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
-  integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
+moment@^2.30.1:
+  version "2.30.1"
+  resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
+  integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
 
 move-concurrently@^1.0.1:
   version "1.0.1"
@@ -11432,11 +11432,6 @@ querystring-es3@^0.2.0:
   resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
   integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==
 
-querystring@0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-  integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==
-
 querystringify@^2.1.1:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 524e3bb1b68fb92b4327e08774b694325f921cd4..89aeb123ed135b7e1ce50743f4562941856dda44 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -1,7 +1,3 @@
-# INFO: This compose file deploys the official Docker images from a stable, tested master branch
-# MODIFIED: 2024-01-07
-# MAINTAINER: Martin Weise <martin.weise@tuwien.ac.at>
-
 version: "3.6"
 
 volumes:
@@ -18,7 +14,7 @@ services:
     restart: "no"
     container_name: dbrepo-metadata-db
     hostname: metadata-db
-    image: docker.io/dbrepo/metadata-db:1.4
+    image: docker.io/dbrepo/metadata-db:latest
     volumes:
       - metadata-db-data:/bitnami/mariadb
       - ./dist/setup-schema_local.sql:/docker-entrypoint-initdb.d/setup-schema_local.sql
@@ -80,7 +76,7 @@ services:
     restart: "no"
     container_name: dbrepo-authentication-service
     hostname: authentication-service
-    image: docker.io/dbrepo/authentication-service:1.4
+    image: docker.io/dbrepo/authentication-service:latest
     ports:
       - "8443:8443"
       - "8080:8080"
@@ -105,7 +101,7 @@ services:
     restart: "no"
     container_name: dbrepo-metadata-service
     hostname: metadata-service
-    image: docker.io/dbrepo/metadata-service:1.4
+    image: docker.io/dbrepo/metadata-service:latest
     volumes:
       - "${SHARED_FILESYSTEM:-/tmp}:/tmp"
     ports:
@@ -178,7 +174,7 @@ services:
     restart: "no"
     container_name: dbrepo-analyse-service
     hostname: analyse-service
-    image: docker.io/dbrepo/analyse-service:1.4
+    image: docker.io/dbrepo/analyse-service:latest
     ports:
       - "5000:5000"
     environment:
@@ -222,7 +218,7 @@ services:
     restart: "no"
     container_name: dbrepo-search-db
     hostname: search-db
-    image: docker.io/dbrepo/search-db:1.4
+    image: docker.io/dbrepo/search-db:latest
     ports:
       - "9200:9200"
     healthcheck:
@@ -246,7 +242,7 @@ services:
     restart: "no"
     container_name: dbrepo-search-service
     hostname: search-service
-    image: docker.io/dbrepo/search-service:1.4
+    image: docker.io/dbrepo/search-service:latest
     ports:
       - "4000:4000"
     environment:
@@ -258,7 +254,7 @@ services:
     restart: "no"
     container_name: dbrepo-data-db-sidecar
     hostname: data-db-sidecar
-    image: docker.io/dbrepo/data-db-sidecar:1.4
+    image: docker.io/dbrepo/data-db-sidecar:latest
     ports:
       - "3305:3305"
     environment:
@@ -278,7 +274,7 @@ services:
     restart: "no"
     container_name: dbrepo-ui
     hostname: ui
-    image: docker.io/dbrepo/ui:1.4
+    image: docker.io/dbrepo/ui:latest
     volumes:
       - ./dist/dbrepo.config.json:/app/dbrepo.config.json
     depends_on:
@@ -334,7 +330,7 @@ services:
     restart: "no"
     container_name: dbrepo-search-db-init
     hostname: search-db-init
-    image: docker.io/dbrepo/search-db-init:1.4
+    image: docker.io/dbrepo/search-db-init:latest
     environment:
       OPENSEARCH_HOST: ${SEARCH_DB_HOST:-http://search-db:9200}
       CURL_EXTRA_ARGS: ${SEARCH_DB_EXTRA_ARGS:-}
@@ -367,7 +363,7 @@ services:
     restart: "no"
     container_name: dbrepo-storage-service-init
     hostname: storage-service-init
-    image: docker.io/dbrepo/storage-service-init:1.4
+    image: docker.io/dbrepo/storage-service-init:latest
     environment:
       SEAWEEDFS_ENDPOINT: "${STORAGE_SEAWEEDFS_ENDPOINT:-storage-service:9333}"
     depends_on:
@@ -406,7 +402,7 @@ services:
     restart: "no"
     container_name: dbrepo-data-service
     hostname: data-service
-    image: docker.io/dbrepo/data-service:1.4
+    image: docker.io/dbrepo/data-service:latest
     ports:
       - "9093:9093"
     environment:
diff --git a/docker-compose.yml b/docker-compose.yml
index f631f7c033ea2cc1c767dcd3762349c2476f37dd..d783a4b77f19e284f156ec33d33f23ff985555f2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,7 +1,3 @@
-# INFO: This compose file deploys the official Docker images from a stable, tested master branch
-# MODIFIED: 2024-01-07
-# MAINTAINER: Martin Weise <martin.weise@tuwien.ac.at>
-
 version: "3.6"
 
 volumes:
diff --git a/mkdocs.yml b/mkdocs.yml
index b4dfba732c38d719639ace21b964457fde77f84e..3eef0cf8c1c1a1892fa8b49f1e268badf854d363 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -15,12 +15,12 @@ nav:
       - Analyse Service: system-services-analyse.md
       - Authentication Service: system-services-authentication.md
       - Broker Service: system-services-broker.md
-      - Gateway Service: system-services-gateway.md
       - Data Service: system-services-data.md
+      - Gateway Service: system-services-gateway.md
       - Metadata Service: system-services-metadata.md
-      - Mirror Service: system-services-mirror.md
-      - Upload Service: system-services-upload.md
+      - Search Service: system-services-search.md
       - Storage Service: system-services-storage.md
+      - Upload Service: system-services-upload.md
     - Databases:
       - Auth Database: system-databases-auth.md
       - Data Database: system-databases-data.md
@@ -35,9 +35,8 @@ nav:
       - Analyse Service: usage-analyse.md
       - Authentication Service: usage-auth.md
       - Broker Service: usage-broker.md
-      - Identifier Service: usage-identifier.md
-      - Upload Service: usage-upload.md
       - Storage Service: usage-storage.md
+      - Upload Service: usage-upload.md
   - publications.md
   - contact.md
 extra_css:
@@ -80,6 +79,7 @@ theme:
   name: material
 markdown_extensions:
   - attr_list
+  - def_list
   - md_in_html
   - admonition
   - pymdownx.details