Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feature/844-demo-inst…
Browse files Browse the repository at this point in the history
…ance
  • Loading branch information
clean-coder committed May 16, 2024
2 parents e1bdd45 + f33b1f6 commit 4f32205
Show file tree
Hide file tree
Showing 38 changed files with 1,664 additions and 774 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/addIssueToProject.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
name: Add issue to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v0.6.1
- uses: actions/add-to-project@v1.0.1
with:
project-url: https://github.com/orgs/puzzle/projects/3
github-token: ${{ secrets.ADD_ISSUE_TO_PROJECT_CLASSIC }}
14 changes: 7 additions & 7 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<parent>
<groupId>ch.puzzle.okr</groupId>
<artifactId>parent</artifactId>
<version>2.0.91-SNAPSHOT</version>
<version>2.0.114-SNAPSHOT</version>
</parent>

<artifactId>backend</artifactId>
<version>2.0.91-SNAPSHOT</version>
<version>2.0.114-SNAPSHOT</version>
<name>backend</name>
<description>Puzzle OKR Tool</description>

Expand Down Expand Up @@ -54,17 +54,17 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.4.0</version>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.10.0</version>
<version>10.11.1</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
<version>10.10.0</version>
<version>10.11.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
Expand All @@ -78,7 +78,7 @@
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>1.2.1</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -102,7 +102,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<version>0.8.12</version>
<configuration>
<excludes>
<exclude>ch/puzzle/okr/models/**</exclude>
Expand Down
3 changes: 3 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/OkrApplication.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package ch.puzzle.okr;

import ch.puzzle.okr.service.clientconfig.ClientCustomizationProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties(ClientCustomizationProperties.class)
public class OkrApplication {
public static void main(String[] args) {
SpringApplication.run(OkrApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package ch.puzzle.okr.controller;

import ch.puzzle.okr.service.ClientConfigService;
import ch.puzzle.okr.dto.ClientConfigDto;
import ch.puzzle.okr.service.clientconfig.ClientConfigService;
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.Map;

@RestController
@RequestMapping("/config")
public class ClientConfigController {
Expand All @@ -20,7 +19,7 @@ public ClientConfigController(ClientConfigService configService) {
}

@GetMapping
public ResponseEntity<Map<String, String>> getConfig() {
public ResponseEntity<ClientConfigDto> getConfig() {
return ResponseEntity.status(HttpStatus.OK).body(configService.getConfigBasedOnActiveEnv());
}
}
7 changes: 7 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/dto/ClientConfigDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ch.puzzle.okr.dto;

import java.util.HashMap;

public record ClientConfigDto(String activeProfile, String issuer, String clientId, String favicon, String logo,
String title, HashMap<String, String> customStyles) {
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package ch.puzzle.okr.service.business;

import ch.puzzle.okr.ErrorKey;
import ch.puzzle.okr.exception.OkrResponseStatusException;
import ch.puzzle.okr.models.Quarter;
import ch.puzzle.okr.service.persistence.QuarterPersistenceService;
import ch.puzzle.okr.service.validation.QuarterValidationService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.temporal.IsoFields;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class QuarterBusinessService {
Expand All @@ -22,6 +23,12 @@ public class QuarterBusinessService {
private final QuarterPersistenceService quarterPersistenceService;
private final QuarterValidationService validator;

@Value("${okr.quarter.business.year.start}")
private int quarterStart;

@Value("${okr.quarter.label.format}")
private String quarterFormat;

public QuarterBusinessService(QuarterPersistenceService quarterPersistenceService,
QuarterValidationService validator) {
this.quarterPersistenceService = quarterPersistenceService;
Expand Down Expand Up @@ -53,31 +60,65 @@ private String padWithZeros(int amount, int number) {
return String.format(format, number);
}

private String createQuarterLabel(YearMonth yearMonth) {
// generation of quarter is two quarter in advance therefore the current quarter of the year corresponds with
// the business quarter we want to generate
return String.format("GJ %s/%s-Q%x", shortenYear(yearMonth.getYear()), shortenYear(yearMonth.getYear() + 1),
yearMonth.get(IsoFields.QUARTER_OF_YEAR));
private String createQuarterLabel(YearMonth startOfQuarter, int quarter) {
int yearStart = getStartOfBusinessYear(startOfQuarter, quarter);
int yearEnd = yearStart + 1;

return StringUtils.replaceEach(quarterFormat, new String[] { "xxxx", "yyyy", "xx", "yy", "zz" },
new String[] { String.valueOf(yearStart), String.valueOf(yearEnd), shortenYear(yearStart),
shortenYear(yearEnd), String.valueOf(quarter) });
}

private int getStartOfBusinessYear(YearMonth startOfQuarter, int quarter) {
// Subtract the amount of months, based on the quarter we are in
// i.e. quarter=2, subtract (2 - 1) * 3 = 3 Months to get start
return startOfQuarter.minusMonths((quarter - 1) * 3L).getYear();
}

private void generateQuarter(YearMonth yearMonth) {
Quarter quarter = Quarter.Builder.builder().withLabel(createQuarterLabel(yearMonth))
.withStartDate(yearMonth.plusMonths(4).atDay(1)).withEndDate(yearMonth.plusMonths(6).atEndOfMonth())
.build();
private void generateQuarter(LocalDateTime start, String label) {
YearMonth yearMonth = YearMonth.from(start);
Quarter quarter = Quarter.Builder.builder().withLabel(label).withStartDate(start.toLocalDate())
.withEndDate(yearMonth.plusMonths(2).atEndOfMonth()).build();
validator.validateOnGeneration(quarter);
quarterPersistenceService.save(quarter);
}

public YearMonth getCurrentYearMonth() {
private boolean inLastMonthOfQuarter(int currentQuarter, int nextQuarter) {
// If the quarter 4 months in the future and the current are exactly 2 apart,
// we are in the final month of the current quarter. This works for all 4 cases:
// 1 -> 3 | 2 -> 4 | 3 -> 1 | 4 -> 2
return Math.abs(nextQuarter - currentQuarter) == 2;
}

YearMonth getCurrentYearMonth() {
return YearMonth.now();
}

Map<Integer, Integer> generateQuarters() {
Map<Integer, Integer> quarters = new HashMap<>();
int quarterIndexZeroBased = quarterStart - 1;
for (int i = 0; i < 12; i++) {
int monthIndexZeroBased = (i + quarterIndexZeroBased) % 12;
int quarterZeroBased = i / 3;
quarters.put(monthIndexZeroBased + 1, quarterZeroBased + 1);
}
return quarters;
}

@Scheduled(cron = "0 59 23 L * ?") // Cron expression for 23:59:00 on the last day of every month
public void scheduledGenerationQuarters() {
YearMonth yearMonth = getCurrentYearMonth();
if (yearMonth.getMonthValue() % 3 == 0) {
Map<Integer, Integer> quarters = generateQuarters();
YearMonth currentYearMonth = getCurrentYearMonth();
YearMonth nextQuarterYearMonth = currentYearMonth.plusMonths(4);

int currentQuarter = quarters.get(currentYearMonth.getMonthValue());
int nextQuarter = quarters.get(nextQuarterYearMonth.getMonthValue());

// If we are in the last month of a quarter, generate the next quarter
if (inLastMonthOfQuarter(currentQuarter, nextQuarter)) {
logger.info("Generated quarters on last day of month");
generateQuarter(yearMonth);
String label = createQuarterLabel(nextQuarterYearMonth, nextQuarter);
generateQuarter(nextQuarterYearMonth.atDay(1).atStartOfDay(), label);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ch.puzzle.okr.service.clientconfig;

import ch.puzzle.okr.dto.ClientConfigDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class ClientConfigService {

@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuer;

@Value("${spring.profiles.active}")
private String activeProfile;

@Value("${spring.security.oauth2.resourceserver.opaquetoken.client-id}")
private String clientId;

private final ClientCustomizationProperties clientCustomizationProperties;

public ClientConfigService(ClientCustomizationProperties clientCustomizationProperties) {
this.clientCustomizationProperties = clientCustomizationProperties;
}

public ClientConfigDto getConfigBasedOnActiveEnv() {
return new ClientConfigDto(activeProfile, issuer, clientId, this.clientCustomizationProperties.getFavicon(),
this.clientCustomizationProperties.getLogo(), this.clientCustomizationProperties.getTitle(),
this.clientCustomizationProperties.getCustomStyles());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ch.puzzle.okr.service.clientconfig;

import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.HashMap;

@ConfigurationProperties("okr.clientcustomization")
public class ClientCustomizationProperties {
private String favicon;
private String logo;
private String title;
private HashMap<String, String> customStyles = new HashMap<>();

public void setCustomStyles(HashMap<String, String> customStyles) {
this.customStyles = customStyles;
}

public String getFavicon() {
return favicon;
}

public void setFavicon(String favicon) {
this.favicon = favicon;
}

public String getLogo() {
return logo;
}

public void setLogo(String logo) {
this.logo = logo;
}

public HashMap<String, String> getCustomStyles() {
return customStyles;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}
}
2 changes: 1 addition & 1 deletion backend/src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ logging.level.ch.puzzle.okr=DEBUG
logging.level.org.springframework.security=DEBUG
# server.servlet.context-path=/resource-server
# flyway fill database with data
spring.flyway.locations=classpath:db/migration,classpath:db/data-migration
spring.flyway.locations=classpath:db/migration,classpath:db/data-migration,classpath:db/callback

spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8544/realms/pitc
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8544/realms/pitc/protocol/openid-connect/certs
Expand Down
1 change: 1 addition & 0 deletions backend/src/main/resources/application-staging.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ logging.level.org.springframework=debug
spring.security.oauth2.resourceserver.opaquetoken.client-id=pitc_okr_staging

okr.user.champion.usernames=peggimann
okr.clientcustomization.customstyles.okr-topbar-background-color=#ab31ad
7 changes: 7 additions & 0 deletions backend/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,10 @@ okr.jwt.user.username=preferred_username
okr.jwt.user.firstname=given_name
okr.jwt.user.lastname=family_name
okr.jwt.user.email=email

okr.clientcustomization.favicon=assets/favicon.png
okr.clientcustomization.logo=assets/images/okr-logo.svg
okr.clientcustomization.title=Puzzle OKR

okr.quarter.business.year.start=7
okr.quarter.label.format=GJ xx/yy-Qzz
Loading

0 comments on commit 4f32205

Please sign in to comment.