diff --git a/.github/workflows/format-action.yml b/.github/workflows/format-action.yml
index 8ab0c9dd70..e57db39e56 100644
--- a/.github/workflows/format-action.yml
+++ b/.github/workflows/format-action.yml
@@ -3,7 +3,7 @@ name: 'Format'
on: [push]
jobs:
- Frontend:
+ frontend:
runs-on: ubuntu-latest
defaults:
run:
@@ -15,33 +15,19 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
- node-version: 22.10.0
+ node-version: ${{vars.NODE_VERSION}}
- name: Npm install
run: npm ci
- name: Format frontend
- run: npm run format
+ run: npm run check
- - name: Commit and Push formated frontend
- shell: bash
- env:
- COMMITPREFIX: '[FM]'
- run: |
- git config --global user.email "actions@github.com"
- git config --global user.name "GitHub Actions"
- git add . || {
- echo "No files were changed, so we did not commit anything"
- exit 1
- }
- git commit -m "$COMMITPREFIX Automated formating frontend" || {
- echo "No changes to commit, skipping push"
- exit 0
- }
- git push -f
-
- Backend:
+ backend:
runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: backend
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -55,21 +41,4 @@ jobs:
settings-path: ${{github.workspace}}
- name: Format backend
- run: mvn formatter:format -f backend/pom.xml
-
- - name: Commit and Push formated backend
- shell: bash
- env:
- COMMITPREFIX: '[FM]'
- run: |
- git config --global user.email "actions@github.com"
- git config --global user.name "GitHub Actions"
- git add . || {
- echo "No files were changed, so we did not commit anything"
- exit 1
- }
- git commit -m "$COMMITPREFIX Automated formating backend" || {
- echo "No changes to commit, skipping push"
- exit 0
- }
- git push -f
\ No newline at end of file
+ run: mvn spotless:check
\ No newline at end of file
diff --git a/backend/README.md b/backend/README.md
index 127c7150a1..b31e5267e7 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -33,17 +33,16 @@ USING DOCKER
- backend/target
Formatting:
-- Check code formatting: `mvn formatter:validate`
-- Format the code: `mvn formatter:format`
+- Check code formatting: `mvn spotless:check`
+- Format the code: `mvn spotless:apply`
-The `compile` goal execute also a `formatter:format` goal.
+The `compile` goal execute also a `spotless:apply` goal.
Verify the Backend for coverage check:
- `mvn clean verify`
## Formatting
-We use the **formatter-maven-plugin** Plugin for formatting the Java code:
-https://code.revelc.net/formatter-maven-plugin/
-
+We use the **spotless** Plugin for formatting the Java code:
+https://github.com/diffplug/spotless
## Build
_tbd_
diff --git a/backend/pom.xml b/backend/pom.xml
index b46ffee466..dc933a17df 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -231,24 +231,32 @@
maven-surefire-plugin
3.5.2
-
- net.revelc.code.formatter
- formatter-maven-plugin
- 2.24.1
-
- ${maven.compiler.source}
- ${maven.compiler.source}
- ${maven.compiler.source}
-
+ com.diffplug.spotless
+ spotless-maven-plugin
+ 2.43.0
code-format
- format
+ apply
+
+
+
+ 4.26
+ ${project.basedir}/src/main/resources/formatting.xml
+
+
+
+ java|javax,ch.puzzle,org,com,com.diffplug,,\#com.diffplug,\#
+ true
+
+
+
+
@@ -305,9 +313,9 @@
- net.revelc.code.formatter
- formatter-maven-plugin
- 2.24.1
+ com.diffplug.spotless
+ spotless-maven-plugin
+ 2.43.0
code-format
diff --git a/backend/src/main/java/ch/puzzle/okr/ErrorKey.java b/backend/src/main/java/ch/puzzle/okr/ErrorKey.java
index f5a67168eb..8d72b8c704 100644
--- a/backend/src/main/java/ch/puzzle/okr/ErrorKey.java
+++ b/backend/src/main/java/ch/puzzle/okr/ErrorKey.java
@@ -1,8 +1,5 @@
package ch.puzzle.okr;
public enum ErrorKey {
- ATTRIBUTE_NULL, ATTRIBUTE_CHANGED, ATTRIBUTE_SET_FORBIDDEN, ATTRIBUTE_NOT_SET, ATTRIBUTE_CANNOT_CHANGE,
- ATTRIBUTE_MUST_BE_DRAFT, KEY_RESULT_CONVERSION, ALREADY_EXISTS_SAME_NAME, CONVERT_TOKEN, DATA_HAS_BEEN_UPDATED,
- MODEL_NULL, MODEL_WITH_ID_NOT_FOUND, NOT_AUTHORIZED_TO_READ, NOT_AUTHORIZED_TO_WRITE, NOT_AUTHORIZED_TO_DELETE,
- TOKEN_NULL, TRIED_TO_DELETE_LAST_ADMIN, TRIED_TO_REMOVE_LAST_OKR_CHAMPION
+ ATTRIBUTE_NULL, ATTRIBUTE_CHANGED, ATTRIBUTE_SET_FORBIDDEN, ATTRIBUTE_NOT_SET, ATTRIBUTE_CANNOT_CHANGE, ATTRIBUTE_MUST_BE_DRAFT, KEY_RESULT_CONVERSION, ALREADY_EXISTS_SAME_NAME, CONVERT_TOKEN, DATA_HAS_BEEN_UPDATED, MODEL_NULL, MODEL_WITH_ID_NOT_FOUND, NOT_AUTHORIZED_TO_READ, NOT_AUTHORIZED_TO_WRITE, NOT_AUTHORIZED_TO_DELETE, TOKEN_NULL, TRIED_TO_DELETE_LAST_ADMIN, TRIED_TO_REMOVE_LAST_OKR_CHAMPION
}
diff --git a/backend/src/main/java/ch/puzzle/okr/FlywayMultitenantConfig.java b/backend/src/main/java/ch/puzzle/okr/FlywayMultitenantConfig.java
index 8ef156dd9a..8bc22f7755 100644
--- a/backend/src/main/java/ch/puzzle/okr/FlywayMultitenantConfig.java
+++ b/backend/src/main/java/ch/puzzle/okr/FlywayMultitenantConfig.java
@@ -1,6 +1,7 @@
package ch.puzzle.okr;
import ch.puzzle.okr.multitenancy.FlywayMultitenantMigrationInitializer;
+
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
diff --git a/backend/src/main/java/ch/puzzle/okr/ForwardFilter.java b/backend/src/main/java/ch/puzzle/okr/ForwardFilter.java
index 2e517f4d59..243f84d92a 100644
--- a/backend/src/main/java/ch/puzzle/okr/ForwardFilter.java
+++ b/backend/src/main/java/ch/puzzle/okr/ForwardFilter.java
@@ -1,25 +1,24 @@
package ch.puzzle.okr;
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.filter.GenericFilterBean;
+
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.GenericFilterBean;
-
-import java.io.IOException;
-import java.util.Arrays;
public class ForwardFilter extends GenericFilterBean {
private static final Logger logger = LoggerFactory.getLogger(ForwardFilter.class);
@Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
- throws IOException, ServletException {
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,
+ ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
logger.debug(String.format("====> pass through the filter '%s'", request.getRequestURI()));
filterChain.doFilter(servletRequest, servletResponse);
diff --git a/backend/src/main/java/ch/puzzle/okr/OkrApplication.java b/backend/src/main/java/ch/puzzle/okr/OkrApplication.java
index 830bac19ad..35c4585e55 100644
--- a/backend/src/main/java/ch/puzzle/okr/OkrApplication.java
+++ b/backend/src/main/java/ch/puzzle/okr/OkrApplication.java
@@ -10,7 +10,7 @@ public class OkrApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(OkrApplication.class) //
- .initializers(new OkrApplicationContextInitializer()) //
- .run(args);
+ .initializers(new OkrApplicationContextInitializer()) //
+ .run(args);
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java b/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java
index 285adea577..88cc54488a 100644
--- a/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java
+++ b/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java
@@ -1,6 +1,7 @@
package ch.puzzle.okr;
import ch.puzzle.okr.multitenancy.HibernateContext;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
diff --git a/backend/src/main/java/ch/puzzle/okr/OkrErrorAttributes.java b/backend/src/main/java/ch/puzzle/okr/OkrErrorAttributes.java
index 0a721ff03b..a00d5292f5 100644
--- a/backend/src/main/java/ch/puzzle/okr/OkrErrorAttributes.java
+++ b/backend/src/main/java/ch/puzzle/okr/OkrErrorAttributes.java
@@ -1,13 +1,14 @@
package ch.puzzle.okr;
+import java.util.Map;
+
import ch.puzzle.okr.exception.OkrResponseStatusException;
+
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
-import java.util.Map;
-
@Component
public class OkrErrorAttributes extends DefaultErrorAttributes {
diff --git a/backend/src/main/java/ch/puzzle/okr/OpenAPI30Configuration.java b/backend/src/main/java/ch/puzzle/okr/OpenAPI30Configuration.java
index a7613f5b26..eb56cb7316 100644
--- a/backend/src/main/java/ch/puzzle/okr/OpenAPI30Configuration.java
+++ b/backend/src/main/java/ch/puzzle/okr/OpenAPI30Configuration.java
@@ -1,11 +1,12 @@
package ch.puzzle.okr;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenAPI30Configuration {
@@ -13,8 +14,11 @@ public class OpenAPI30Configuration {
public OpenAPI customizeOpenAPI() {
final String securitySchemeName = "bearerAuth";
return new OpenAPI().addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
- .components(new Components().addSecuritySchemes(securitySchemeName, new SecurityScheme()
- .name(securitySchemeName).type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
+ .components(new Components().addSecuritySchemes(securitySchemeName,
+ new SecurityScheme().name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")));
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/SecurityConfig.java b/backend/src/main/java/ch/puzzle/okr/SecurityConfig.java
index 051f3309f0..4ba6d90352 100644
--- a/backend/src/main/java/ch/puzzle/okr/SecurityConfig.java
+++ b/backend/src/main/java/ch/puzzle/okr/SecurityConfig.java
@@ -1,10 +1,5 @@
package ch.puzzle.okr;
-import com.nimbusds.jose.proc.SecurityContext;
-import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
-import com.nimbusds.jwt.proc.DefaultJWTProcessor;
-import com.nimbusds.jwt.proc.JWTClaimsSetAwareJWSKeySelector;
-import com.nimbusds.jwt.proc.JWTProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
@@ -33,6 +28,12 @@
import org.springframework.security.web.header.writers.CrossOriginResourcePolicyHeaderWriter;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+import com.nimbusds.jwt.proc.JWTClaimsSetAwareJWSKeySelector;
+import com.nimbusds.jwt.proc.JWTProcessor;
+
import static org.springframework.security.web.header.writers.CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.REQUIRE_CORP;
import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER;
import static org.springframework.security.web.header.writers.XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK;
@@ -50,17 +51,20 @@ public class SecurityConfig {
@Bean
@Order(1) // Must be First order! Otherwise unauthorized Requests are sent to Controllers
- public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http, @Value("${connect.src}") String connectSrc)
- throws Exception {
+ public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http, @Value("${connect.src}") String connectSrc) throws Exception {
this.connectSrc = connectSrc;
setHeaders(http);
http.addFilterAfter(new ForwardFilter(), BasicAuthenticationFilter.class);
logger.debug("*** apiSecurityFilterChain reached");
return http.cors(Customizer.withDefaults())
- .authorizeHttpRequests(e -> e.requestMatchers("/api/**").authenticated().anyRequest().permitAll())
- .exceptionHandling(e -> e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
- .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())).build();
+ .authorizeHttpRequests(e -> e.requestMatchers("/api/**")
+ .authenticated()
+ .anyRequest()
+ .permitAll())
+ .exceptionHandling(e -> e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
+ .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
+ .build();
}
@Bean
@@ -81,22 +85,24 @@ JWTProcessor jwtProcessor(JWTClaimsSetAwareJWSKeySelector jwtProcessor, OAuth2TokenValidator jwtValidator) {
NimbusJwtDecoder decoder = new NimbusJwtDecoder(jwtProcessor);
OAuth2TokenValidator validator = new DelegatingOAuth2TokenValidator<>(JwtValidators.createDefault(),
- jwtValidator);
+ jwtValidator);
decoder.setJwtValidator(validator);
return decoder;
}
private HttpSecurity setHeaders(HttpSecurity http) throws Exception {
- return http.headers(headers -> headers
- .contentSecurityPolicy(c -> c.policyDirectives(okrContentSecurityPolicy()))
- .crossOriginEmbedderPolicy(c -> c.policy(REQUIRE_CORP))
- .crossOriginOpenerPolicy(c -> c.policy(OPENER_SAME_ORIGIN))
- .crossOriginResourcePolicy(c -> c.policy(RESOURCE_SAME_ORIGIN))
- .addHeaderWriter(new StaticHeadersWriter("X-Permitted-Cross-Domain-Policies", "none"))
- .frameOptions(HeadersConfigurer.FrameOptionsConfig::deny)
- .xssProtection(c -> c.headerValue(ENABLED_MODE_BLOCK))
- .httpStrictTransportSecurity(c -> c.includeSubDomains(true).maxAgeInSeconds(31536000))
- .referrerPolicy(c -> c.policy(NO_REFERRER)).permissionsPolicy(c -> c.policy(okrPermissionPolicy())));
+ return http.headers(headers -> headers.contentSecurityPolicy(c -> c.policyDirectives(okrContentSecurityPolicy()))
+ .crossOriginEmbedderPolicy(c -> c.policy(REQUIRE_CORP))
+ .crossOriginOpenerPolicy(c -> c.policy(OPENER_SAME_ORIGIN))
+ .crossOriginResourcePolicy(c -> c.policy(RESOURCE_SAME_ORIGIN))
+ .addHeaderWriter(new StaticHeadersWriter("X-Permitted-Cross-Domain-Policies",
+ "none"))
+ .frameOptions(HeadersConfigurer.FrameOptionsConfig::deny)
+ .xssProtection(c -> c.headerValue(ENABLED_MODE_BLOCK))
+ .httpStrictTransportSecurity(c -> c.includeSubDomains(true)
+ .maxAgeInSeconds(31536000))
+ .referrerPolicy(c -> c.policy(NO_REFERRER))
+ .permissionsPolicy(c -> c.policy(okrPermissionPolicy())));
}
private String okrContentSecurityPolicy() {
@@ -115,18 +121,11 @@ private String okrContentSecurityPolicy() {
}
private String okrPermissionPolicy() {
- return "accelerometer=(), ambient-light-sensor=(), autoplay=(), "
- + "battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), "
- + "execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(),"
- + " geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), "
- + "midi=(), navigation-override=(), payment=(), picture-in-picture=(),"
- + " publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), "
- + "usb=(), web-share=(), xr-spatial-tracking=()";
+ return "accelerometer=(), ambient-light-sensor=(), autoplay=(), " + "battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), " + "execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=()," + " geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), " + "midi=(), navigation-override=(), payment=(), picture-in-picture=()," + " publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), " + "usb=(), web-share=(), xr-spatial-tracking=()";
}
@Bean
- public AuthenticationEventPublisher authenticationEventPublisher(
- ApplicationEventPublisher applicationEventPublisher) {
+ public AuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
}
diff --git a/backend/src/main/java/ch/puzzle/okr/SpringCachingConfig.java b/backend/src/main/java/ch/puzzle/okr/SpringCachingConfig.java
index 62bae32213..256107f4e7 100644
--- a/backend/src/main/java/ch/puzzle/okr/SpringCachingConfig.java
+++ b/backend/src/main/java/ch/puzzle/okr/SpringCachingConfig.java
@@ -2,6 +2,7 @@
import ch.puzzle.okr.models.User;
import ch.puzzle.okr.multitenancy.TenantContext;
+
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
diff --git a/backend/src/main/java/ch/puzzle/okr/UserKeyGenerator.java b/backend/src/main/java/ch/puzzle/okr/UserKeyGenerator.java
index 144a056e30..ef6dbf9d31 100644
--- a/backend/src/main/java/ch/puzzle/okr/UserKeyGenerator.java
+++ b/backend/src/main/java/ch/puzzle/okr/UserKeyGenerator.java
@@ -1,11 +1,12 @@
package ch.puzzle.okr;
+import java.lang.reflect.Method;
+import java.text.MessageFormat;
+
import ch.puzzle.okr.models.User;
import ch.puzzle.okr.multitenancy.TenantContext;
-import org.springframework.cache.interceptor.KeyGenerator;
-import java.lang.reflect.Method;
-import java.text.MessageFormat;
+import org.springframework.cache.interceptor.KeyGenerator;
public class UserKeyGenerator implements KeyGenerator {
@Override
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/ActionController.java b/backend/src/main/java/ch/puzzle/okr/controller/ActionController.java
index d6b9855b7b..5edfefb8d6 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/ActionController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/ActionController.java
@@ -1,17 +1,19 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.ActionDto;
import ch.puzzle.okr.mapper.ActionMapper;
import ch.puzzle.okr.models.Action;
import ch.puzzle.okr.service.authorization.ActionAuthorizationService;
+
+import org.springframework.web.bind.annotation.*;
+
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 org.springframework.web.bind.annotation.*;
-
-import java.util.List;
@RestController
@RequestMapping("api/v2/action")
@@ -25,20 +27,15 @@ public ActionController(ActionAuthorizationService actionAuthorizationService, A
}
@Operation(summary = "Update Actions", description = "Update Actions of KeyResult")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Updated Actions of KeyResult", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ActionDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't update Actions, attributes are not set", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Updated Actions of KeyResult", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ActionDto.class))}), @ApiResponse(responseCode = "400", description = "Can't update Actions, attributes are not set", content = @Content)})
@PutMapping
- public void updateActions(
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Action as json to update existing Actions.", required = true) @RequestBody List actionDtoList) {
+ public void updateActions(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Action as json to update existing Actions.", required = true) @RequestBody List actionDtoList) {
List actionList = actionMapper.toActions(actionDtoList);
actionAuthorizationService.updateEntities(actionList);
}
@Operation(summary = "Delete Action by Id", description = "Delete Action by Id")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted Action by Id"),
- @ApiResponse(responseCode = "404", description = "Did not find the Action with requested id") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted Action by Id"), @ApiResponse(responseCode = "404", description = "Did not find the Action with requested id")})
@DeleteMapping("/{actionId}")
public void deleteActionById(@PathVariable long actionId) {
actionAuthorizationService.deleteActionByActionId(actionId);
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/AlignmentController.java b/backend/src/main/java/ch/puzzle/okr/controller/AlignmentController.java
index 85b6a77ec1..6b19e52c1c 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/AlignmentController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/AlignmentController.java
@@ -1,13 +1,11 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.alignment.AlignmentObjectiveDto;
import ch.puzzle.okr.mapper.AlignmentSelectionMapper;
import ch.puzzle.okr.service.business.AlignmentSelectionBusinessService;
-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 org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -15,7 +13,11 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-import java.util.List;
+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;
@RestController
@RequestMapping("api/v2/alignments")
@@ -23,23 +25,17 @@ public class AlignmentController {
private final AlignmentSelectionMapper alignmentSelectionMapper;
private final AlignmentSelectionBusinessService alignmentSelectionBusinessService;
- public AlignmentController(AlignmentSelectionMapper alignmentSelectionMapper,
- AlignmentSelectionBusinessService alignmentSelectionBusinessService) {
+ public AlignmentController(AlignmentSelectionMapper alignmentSelectionMapper, AlignmentSelectionBusinessService alignmentSelectionBusinessService) {
this.alignmentSelectionMapper = alignmentSelectionMapper;
this.alignmentSelectionBusinessService = alignmentSelectionBusinessService;
}
@Operation(summary = "Get all objectives and their key results to select the alignment", description = "Get a list of objectives with their key results to select the alignment")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned a list of objectives with their key results to select the alignment", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = AlignmentObjectiveDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't return list of objectives with their key results to select the alignment", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned a list of objectives with their key results to select the alignment", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = AlignmentObjectiveDto.class))}), @ApiResponse(responseCode = "400", description = "Can't return list of objectives with their key results to select the alignment", content = @Content)})
@GetMapping("/selections")
- public ResponseEntity> getAlignmentSelections(
- @RequestParam(required = false, defaultValue = "", name = "quarter") Long quarterFilter,
- @RequestParam(required = false, defaultValue = "", name = "team") Long teamFilter) {
+ public ResponseEntity> getAlignmentSelections(@RequestParam(required = false, defaultValue = "", name = "quarter") Long quarterFilter, @RequestParam(required = false, defaultValue = "", name = "team") Long teamFilter) {
return ResponseEntity.status(HttpStatus.OK)
- .body(alignmentSelectionMapper.toDto(alignmentSelectionBusinessService
- .getAlignmentSelectionByQuarterIdAndTeamIdNot(quarterFilter, teamFilter)));
+ .body(alignmentSelectionMapper.toDto(alignmentSelectionBusinessService.getAlignmentSelectionByQuarterIdAndTeamIdNot(quarterFilter,
+ teamFilter)));
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/CacheController.java b/backend/src/main/java/ch/puzzle/okr/controller/CacheController.java
index ee46548003..7c025652ac 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/CacheController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/CacheController.java
@@ -1,13 +1,15 @@
package ch.puzzle.okr.controller;
import ch.puzzle.okr.service.CacheService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
+
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+
@RestController
@RequestMapping("api/v2/caches")
public class CacheController {
@@ -18,14 +20,14 @@ public CacheController(CacheService cacheService) {
}
@Operation(summary = "Delete authorization users cache", description = "Delete authorization users cache")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Authorization users cache deleted") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Authorization users cache deleted")})
@PostMapping("emptyAuthorizationUsersCache")
public void emptyAuthorizationUsersCache() {
cacheService.emptyAuthorizationUsersCache();
}
@Operation(summary = "Delete all caches", description = "Delete all caches")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "All caches deleted") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "All caches deleted")})
@PostMapping("emptyAllCaches")
public void emptyAllCaches() {
cacheService.emptyAllCaches();
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/CheckInController.java b/backend/src/main/java/ch/puzzle/okr/controller/CheckInController.java
index 83c6030f2e..dd58e2cda2 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/CheckInController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/CheckInController.java
@@ -4,15 +4,17 @@
import ch.puzzle.okr.mapper.checkin.CheckInMapper;
import ch.puzzle.okr.models.checkin.CheckIn;
import ch.puzzle.okr.service.authorization.CheckInAuthorizationService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("api/v2/checkIns")
@@ -27,56 +29,38 @@ public CheckInController(CheckInMapper checkInMapper, CheckInAuthorizationServic
}
@Operation(summary = "Get Check-in", description = "Get Check-in by ID")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned a Check-in with a specified ID", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class)) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to read Check-in", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find a Check-in with a specified ID", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned a Check-in with a specified ID", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class))}), @ApiResponse(responseCode = "401", description = "Not authorized to read Check-in", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find a Check-in with a specified ID", content = @Content)})
@GetMapping("/{id}")
public ResponseEntity getCheckInById(@PathVariable long id) {
return ResponseEntity.status(HttpStatus.OK)
- .body(checkInMapper.toDto(this.checkInAuthorizationService.getEntityById(id)));
+ .body(checkInMapper.toDto(this.checkInAuthorizationService.getEntityById(id)));
}
@Operation(summary = "Update Check-in", description = "Update a Check-in by ID")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Updated Check-in in db", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't create new Check-in, attributes are not set", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to update Check-in", content = @Content),
- @ApiResponse(responseCode = "404", description = "Given ID of Check-in wasn't found.", content = @Content),
- @ApiResponse(responseCode = "422", description = "Can't update Check-in since Check-in was updated or deleted by another user.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Updated Check-in in db", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class))}), @ApiResponse(responseCode = "400", description = "Can't create new Check-in, attributes are not set", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to update Check-in", content = @Content), @ApiResponse(responseCode = "404", description = "Given ID of Check-in wasn't found.", content = @Content), @ApiResponse(responseCode = "422", description = "Can't update Check-in since Check-in was updated or deleted by another user.", content = @Content)})
@PutMapping("/{id}")
- public ResponseEntity updateCheckIn(
- @Parameter(description = "The ID for updating a Check-in.", required = true) @PathVariable Long id,
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Check-in as json to update an existing Check-in.", required = true) @RequestBody CheckInDto checkInDto) {
+ public ResponseEntity updateCheckIn(@Parameter(description = "The ID for updating a Check-in.", required = true) @PathVariable Long id, @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Check-in as json to update an existing Check-in.", required = true) @RequestBody CheckInDto checkInDto) {
CheckIn checkIn = checkInMapper.toCheckIn(checkInDto);
- CheckInDto updatedCheckIn = this.checkInMapper
- .toDto(this.checkInAuthorizationService.updateEntity(id, checkIn));
- return ResponseEntity.status(HttpStatus.OK).body(updatedCheckIn);
+ CheckInDto updatedCheckIn = this.checkInMapper.toDto(this.checkInAuthorizationService.updateEntity(id,
+ checkIn));
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(updatedCheckIn);
}
@Operation(summary = "Create Check-in", description = "Create a new Check-in")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "Created new Check-in.", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't create new Check-in, not allowed to give an ID", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to create Check-in", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Created new Check-in.", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class))}), @ApiResponse(responseCode = "400", description = "Can't create new Check-in, not allowed to give an ID", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to create Check-in", content = @Content)})
@PostMapping
- public ResponseEntity createCheckIn(
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Check-in as json to create a new Check-in.", required = true) @RequestBody CheckInDto checkInDto) {
+ public ResponseEntity createCheckIn(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Check-in as json to create a new Check-in.", required = true) @RequestBody CheckInDto checkInDto) {
CheckIn checkIn = checkInMapper.toCheckIn(checkInDto);
CheckInDto createdCheckIn = checkInMapper.toDto(checkInAuthorizationService.createEntity(checkIn));
- return ResponseEntity.status(HttpStatus.CREATED).body(createdCheckIn);
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(createdCheckIn);
}
@Operation(summary = "Delete Check-in by ID", description = "Delete Check-in by ID")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted Check-in by ID"),
- @ApiResponse(responseCode = "401", description = "Not authorized to delete Check-in", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Check-in with requested ID") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted Check-in by ID"), @ApiResponse(responseCode = "401", description = "Not authorized to delete Check-in", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Check-in with requested ID")})
@DeleteMapping("/{id}")
- public void deleteCheckInById(
- @Parameter(description = "The ID of an Check-in to delete it.", required = true) @PathVariable long id) {
+ public void deleteCheckInById(@Parameter(description = "The ID of an Check-in to delete it.", required = true) @PathVariable long id) {
this.checkInAuthorizationService.deleteEntityById(id);
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/ClientConfigController.java b/backend/src/main/java/ch/puzzle/okr/controller/ClientConfigController.java
index ec45e2f782..6bce730715 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/ClientConfigController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/ClientConfigController.java
@@ -2,13 +2,15 @@
import ch.puzzle.okr.dto.ClientConfigDto;
import ch.puzzle.okr.service.clientconfig.ClientConfigService;
-import jakarta.servlet.http.HttpServletRequest;
+
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
+import jakarta.servlet.http.HttpServletRequest;
+
@Controller
public class ClientConfigController {
@@ -21,7 +23,7 @@ public ClientConfigController(ClientConfigService configService) {
@GetMapping("/config")
public ResponseEntity getConfig(HttpServletRequest request) {
return ResponseEntity.status(HttpStatus.OK)
- .body(configService.getConfigBasedOnActiveEnv(request.getServerName()));
+ .body(configService.getConfigBasedOnActiveEnv(request.getServerName()));
}
@RequestMapping(value = "/**/{[path:[^\\.]*}")
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/CompletedController.java b/backend/src/main/java/ch/puzzle/okr/controller/CompletedController.java
index 4b8e10e5dc..39687fbbcc 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/CompletedController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/CompletedController.java
@@ -4,14 +4,16 @@
import ch.puzzle.okr.mapper.CompletedMapper;
import ch.puzzle.okr.models.Completed;
import ch.puzzle.okr.service.authorization.CompletedAuthorizationService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
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 org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("api/v2/completed")
@@ -20,29 +22,23 @@ public class CompletedController {
private final CompletedAuthorizationService completedAuthorizationService;
private final CompletedMapper completedMapper;
- public CompletedController(CompletedAuthorizationService completedAuthorizationService,
- CompletedMapper completedMapper) {
+ public CompletedController(CompletedAuthorizationService completedAuthorizationService, CompletedMapper completedMapper) {
this.completedAuthorizationService = completedAuthorizationService;
this.completedMapper = completedMapper;
}
@Operation(summary = "Create Completed", description = "Create a new Completed Reference.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "Created new Completed.", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = Completed.class)) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to create Completed Reference", content = @Content),
- @ApiResponse(responseCode = "404", description = "Could not create Completed Reference", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Created new Completed.", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = Completed.class))}), @ApiResponse(responseCode = "401", description = "Not authorized to create Completed Reference", content = @Content), @ApiResponse(responseCode = "404", description = "Could not create Completed Reference", content = @Content)})
@PostMapping
public ResponseEntity createCompleted(@RequestBody CompletedDto completedDto) {
Completed completed = completedMapper.toCompleted(completedDto);
Completed createdCompleted = completedAuthorizationService.createCompleted(completed);
- return ResponseEntity.status(HttpStatus.CREATED).body(completedMapper.toDto(createdCompleted));
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(completedMapper.toDto(createdCompleted));
}
@Operation(summary = "Delete Completed by Objective Id", description = "Delete Completed Reference by Objective Id")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted Completed by Objective Id"),
- @ApiResponse(responseCode = "401", description = "Not authorized to delete Completed Reference", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Completed with requested Objective id") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted Completed by Objective Id"), @ApiResponse(responseCode = "401", description = "Not authorized to delete Completed Reference", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Completed with requested Objective id")})
@DeleteMapping("/{objectiveId}")
public void deleteCompletedByObjectiveId(@PathVariable long objectiveId) {
completedAuthorizationService.deleteCompletedByObjectiveId(objectiveId);
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/KeyResultController.java b/backend/src/main/java/ch/puzzle/okr/controller/KeyResultController.java
index 0940bdc333..98e1982421 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/KeyResultController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/KeyResultController.java
@@ -1,5 +1,7 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.checkin.CheckInDto;
import ch.puzzle.okr.dto.keyresult.KeyResultDto;
import ch.puzzle.okr.dto.keyresult.KeyResultMetricDto;
@@ -12,16 +14,16 @@
import ch.puzzle.okr.models.keyresult.KeyResultWithActionList;
import ch.puzzle.okr.service.authorization.ActionAuthorizationService;
import ch.puzzle.okr.service.authorization.KeyResultAuthorizationService;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
import static org.springframework.http.HttpStatus.*;
@@ -35,9 +37,7 @@ public class KeyResultController {
private final CheckInMapper checkInMapper;
private final ActionMapper actionMapper;
- public KeyResultController(KeyResultAuthorizationService keyResultAuthorizationService,
- ActionAuthorizationService actionAuthorizationService, KeyResultMapper keyResultMapper,
- CheckInMapper checkInMapper, ActionMapper actionMapper) {
+ public KeyResultController(KeyResultAuthorizationService keyResultAuthorizationService, ActionAuthorizationService actionAuthorizationService, KeyResultMapper keyResultMapper, CheckInMapper checkInMapper, ActionMapper actionMapper) {
this.keyResultAuthorizationService = keyResultAuthorizationService;
this.actionAuthorizationService = actionAuthorizationService;
this.keyResultMapper = keyResultMapper;
@@ -46,12 +46,7 @@ public KeyResultController(KeyResultAuthorizationService keyResultAuthorizationS
}
@Operation(summary = "Get KeyResult by Id", description = "Get KeyResult by Id")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Got KeyResult by Id", content = {
- @Content(mediaType = "application/json", schema = @Schema(allOf = { KeyResultMetricDto.class,
- KeyResultOrdinalDto.class })) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to read a KeyResult", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the KeyResult with requested id", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Got KeyResult by Id", content = {@Content(mediaType = "application/json", schema = @Schema(allOf = {KeyResultMetricDto.class, KeyResultOrdinalDto.class}))}), @ApiResponse(responseCode = "401", description = "Not authorized to read a KeyResult", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the KeyResult with requested id", content = @Content)})
@GetMapping("/{id}")
public KeyResultDto getKeyResultById(@PathVariable long id) {
KeyResult keyResult = keyResultAuthorizationService.getEntityById(id);
@@ -60,60 +55,43 @@ public KeyResultDto getKeyResultById(@PathVariable long id) {
}
@Operation(summary = "Get Check-ins from KeyResult", description = "Get all Check-ins from one KeyResult by keyResultId.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned all Check-ins from KeyResult.", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class)) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to read Check-ins from a KeyResult", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find a KeyResult with a specified ID to get Check-ins from.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned all Check-ins from KeyResult.", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDto.class))}), @ApiResponse(responseCode = "401", description = "Not authorized to read Check-ins from a KeyResult", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find a KeyResult with a specified ID to get Check-ins from.", content = @Content)})
@GetMapping("/{id}/checkins")
- public List getCheckInsFromKeyResult(
- @Parameter(description = "The ID for getting all Check-ins from a KeyResult.", required = true) @PathVariable long id) {
- return keyResultAuthorizationService.getAllCheckInsByKeyResult(id).stream().map(checkInMapper::toDto).toList();
+ public List getCheckInsFromKeyResult(@Parameter(description = "The ID for getting all Check-ins from a KeyResult.", required = true) @PathVariable long id) {
+ return keyResultAuthorizationService.getAllCheckInsByKeyResult(id)
+ .stream()
+ .map(checkInMapper::toDto)
+ .toList();
}
@Operation(summary = "Create KeyResult", description = "Create a new KeyResult.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "Created new KeyResult.", content = {
- @Content(mediaType = "application/json", schema = @Schema(allOf = { KeyResultDto.class,
- KeyResultOrdinalDto.class })) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to create a KeyResult", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find an Objective on which the KeyResult tries to refer to.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Created new KeyResult.", content = {@Content(mediaType = "application/json", schema = @Schema(allOf = {KeyResultDto.class, KeyResultOrdinalDto.class}))}), @ApiResponse(responseCode = "401", description = "Not authorized to create a KeyResult", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find an Objective on which the KeyResult tries to refer to.", content = @Content)})
@PostMapping
public ResponseEntity createKeyResult(@RequestBody KeyResultDto keyResultDto) {
KeyResult keyResult = keyResultAuthorizationService.createEntity(keyResultMapper.toKeyResult(keyResultDto));
List actionList = actionMapper.toActions(keyResultDto.getActionList(), keyResult);
List savedActions = actionAuthorizationService.createEntities(actionList);
KeyResultDto createdKeyResult = keyResultMapper.toDto(keyResult, savedActions);
- return ResponseEntity.status(CREATED).body(createdKeyResult);
+ return ResponseEntity.status(CREATED)
+ .body(createdKeyResult);
}
@Operation(summary = "Update KeyResult", description = "Update a KeyResult by ID.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Updated KeyResult in db.", content = {
- @Content(mediaType = "application/json", schema = @Schema(allOf = { KeyResultDto.class,
- KeyResultOrdinalDto.class })) }),
- @ApiResponse(responseCode = "226", description = "Updated KeyResult in db but keyResultType was not changed", content = {
- @Content(mediaType = "application/json", schema = @Schema(allOf = KeyResultDto.class)) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to update a KeyResult", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find a KeyResult with a specified ID to update.", content = @Content),
- @ApiResponse(responseCode = "422", description = "Can't update KeyResult since KeyResult was updated or deleted by another user.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Updated KeyResult in db.", content = {@Content(mediaType = "application/json", schema = @Schema(allOf = {KeyResultDto.class, KeyResultOrdinalDto.class}))}), @ApiResponse(responseCode = "226", description = "Updated KeyResult in db but keyResultType was not changed", content = {@Content(mediaType = "application/json", schema = @Schema(allOf = KeyResultDto.class))}), @ApiResponse(responseCode = "401", description = "Not authorized to update a KeyResult", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find a KeyResult with a specified ID to update.", content = @Content), @ApiResponse(responseCode = "422", description = "Can't update KeyResult since KeyResult was updated or deleted by another user.", content = @Content)})
@PutMapping("/{id}")
- public ResponseEntity updateKeyResult(
- @Parameter(description = "The ID for updating a KeyResult.", required = true) @PathVariable long id,
- @RequestBody KeyResultDto keyResultDto) {
+ public ResponseEntity updateKeyResult(@Parameter(description = "The ID for updating a KeyResult.", required = true) @PathVariable long id, @RequestBody KeyResultDto keyResultDto) {
KeyResult keyResult = keyResultMapper.toKeyResult(keyResultDto);
List actionList = actionMapper.toActions(keyResultDto.getActionList(), keyResult);
boolean isKeyResultImUsed = keyResultAuthorizationService.isImUsed(id, keyResult);
- KeyResultWithActionList updatedKeyResult = keyResultAuthorizationService.updateEntities(id, keyResult,
- actionList);
+ KeyResultWithActionList updatedKeyResult = keyResultAuthorizationService.updateEntities(id,
+ keyResult,
+ actionList);
return ResponseEntity.status(isKeyResultImUsed ? IM_USED : OK)
- .body(keyResultMapper.toDto(updatedKeyResult.keyResult(), updatedKeyResult.actionList()));
+ .body(keyResultMapper.toDto(updatedKeyResult.keyResult(), updatedKeyResult.actionList()));
}
@Operation(summary = "Delete KeyResult by Id", description = "Delete KeyResult by Id")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted KeyResult by Id"),
- @ApiResponse(responseCode = "401", description = "Not authorized to delete a KeyResult", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the KeyResult with requested id") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted KeyResult by Id"), @ApiResponse(responseCode = "401", description = "Not authorized to delete a KeyResult", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the KeyResult with requested id")})
@DeleteMapping("/{id}")
public void deleteKeyResultById(@PathVariable long id) {
keyResultAuthorizationService.deleteEntityById(id);
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/ObjectiveController.java b/backend/src/main/java/ch/puzzle/okr/controller/ObjectiveController.java
index 61e0f2cab8..32868f8b6b 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/ObjectiveController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/ObjectiveController.java
@@ -4,15 +4,17 @@
import ch.puzzle.okr.mapper.ObjectiveMapper;
import ch.puzzle.okr.models.Objective;
import ch.puzzle.okr.service.authorization.ObjectiveAuthorizationService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
import static org.springframework.http.HttpStatus.IM_USED;
import static org.springframework.http.HttpStatus.OK;
@@ -23,80 +25,56 @@ public class ObjectiveController {
private final ObjectiveAuthorizationService objectiveAuthorizationService;
private final ObjectiveMapper objectiveMapper;
- public ObjectiveController(ObjectiveAuthorizationService objectiveAuthorizationService,
- ObjectiveMapper objectiveMapper) {
+ public ObjectiveController(ObjectiveAuthorizationService objectiveAuthorizationService, ObjectiveMapper objectiveMapper) {
this.objectiveAuthorizationService = objectiveAuthorizationService;
this.objectiveMapper = objectiveMapper;
}
@Operation(summary = "Get Objective", description = "Get an Objective by ID")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned an Objective with a specified ID", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class)) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to read an Objective", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find an Objective with a specified ID", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned an Objective with a specified ID", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class))}), @ApiResponse(responseCode = "401", description = "Not authorized to read an Objective", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find an Objective with a specified ID", content = @Content)})
@GetMapping("/{id}")
- public ResponseEntity getObjective(
- @Parameter(description = "The ID for getting an Objective.", required = true) @PathVariable Long id) {
+ public ResponseEntity getObjective(@Parameter(description = "The ID for getting an Objective.", required = true) @PathVariable Long id) {
return ResponseEntity.status(HttpStatus.OK)
- .body(objectiveMapper.toDto(objectiveAuthorizationService.getEntityById(id)));
+ .body(objectiveMapper.toDto(objectiveAuthorizationService.getEntityById(id)));
}
@Operation(summary = "Delete Objective by ID", description = "Delete Objective by ID")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted Objective by ID"),
- @ApiResponse(responseCode = "401", description = "Not authorized to delete an Objective", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Objective with requested ID") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted Objective by ID"), @ApiResponse(responseCode = "401", description = "Not authorized to delete an Objective", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Objective with requested ID")})
@DeleteMapping("/{id}")
- public void deleteObjectiveById(
- @Parameter(description = "The ID of an Objective to delete it.", required = true) @PathVariable long id) {
+ public void deleteObjectiveById(@Parameter(description = "The ID of an Objective to delete it.", required = true) @PathVariable long id) {
objectiveAuthorizationService.deleteEntityById(id);
}
@Operation(summary = "Create Objective", description = "Create a new Objective")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "Created new Objective", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't create new Objective, not allowed to give an ID", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to create an Objective", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Created new Objective", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class))}), @ApiResponse(responseCode = "400", description = "Can't create new Objective, not allowed to give an ID", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to create an Objective", content = @Content)})
@PostMapping
- public ResponseEntity createObjective(
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Objective as json to create a new Objective.", required = true) @RequestBody ObjectiveDto objectiveDTO) {
+ public ResponseEntity createObjective(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Objective as json to create a new Objective.", required = true) @RequestBody ObjectiveDto objectiveDTO) {
Objective objective = objectiveMapper.toObjective(objectiveDTO);
ObjectiveDto createdObjective = objectiveMapper.toDto(objectiveAuthorizationService.createEntity(objective));
- return ResponseEntity.status(HttpStatus.CREATED).body(createdObjective);
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(createdObjective);
}
@Operation(summary = "Duplicate Objective", description = "Duplicate a given Objective")
- @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "Duplicated a given Objective", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class)) }) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Duplicated a given Objective", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class))})})
@PostMapping("/{id}")
- public ResponseEntity duplicateObjective(
- @Parameter(description = "The ID for duplicating an Objective.", required = true) @PathVariable Long id,
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Objective which should be duplicated as json", required = true) @RequestBody ObjectiveDto objectiveDTO) {
+ public ResponseEntity duplicateObjective(@Parameter(description = "The ID for duplicating an Objective.", required = true) @PathVariable Long id, @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Objective which should be duplicated as json", required = true) @RequestBody ObjectiveDto objectiveDTO) {
Objective objective = objectiveMapper.toObjective(objectiveDTO);
- ObjectiveDto duplicatedObjectiveDto = objectiveMapper
- .toDto(objectiveAuthorizationService.duplicateEntity(id, objective));
- return ResponseEntity.status(HttpStatus.CREATED).body(duplicatedObjectiveDto);
+ ObjectiveDto duplicatedObjectiveDto = objectiveMapper.toDto(objectiveAuthorizationService.duplicateEntity(id,
+ objective));
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(duplicatedObjectiveDto);
}
@Operation(summary = "Update Objective", description = "Update Objective by ID")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Updated Objective in db", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class)) }),
- @ApiResponse(responseCode = "226", description = "Updated Objective in db but quarter was not changed", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't create new Objective, attributes are not set or tried to set quarter", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to update an Objective", content = @Content),
- @ApiResponse(responseCode = "404", description = "Given ID of Objective wasn't found", content = @Content),
- @ApiResponse(responseCode = "422", description = "Can't update Objective since Objective was updated or deleted by another user.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Updated Objective in db", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class))}), @ApiResponse(responseCode = "226", description = "Updated Objective in db but quarter was not changed", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ObjectiveDto.class))}), @ApiResponse(responseCode = "400", description = "Can't create new Objective, attributes are not set or tried to set quarter", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to update an Objective", content = @Content), @ApiResponse(responseCode = "404", description = "Given ID of Objective wasn't found", content = @Content), @ApiResponse(responseCode = "422", description = "Can't update Objective since Objective was updated or deleted by another user.", content = @Content)})
@PutMapping("/{id}")
- public ResponseEntity updateObjective(
- @Parameter(description = "The ID for updating an Objective.", required = true) @PathVariable Long id,
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The objective as json to update an existing Objective.", required = true) @RequestBody ObjectiveDto objectiveDTO) {
+ public ResponseEntity updateObjective(@Parameter(description = "The ID for updating an Objective.", required = true) @PathVariable Long id, @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The objective as json to update an existing Objective.", required = true) @RequestBody ObjectiveDto objectiveDTO) {
Objective objective = objectiveMapper.toObjective(objectiveDTO);
boolean isObjectiveImUsed = objectiveAuthorizationService.isImUsed(objective);
- ObjectiveDto updatedObjective = objectiveMapper
- .toDto(objectiveAuthorizationService.updateEntity(id, objective));
- return ResponseEntity.status(isObjectiveImUsed ? IM_USED : OK).body(updatedObjective);
+ ObjectiveDto updatedObjective = objectiveMapper.toDto(objectiveAuthorizationService.updateEntity(id,
+ objective));
+ return ResponseEntity.status(isObjectiveImUsed ? IM_USED : OK)
+ .body(updatedObjective);
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/OverviewController.java b/backend/src/main/java/ch/puzzle/okr/controller/OverviewController.java
index ff8dfe009d..1ba5dbca55 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/OverviewController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/OverviewController.java
@@ -1,13 +1,11 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.overview.OverviewDto;
import ch.puzzle.okr.mapper.OverviewMapper;
import ch.puzzle.okr.service.authorization.OverviewAuthorizationService;
-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 org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -15,7 +13,11 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-import java.util.List;
+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;
@RestController
@RequestMapping("api/v2/overview")
@@ -23,25 +25,18 @@ public class OverviewController {
private final OverviewMapper overviewMapper;
private final OverviewAuthorizationService overviewAuthorizationService;
- public OverviewController(OverviewMapper overviewMapper,
- OverviewAuthorizationService overviewAuthorizationService) {
+ public OverviewController(OverviewMapper overviewMapper, OverviewAuthorizationService overviewAuthorizationService) {
this.overviewMapper = overviewMapper;
this.overviewAuthorizationService = overviewAuthorizationService;
}
@Operation(summary = "Get all teams and their objectives", description = "Get a List of teams with their objectives")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned a List of teams and their objectives", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = OverviewDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't return list of teams with their objectives", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to read teams with their objectives", content = @Content),
- @ApiResponse(responseCode = "404", description = "The quarter or one of the teams were not found", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned a List of teams and their objectives", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = OverviewDto.class))}), @ApiResponse(responseCode = "400", description = "Can't return list of teams with their objectives", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to read teams with their objectives", content = @Content), @ApiResponse(responseCode = "404", description = "The quarter or one of the teams were not found", content = @Content)})
@GetMapping("")
- public ResponseEntity> getOverview(
- @RequestParam(required = false, defaultValue = "", name = "team") List teamFilter,
- @RequestParam(required = false, defaultValue = "", name = "quarter") Long quarterFilter,
- @RequestParam(required = false, defaultValue = "", name = "objectiveQuery") String objectiveQuery) {
- return ResponseEntity.status(HttpStatus.OK).body(overviewMapper
- .toDto(overviewAuthorizationService.getFilteredOverview(quarterFilter, teamFilter, objectiveQuery)));
+ public ResponseEntity> getOverview(@RequestParam(required = false, defaultValue = "", name = "team") List teamFilter, @RequestParam(required = false, defaultValue = "", name = "quarter") Long quarterFilter, @RequestParam(required = false, defaultValue = "", name = "objectiveQuery") String objectiveQuery) {
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(overviewMapper.toDto(overviewAuthorizationService.getFilteredOverview(quarterFilter,
+ teamFilter,
+ objectiveQuery)));
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/QuarterController.java b/backend/src/main/java/ch/puzzle/okr/controller/QuarterController.java
index 1cc1383dbc..8edef72bf9 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/QuarterController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/QuarterController.java
@@ -1,20 +1,21 @@
package ch.puzzle.okr.controller;
-import ch.puzzle.okr.dto.TeamDto;
+import java.util.List;
+
import ch.puzzle.okr.models.Quarter;
import ch.puzzle.okr.service.business.QuarterBusinessService;
-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 org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import java.util.List;
+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;
@RestController
@RequestMapping("api/v2/quarters")
@@ -27,18 +28,18 @@ public QuarterController(QuarterBusinessService quarterBusinessService) {
}
@Operation(summary = "Get quarters", description = "Get a List of quarters depending on current date")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned a List of quarters", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = Quarter.class)) }) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned a List of quarters", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = Quarter.class))})})
@GetMapping("")
public ResponseEntity> getCurrentQuarters() {
- return ResponseEntity.status(HttpStatus.OK).body(this.quarterBusinessService.getQuarters());
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(this.quarterBusinessService.getQuarters());
}
@Operation(summary = "Get current quarter", description = "Get the current quarter depending on current date")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned the current quarter", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = Quarter.class)) }) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned the current quarter", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = Quarter.class))})})
@GetMapping("/current")
public ResponseEntity getCurrentQuarter() {
- return ResponseEntity.status(HttpStatus.OK).body(this.quarterBusinessService.getCurrentQuarter());
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(this.quarterBusinessService.getCurrentQuarter());
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/TeamController.java b/backend/src/main/java/ch/puzzle/okr/controller/TeamController.java
index ccaad22741..e6f502133f 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/TeamController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/TeamController.java
@@ -1,21 +1,23 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.TeamDto;
import ch.puzzle.okr.dto.UserDto;
import ch.puzzle.okr.mapper.TeamMapper;
import ch.puzzle.okr.models.Team;
import ch.puzzle.okr.service.authorization.TeamAuthorizationService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
import static org.springframework.http.HttpStatus.OK;
@@ -31,84 +33,61 @@ public TeamController(TeamAuthorizationService teamAuthorizationService, TeamMap
}
@Operation(summary = "Get Teams", description = "Get all Teams from db")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned all Teams", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = TeamDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned all Teams", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = TeamDto.class))}),})
@GetMapping
public List getAllTeams() {
- return teamAuthorizationService.getAllTeams().stream().map(teamMapper::toDto).toList();
+ return teamAuthorizationService.getAllTeams()
+ .stream()
+ .map(teamMapper::toDto)
+ .toList();
}
@Operation(summary = "Create Team", description = "Create a new Team")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "Created new Team", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = TeamDto.class)) }),
- @ApiResponse(responseCode = "400", description = "Can't create new Team, not allowed to give an ID", content = @Content),
- @ApiResponse(responseCode = "401", description = "Not authorized to create a Team", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Created new Team", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = TeamDto.class))}), @ApiResponse(responseCode = "400", description = "Can't create new Team, not allowed to give an ID", content = @Content), @ApiResponse(responseCode = "401", description = "Not authorized to create a Team", content = @Content)})
@PostMapping
- public ResponseEntity createTeam(
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Team as json to create a new Team.", required = true) @RequestBody TeamDto teamDto) {
+ public ResponseEntity createTeam(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Team as json to create a new Team.", required = true) @RequestBody TeamDto teamDto) {
Team createdTeam = teamAuthorizationService.createEntity(teamMapper.toTeam(teamDto));
- return ResponseEntity.status(HttpStatus.CREATED).body(teamMapper.toDto(createdTeam));
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(teamMapper.toDto(createdTeam));
}
@Operation(summary = "Update Team", description = "Update a Team by ID.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Updated Team in db.", content = {
- @Content(mediaType = "application/json", schema = @Schema(allOf = { TeamDto.class })) }),
- @ApiResponse(responseCode = "401", description = "Not authorized to update a Team", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find a Team with a specified ID to update.", content = @Content),
- @ApiResponse(responseCode = "422", description = "Can't update Team since Team was updated or deleted by another user.", content = @Content) })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Updated Team in db.", content = {@Content(mediaType = "application/json", schema = @Schema(allOf = {TeamDto.class}))}), @ApiResponse(responseCode = "401", description = "Not authorized to update a Team", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find a Team with a specified ID to update.", content = @Content), @ApiResponse(responseCode = "422", description = "Can't update Team since Team was updated or deleted by another user.", content = @Content)})
@PutMapping("/{id}")
- public ResponseEntity updateTeam(
- @Parameter(description = "The ID for updating a Team.", required = true) @PathVariable long id,
- @RequestBody TeamDto teamDto) {
+ public ResponseEntity updateTeam(@Parameter(description = "The ID for updating a Team.", required = true) @PathVariable long id, @RequestBody TeamDto teamDto) {
Team updatedTeam = teamAuthorizationService.updateEntity(teamMapper.toTeam(teamDto), id);
- return ResponseEntity.status(OK).body(teamMapper.toDto(updatedTeam));
+ return ResponseEntity.status(OK)
+ .body(teamMapper.toDto(updatedTeam));
}
@Operation(summary = "Delete Team by ID", description = "Delete Team by ID")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Deleted Team by ID"),
- @ApiResponse(responseCode = "401", description = "Not authorized to delete an Team", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Deleted Team by ID"), @ApiResponse(responseCode = "401", description = "Not authorized to delete an Team", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID")})
@DeleteMapping("/{id}")
- public void deleteTeamById(
- @Parameter(description = "The ID of an Team to delete it.", required = true) @PathVariable long id) {
+ public void deleteTeamById(@Parameter(description = "The ID of an Team to delete it.", required = true) @PathVariable long id) {
teamAuthorizationService.deleteEntity(id);
}
@Operation(summary = "Add users to a team", description = "Add users to a team")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Added users to team"),
- @ApiResponse(responseCode = "401", description = "Not authorized to add users to the team", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Added users to team"), @ApiResponse(responseCode = "401", description = "Not authorized to add users to the team", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID")})
@PutMapping("/{id}/addusers")
- public void addUsersToTeam(
- @Parameter(description = "The ID of an Team to add to users to it.", required = true) @PathVariable long id,
- @RequestBody List userDtoList) {
- var userIds = userDtoList.stream().map(UserDto::id).toList();
+ public void addUsersToTeam(@Parameter(description = "The ID of an Team to add to users to it.", required = true) @PathVariable long id, @RequestBody List userDtoList) {
+ var userIds = userDtoList.stream()
+ .map(UserDto::id)
+ .toList();
teamAuthorizationService.addUsersToTeam(id, userIds);
}
@Operation(summary = "Remove User from Team", description = "Remove User with given UserID from Team")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Removed User from Team"),
- @ApiResponse(responseCode = "401", description = "Not authorized to remove user from team", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Removed User from Team"), @ApiResponse(responseCode = "401", description = "Not authorized to remove user from team", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID")})
@PutMapping("/{id}/user/{userId}/removeuser")
- public void removeUserFromTeam(
- @Parameter(description = "The ID of an team to remove the user from it.", required = true) @PathVariable long id,
- @Parameter(description = "The User ID to remove from the team.", required = true) @PathVariable long userId) {
+ public void removeUserFromTeam(@Parameter(description = "The ID of an team to remove the user from it.", required = true) @PathVariable long id, @Parameter(description = "The User ID to remove from the team.", required = true) @PathVariable long userId) {
teamAuthorizationService.removeUserFromTeam(id, userId);
}
- @Operation(summary = "Update or add team membership", description = "If user is already member of this team, isAdmin is set. otherwise new team membership "
- + "is added with isAdmin true or false")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Update or add team membership"),
- @ApiResponse(responseCode = "401", description = "Not authorized to update or add team membership", content = @Content),
- @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
+ @Operation(summary = "Update or add team membership", description = "If user is already member of this team, isAdmin is set. otherwise new team membership " + "is added with isAdmin true or false")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Update or add team membership"), @ApiResponse(responseCode = "401", description = "Not authorized to update or add team membership", content = @Content), @ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID")})
@PutMapping("/{id}/user/{userId}/updateaddteammembership/{isAdmin}")
- public void updateOrAddTeamMembership(
- @Parameter(description = "The ID of an team to update or add membership", required = true) @PathVariable long id,
- @Parameter(description = "The User ID to update or add membership", required = true) @PathVariable long userId,
- @Parameter(description = "The parameter if user should be admin or not", required = true) @PathVariable boolean isAdmin) {
+ public void updateOrAddTeamMembership(@Parameter(description = "The ID of an team to update or add membership", required = true) @PathVariable long id, @Parameter(description = "The User ID to update or add membership", required = true) @PathVariable long userId, @Parameter(description = "The parameter if user should be admin or not", required = true) @PathVariable boolean isAdmin) {
teamAuthorizationService.updateOrAddTeamMembership(id, userId, isAdmin);
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/controller/UserController.java b/backend/src/main/java/ch/puzzle/okr/controller/UserController.java
index bc6d772a9a..009510422d 100644
--- a/backend/src/main/java/ch/puzzle/okr/controller/UserController.java
+++ b/backend/src/main/java/ch/puzzle/okr/controller/UserController.java
@@ -1,16 +1,13 @@
package ch.puzzle.okr.controller;
+import java.util.List;
+
import ch.puzzle.okr.dto.NewUserDto;
import ch.puzzle.okr.dto.UserDto;
import ch.puzzle.okr.mapper.UserMapper;
import ch.puzzle.okr.service.authorization.AuthorizationService;
import ch.puzzle.okr.service.authorization.UserAuthorizationService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -19,7 +16,12 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import java.util.List;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+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;
@RestController
@RequestMapping("api/v1/users")
@@ -29,58 +31,51 @@ public class UserController {
private final AuthorizationService authorizationService;
private final UserMapper userMapper;
- public UserController(UserAuthorizationService userAuthorizationService, AuthorizationService authorizationService,
- UserMapper userMapper) {
+ public UserController(UserAuthorizationService userAuthorizationService, AuthorizationService authorizationService, UserMapper userMapper) {
this.userAuthorizationService = userAuthorizationService;
this.authorizationService = authorizationService;
this.userMapper = userMapper;
}
@Operation(summary = "Get Users", description = "Get all Users from db.")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned all Users.", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned all Users.", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class))}),})
@GetMapping
public List getAllUsers() {
- return userAuthorizationService.getAllUsers().stream().map(userMapper::toDto).toList();
+ return userAuthorizationService.getAllUsers()
+ .stream()
+ .map(userMapper::toDto)
+ .toList();
}
@Operation(summary = "Get Current User", description = "Get all current logged in user.")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Returned current logged in user.", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned current logged in user.", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class))}),})
@GetMapping(path = "/current")
public UserDto getCurrentUser() {
- var currentUser = this.authorizationService.updateOrAddAuthorizationUser().user();
+ var currentUser = this.authorizationService.updateOrAddAuthorizationUser()
+ .user();
return userMapper.toDto(currentUser);
}
@Operation(summary = "Get User by ID", description = "Get user by given ID.")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned user", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned user", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class))}),})
@GetMapping(path = "/{id}")
- public UserDto getUserById(
- @Parameter(description = "The ID for requested user.", required = true) @PathVariable long id) {
+ public UserDto getUserById(@Parameter(description = "The ID for requested user.", required = true) @PathVariable long id) {
var user = this.userAuthorizationService.getById(id);
return userMapper.toDto(user);
}
@Operation(summary = "Set OKR Champion property for user", description = "Sets the property okrChampion of user to true or false")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned user", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned user", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class))}),})
@PutMapping(path = "/{id}/isokrchampion/{isOkrChampion}")
- public UserDto setOkrChampion(
- @Parameter(description = "The ID for requested user.", required = true) @PathVariable long id,
- @Parameter(description = "okrChampion property of user is set to this flag.", required = true) @PathVariable boolean isOkrChampion) {
+ public UserDto setOkrChampion(@Parameter(description = "The ID for requested user.", required = true) @PathVariable long id, @Parameter(description = "okrChampion property of user is set to this flag.", required = true) @PathVariable boolean isOkrChampion) {
var user = this.userAuthorizationService.setIsOkrChampion(id, isOkrChampion);
return userMapper.toDto(user);
}
@Operation(summary = "Create users", description = "Creates a user entity for every user in the method body")
- @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned users", content = {
- @Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returned users", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class))}),})
@PostMapping(path = "/createall")
- public List createUsers(
- @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The users to create", required = true) @RequestBody List newUserDtoList) {
+ public List createUsers(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The users to create", required = true) @RequestBody List newUserDtoList) {
var createdUsers = this.userAuthorizationService.createUsers(userMapper.toUserList(newUserDtoList));
return userMapper.toDtos(createdUsers);
}
diff --git a/backend/src/main/java/ch/puzzle/okr/deserializer/CheckInDeserializer.java b/backend/src/main/java/ch/puzzle/okr/deserializer/CheckInDeserializer.java
index f7442819cb..36ea9cf674 100644
--- a/backend/src/main/java/ch/puzzle/okr/deserializer/CheckInDeserializer.java
+++ b/backend/src/main/java/ch/puzzle/okr/deserializer/CheckInDeserializer.java
@@ -1,21 +1,23 @@
package ch.puzzle.okr.deserializer;
+import java.io.IOException;
+
import ch.puzzle.okr.dto.checkin.CheckInDto;
import ch.puzzle.okr.dto.checkin.CheckInMetricDto;
import ch.puzzle.okr.dto.checkin.CheckInOrdinalDto;
import ch.puzzle.okr.models.keyresult.KeyResult;
import ch.puzzle.okr.service.business.KeyResultBusinessService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ResponseStatusException;
+
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ResponseStatusException;
-
-import java.io.IOException;
import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_METRIC;
import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_ORDINAL;
@@ -30,12 +32,13 @@ public CheckInDeserializer(KeyResultBusinessService keyResultBusinessService) {
}
@Override
- public CheckInDto deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
- throws IOException, JacksonException {
+ public CheckInDto deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException,
+ JacksonException {
ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();
ObjectNode root = mapper.readTree(jsonParser);
if (root.has("keyResultId")) {
- KeyResult keyResultOfCheckIn = keyResultBusinessService.getEntityById(root.get("keyResultId").asLong());
+ KeyResult keyResultOfCheckIn = keyResultBusinessService.getEntityById(root.get("keyResultId")
+ .asLong());
if (KEY_RESULT_TYPE_METRIC.equals(keyResultOfCheckIn.getKeyResultType())) {
return mapper.readValue(root.toString(), CheckInMetricDto.class);
} else if (KEY_RESULT_TYPE_ORDINAL.equals(keyResultOfCheckIn.getKeyResultType())) {
@@ -45,7 +48,7 @@ public CheckInDto deserialize(JsonParser jsonParser, DeserializationContext dese
}
} else {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
- "missing keyResult ID to deserialize checkIn DTO");
+ "missing keyResult ID to deserialize checkIn DTO");
}
}
}
diff --git a/backend/src/main/java/ch/puzzle/okr/deserializer/KeyResultDeserializer.java b/backend/src/main/java/ch/puzzle/okr/deserializer/KeyResultDeserializer.java
index d873168391..0e31909646 100644
--- a/backend/src/main/java/ch/puzzle/okr/deserializer/KeyResultDeserializer.java
+++ b/backend/src/main/java/ch/puzzle/okr/deserializer/KeyResultDeserializer.java
@@ -1,33 +1,38 @@
package ch.puzzle.okr.deserializer;
+import java.io.IOException;
+
import ch.puzzle.okr.dto.keyresult.KeyResultDto;
import ch.puzzle.okr.dto.keyresult.KeyResultMetricDto;
import ch.puzzle.okr.dto.keyresult.KeyResultOrdinalDto;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.server.ResponseStatusException;
+
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.server.ResponseStatusException;
-
-import java.io.IOException;
import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_METRIC;
import static ch.puzzle.okr.Constants.KEY_RESULT_TYPE_ORDINAL;
public class KeyResultDeserializer extends JsonDeserializer {
@Override
- public KeyResultDto deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
- throws IOException, JacksonException {
+ public KeyResultDto deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException,
+ JacksonException {
ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();
ObjectNode root = mapper.readTree(jsonParser);
String keyResultAttribute = "keyResultType";
- if (root.has(keyResultAttribute) && root.get(keyResultAttribute).asText().equals(KEY_RESULT_TYPE_METRIC)) {
+ if (root.has(keyResultAttribute) && root.get(keyResultAttribute)
+ .asText()
+ .equals(KEY_RESULT_TYPE_METRIC)) {
return mapper.readValue(root.toString(), KeyResultMetricDto.class);
- } else if (root.has(keyResultAttribute)
- && root.get(keyResultAttribute).asText().equals(KEY_RESULT_TYPE_ORDINAL)) {
+ } else if (root.has(keyResultAttribute) && root.get(keyResultAttribute)
+ .asText()
+ .equals(KEY_RESULT_TYPE_ORDINAL)) {
return mapper.readValue(root.toString(), KeyResultOrdinalDto.class);
}
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "unsupported keyResult DTO to deserialize");
diff --git a/backend/src/main/java/ch/puzzle/okr/dto/ActionDto.java b/backend/src/main/java/ch/puzzle/okr/dto/ActionDto.java
index 2cfe1d6836..2208107c6c 100644
--- a/backend/src/main/java/ch/puzzle/okr/dto/ActionDto.java
+++ b/backend/src/main/java/ch/puzzle/okr/dto/ActionDto.java
@@ -1,5 +1,6 @@
package ch.puzzle.okr.dto;
-public record ActionDto(Long id, int version, String action, int priority, boolean isChecked, Long keyResultId,
- boolean writeable) {
+public record ActionDto(
+ Long id, int version, String action, int priority, boolean isChecked, Long keyResultId, boolean writeable
+) {
}
diff --git a/backend/src/main/java/ch/puzzle/okr/dto/ClientConfigDto.java b/backend/src/main/java/ch/puzzle/okr/dto/ClientConfigDto.java
index 702a4de5c4..9503c652a8 100644
--- a/backend/src/main/java/ch/puzzle/okr/dto/ClientConfigDto.java
+++ b/backend/src/main/java/ch/puzzle/okr/dto/ClientConfigDto.java
@@ -2,6 +2,8 @@
import java.util.Map;
-public record ClientConfigDto(String activeProfile, String issuer, String clientId, String favicon, String logo,
- String triangles, String backgroundLogo, String title, Map customStyles) {
+public record ClientConfigDto(
+ String activeProfile, String issuer, String clientId, String favicon, String logo, String triangles,
+ String backgroundLogo, String title, Map customStyles
+) {
}
diff --git a/backend/src/main/java/ch/puzzle/okr/dto/ErrorDto.java b/backend/src/main/java/ch/puzzle/okr/dto/ErrorDto.java
index 07ad03f1ae..41c88da2f9 100644
--- a/backend/src/main/java/ch/puzzle/okr/dto/ErrorDto.java
+++ b/backend/src/main/java/ch/puzzle/okr/dto/ErrorDto.java
@@ -1,9 +1,9 @@
package ch.puzzle.okr.dto;
-import ch.puzzle.okr.ErrorKey;
-
import java.util.List;
+import ch.puzzle.okr.ErrorKey;
+
public record ErrorDto(String errorKey, List params) {
public static ErrorDto of(ErrorKey errorKey, String param) {
@@ -15,6 +15,9 @@ public static ErrorDto of(ErrorKey errorKey, List