diff --git a/README.md b/README.md
index de1bb5bb..2888772a 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
## Project Documents
-For other information, you can check [Wiki](https://github.com/gelecekbilimde/gelecekbilimde-backend/wiki)
+For other information, you can check [Wiki](https://gelecekbilimde.atlassian.net/wiki/spaces/GBS/overview)
Page.
---
@@ -57,3 +57,16 @@ The following command can be used to remove Docker Containers.
> directory.
> is required.
+---
+
+# Project Infrastructure
+
+## 🏛️ HexaLayered Architecture
+
+
+
+> **Reference: [HexaLayered Architecture](https://github.com/agitrubard/hexalayered-architecture)**
+
+## 📦 Package Architecture
+
+
diff --git a/documents/architecture/gb-architecture.drawio b/documents/architecture/gb-architecture.drawio
new file mode 100644
index 00000000..8fe381b7
--- /dev/null
+++ b/documents/architecture/gb-architecture.drawio
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/documents/architecture/gb-architecture.png b/documents/architecture/gb-architecture.png
new file mode 100644
index 00000000..2d5f440e
Binary files /dev/null and b/documents/architecture/gb-architecture.png differ
diff --git a/documents/architecture/package-architecture-example.drawio b/documents/architecture/package-architecture-example.drawio
new file mode 100644
index 00000000..c0391e06
--- /dev/null
+++ b/documents/architecture/package-architecture-example.drawio
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/documents/architecture/package-architecture-example.png b/documents/architecture/package-architecture-example.png
new file mode 100644
index 00000000..1e399168
Binary files /dev/null and b/documents/architecture/package-architecture-example.png differ
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/config/SecurityConfiguration.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/config/SecurityConfiguration.java
index 3fde2970..71dca840 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/config/SecurityConfiguration.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/config/SecurityConfiguration.java
@@ -43,15 +43,20 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity,
httpSecurity.cors(customizer -> customizer.configurationSource(corsConfigurationSource()))
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(customizer -> customizer
- .requestMatchers(HttpMethod.GET, "/public/**").permitAll()
- .requestMatchers("/api/v1/version", "/api/v1/auth/**", "/api/v1/category/**")
+ .requestMatchers(HttpMethod.GET, "/public/**")
.permitAll()
- .requestMatchers(HttpMethod.GET, "/api/v1/users/*/followers", "/api/v1/users/*/followings")
+ .requestMatchers("/api/v1/auth/**")
+ .permitAll()
+ .requestMatchers("/api/v1/categories/summary")
+ .permitAll()
+ .requestMatchers(HttpMethod.GET, "/api/v1/user/*/followers", "/api/v1/user/*/followings")
.permitAll()
.anyRequest()
- .authenticated())
+ .authenticated()
+ )
.sessionManagement(customizer -> customizer
- .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ )
.addFilterBefore(bearerTokenAuthenticationFilter, BearerTokenAuthenticationFilter.class);
return httpSecurity.build();
@@ -71,4 +76,5 @@ CorsConfigurationSource corsConfigurationSource() {
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/AlreadyRegisteredException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/AlreadyRegisteredException.java
deleted file mode 100644
index 7aeb0370..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/AlreadyRegisteredException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.gelecekbilimde.scienceplatform.auth.exception;
-
-import java.io.Serial;
-
-public class AlreadyRegisteredException extends RuntimeException {
-
- @Serial
- private static final long serialVersionUID = -8120776112921535480L;
-
- public AlreadyRegisteredException(String email) {
- super("This user is already registered" + email);
- }
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairConversionException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairConversionException.java
index 183d436c..edd1de56 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairConversionException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairConversionException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class KeyPairConversionException extends AbstractServerException {
+public final class KeyPairConversionException extends AbstractServerException {
@Serial
- private static final long serialVersionUID = -714864829639781798L;
+ private static final long serialVersionUID = 304959574320527271L;
public KeyPairConversionException(Throwable cause) {
super("error occurred while converting key pair", cause);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairGenerationException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairGenerationException.java
index 6cac596f..88befbd7 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairGenerationException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/KeyPairGenerationException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class KeyPairGenerationException extends AbstractServerException {
+public final class KeyPairGenerationException extends AbstractServerException {
@Serial
- private static final long serialVersionUID = 7666167175325870801L;
+ private static final long serialVersionUID = 6533777004102054133L;
public KeyPairGenerationException(Throwable cause) {
super("error occurred while generating key pair", cause);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyConcludedException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyConcludedException.java
index 2f8244ab..a52267a2 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyConcludedException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyConcludedException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class RoleApplicationAlreadyConcludedException extends AbstractConflictException {
+public final class RoleApplicationAlreadyConcludedException extends AbstractConflictException {
@Serial
- private static final long serialVersionUID = -7807528937254572325L;
+ private static final long serialVersionUID = 6963403850981238210L;
public RoleApplicationAlreadyConcludedException(String id) {
super("role application already concluded id: " + id);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyExistException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyExistException.java
index a6fd9a3c..e28ae7e4 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyExistException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationAlreadyExistException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class RoleApplicationAlreadyExistException extends AbstractConflictException {
+public final class RoleApplicationAlreadyExistException extends AbstractConflictException {
@Serial
- private static final long serialVersionUID = 3834570698226426742L;
+ private static final long serialVersionUID = 8186687324812319190L;
public RoleApplicationAlreadyExistException() {
super("user already has a role application in review");
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByIdException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByIdException.java
index 7a9c9df8..3a44b479 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByIdException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByIdException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class RoleApplicationNotFoundByIdException extends AbstractNotFoundException {
+public final class RoleApplicationNotFoundByIdException extends AbstractNotFoundException {
@Serial
- private static final long serialVersionUID = -7420720906649254998L;
+ private static final long serialVersionUID = -1036422987236610575L;
public RoleApplicationNotFoundByIdException(String id) {
super("role application does not found! id: " + id);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByUserIdAndStatusException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByUserIdAndStatusException.java
index 4f73aac0..1831a477 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByUserIdAndStatusException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleApplicationNotFoundByUserIdAndStatusException.java
@@ -5,10 +5,10 @@
import java.io.Serial;
-public class RoleApplicationNotFoundByUserIdAndStatusException extends AbstractNotFoundException {
+public final class RoleApplicationNotFoundByUserIdAndStatusException extends AbstractNotFoundException {
@Serial
- private static final long serialVersionUID = 4738260982768669235L;
+ private static final long serialVersionUID = -8360751775119161646L;
public RoleApplicationNotFoundByUserIdAndStatusException(String userId, RoleApplicationStatus status) {
super("role application not found! userId: " + userId + ", status: " + status);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleNotFoundByNameException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleNotFoundByNameException.java
index d340e190..e9a8c2d0 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleNotFoundByNameException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/RoleNotFoundByNameException.java
@@ -2,10 +2,10 @@
import java.io.Serial;
-public class RoleNotFoundByNameException extends RuntimeException {
+public final class RoleNotFoundByNameException extends RuntimeException {
@Serial
- private static final long serialVersionUID = -927147689852209182L;
+ private static final long serialVersionUID = -4700198439829934412L;
public RoleNotFoundByNameException(String name) {
super("role not found with name: " + name);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserAlreadyRegisteredException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserAlreadyRegisteredException.java
new file mode 100644
index 00000000..0b06e66f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserAlreadyRegisteredException.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.auth.exception;
+
+import org.gelecekbilimde.scienceplatform.common.exception.AbstractConflictException;
+
+import java.io.Serial;
+
+public final class UserAlreadyRegisteredException extends AbstractConflictException {
+
+ @Serial
+ private static final long serialVersionUID = -5670350199459862153L;
+
+ public UserAlreadyRegisteredException(String email) {
+ super("user already registered by " + email);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserNotVerifiedException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserNotVerifiedException.java
index 5704e161..306237c9 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserNotVerifiedException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserNotVerifiedException.java
@@ -4,10 +4,10 @@
import java.io.Serial;
-public class UserNotVerifiedException extends AbstractAuthException {
+public final class UserNotVerifiedException extends AbstractAuthException {
@Serial
- private static final long serialVersionUID = 263502105581485335L;
+ private static final long serialVersionUID = -8766975383392137276L;
public UserNotVerifiedException(String email) {
super("user not verified yet! email: " + email);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserPasswordNotValidException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserPasswordNotValidException.java
index 0f69b1f1..4f8d351b 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserPasswordNotValidException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserPasswordNotValidException.java
@@ -4,7 +4,7 @@
import java.io.Serial;
-public class UserPasswordNotValidException extends AbstractAuthException {
+public final class UserPasswordNotValidException extends AbstractAuthException {
@Serial
private static final long serialVersionUID = 359664997679732461L;
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationAlreadyCompletedException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationAlreadyCompletedException.java
index d1e03e0a..5a3c1b33 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationAlreadyCompletedException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationAlreadyCompletedException.java
@@ -2,12 +2,13 @@
import java.io.Serial;
-public class UserVerificationAlreadyCompletedException extends RuntimeException {
+public final class UserVerificationAlreadyCompletedException extends RuntimeException {
@Serial
- private static final long serialVersionUID = 3624833133483334337L;
+ private static final long serialVersionUID = 5017223706763359158L;
public UserVerificationAlreadyCompletedException() {
super("User verification is already completed!");
}
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationIsNotFoundException.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationIsNotFoundException.java
index 43a2a2b9..fd013ca3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationIsNotFoundException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/exception/UserVerificationIsNotFoundException.java
@@ -2,13 +2,13 @@
import java.io.Serial;
-public class UserVerificationIsNotFoundException extends RuntimeException {
+public final class UserVerificationIsNotFoundException extends RuntimeException {
+
@Serial
- private static final long serialVersionUID = 7045861607490841147L;
+ private static final long serialVersionUID = 3026197679369190902L;
public UserVerificationIsNotFoundException(String id) {
super("User Verification ID does not found! verificationId: " + id);
}
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Identity.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Identity.java
index 418dcc39..f05fde9a 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Identity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Identity.java
@@ -1,5 +1,6 @@
package org.gelecekbilimde.scienceplatform.auth.model;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
import org.gelecekbilimde.scienceplatform.auth.model.enums.TokenClaims;
import org.gelecekbilimde.scienceplatform.auth.util.BeanScope;
import org.springframework.context.annotation.Scope;
@@ -15,7 +16,14 @@
public class Identity {
public String getUserId() {
- return this.getJwt().getClaim("userId");
+ return this.getJwt().getClaim(TokenClaims.USER_ID.getValue());
+ }
+
+ public boolean isAdmin() {
+ final RoleName roleName = RoleName.valueOf(
+ this.getJwt().getClaim(TokenClaims.USER_ROLE.getValue())
+ );
+ return RoleName.ADMIN == roleName;
}
public boolean hasPermission(String requiredPermission) {
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/Settings.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/InvalidToken.java
similarity index 50%
rename from src/main/java/org/gelecekbilimde/scienceplatform/settings/model/Settings.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/auth/model/InvalidToken.java
index fd266589..44bfd474 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/Settings.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/InvalidToken.java
@@ -1,4 +1,4 @@
-package org.gelecekbilimde.scienceplatform.settings.model;
+package org.gelecekbilimde.scienceplatform.auth.model;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -10,13 +10,9 @@
@Setter
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
-public class Settings extends BaseDomainModel {
+public class InvalidToken extends BaseDomainModel {
- private Long settingsId;
- private String groupName;
- private String name;
- private String definition;
- private Long userId;
- private boolean hidden;
+ private Long id;
+ private String tokenId;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Role.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Role.java
index 0a552592..c9a957c0 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Role.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/Role.java
@@ -17,4 +17,11 @@ public class Role {
private RoleStatus status;
private List permissions;
+
+ public List getPermissionNames() {
+ return permissions.stream()
+ .map(PermissionEntity::getName)
+ .toList();
+ }
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplication.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplication.java
index 56f3029d..9cbe77c5 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplication.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplication.java
@@ -1,5 +1,6 @@
package org.gelecekbilimde.scienceplatform.auth.model;
+import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
@@ -7,6 +8,7 @@
@Getter
@Setter
+@Builder
public class RoleApplication {
private String id;
@@ -14,4 +16,22 @@ public class RoleApplication {
private Role role;
private RoleApplicationStatus status;
+
+ public boolean isConcluded() {
+ return this.status == RoleApplicationStatus.APPROVED || this.status == RoleApplicationStatus.REJECTED;
+ }
+
+
+ public void cancel() {
+ this.status = RoleApplicationStatus.CANCELLED;
+ }
+
+ public void approve() {
+ this.status = RoleApplicationStatus.APPROVED;
+ }
+
+ public void reject() {
+ this.status = RoleApplicationStatus.REJECTED;
+ }
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationAbstractFilter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationAbstractFilter.java
new file mode 100644
index 00000000..32726423
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationAbstractFilter.java
@@ -0,0 +1,39 @@
+package org.gelecekbilimde.scienceplatform.auth.model;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
+import org.gelecekbilimde.scienceplatform.common.model.BaseFilter;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Set;
+
+@Getter
+@Setter
+public class RoleApplicationAbstractFilter implements BaseFilter {
+
+ protected Set statuses;
+
+
+ @Override
+ public Specification toSpecification() {
+
+ Specification specification = Specification.where(null);
+
+ if (!CollectionUtils.isEmpty(this.statuses)) {
+
+ Specification statusSpecification = this.statuses.stream()
+ .map(status -> (Specification) (root, query, criteriaBuilder) ->
+ criteriaBuilder.equal(root.get("status"), status))
+ .reduce(Specification::or)
+ .orElse(null);
+
+ specification = specification.and(statusSpecification);
+ }
+
+ return specification;
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationFilter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationFilter.java
index 42b614d9..41b56992 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationFilter.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleApplicationFilter.java
@@ -2,38 +2,8 @@
import lombok.Getter;
import lombok.Setter;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
-import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
-import org.gelecekbilimde.scienceplatform.common.model.BaseFilter;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Set;
@Getter
@Setter
-public class RoleApplicationFilter implements BaseFilter {
-
- private Set statuses;
-
-
- @Override
- public Specification toSpecification() {
-
- Specification specification = Specification.where(null);
-
- if (!CollectionUtils.isEmpty(this.statuses)) {
-
- Specification statusSpecification = this.statuses.stream()
- .map(status -> (Specification) (root, query, criteriaBuilder) ->
- criteriaBuilder.equal(root.get("status"), status))
- .reduce(Specification::or)
- .orElse(null);
-
- specification = specification.and(statusSpecification);
- }
-
- return specification;
- }
-
+public class RoleApplicationFilter extends RoleApplicationAbstractFilter {
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleSelfApplicationFilter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleSelfApplicationFilter.java
index 9b671790..87e829d3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleSelfApplicationFilter.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/RoleSelfApplicationFilter.java
@@ -4,19 +4,14 @@
import lombok.Getter;
import lombok.Setter;
import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
-import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
-import org.gelecekbilimde.scienceplatform.common.model.BaseFilter;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
-import java.util.Set;
-
@Getter
@Setter
@Builder
-public class RoleSelfApplicationFilter implements BaseFilter {
+public class RoleSelfApplicationFilter extends RoleApplicationAbstractFilter {
- private Set statuses;
private User user;
@Getter
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/AuthorRequestEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/AuthorRequestEntity.java
deleted file mode 100644
index 9869f889..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/AuthorRequestEntity.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.gelecekbilimde.scienceplatform.auth.model.entity;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-import org.gelecekbilimde.scienceplatform.auth.model.enums.Role;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-
-@Data
-@SuperBuilder
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "gb_author_request")
-public class AuthorRequestEntity {
-
- @Id
- @Column(name = "ID")
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @OneToOne
- private UserEntity user;
-
- private Role requestRoleName;
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleApplicationEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleApplicationEntity.java
index 806e329b..914fc2e9 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleApplicationEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleApplicationEntity.java
@@ -45,22 +45,4 @@ public class RoleApplicationEntity extends BaseEntity {
@Column(name = "status")
private RoleApplicationStatus status;
-
- public boolean isConcluded() {
- return this.status == RoleApplicationStatus.APPROVED || this.status == RoleApplicationStatus.REJECTED;
- }
-
-
- public void cancel() {
- this.status = RoleApplicationStatus.CANCELLED;
- }
-
- public void approve() {
- this.status = RoleApplicationStatus.APPROVED;
- }
-
- public void reject() {
- this.status = RoleApplicationStatus.REJECTED;
- }
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleEntity.java
index 180720fa..4ef9a3f3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/entity/RoleEntity.java
@@ -16,6 +16,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleStatus;
import org.gelecekbilimde.scienceplatform.common.model.entity.BaseEntity;
@@ -35,8 +36,9 @@ public class RoleEntity extends BaseEntity {
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
+ @Enumerated(EnumType.STRING)
@Column(name = "name")
- private String name;
+ private RoleName name;
@Column(name = "description")
private String description;
@@ -53,11 +55,4 @@ public class RoleEntity extends BaseEntity {
)
private List permissions;
-
- public List getPermissionNames() {
- return permissions.stream()
- .map(PermissionEntity::getName)
- .toList();
- }
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/enums/Role.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/enums/Role.java
deleted file mode 100644
index 5ae9dac5..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/enums/Role.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.gelecekbilimde.scienceplatform.auth.model.enums;
-
-public enum Role {
- GUEST,
- USER,
- AUTHOR,
- MODERATOR,
- ADMIN
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/InvalidTokenToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/InvalidTokenToEntityMapper.java
new file mode 100644
index 00000000..e6d15461
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/InvalidTokenToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.auth.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.auth.model.InvalidToken;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.InvalidTokenEntity;
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface InvalidTokenToEntityMapper extends BaseMapper {
+
+ static InvalidTokenToEntityMapper initialize() {
+ return Mappers.getMapper(InvalidTokenToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleApplicationToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleApplicationToEntityMapper.java
new file mode 100644
index 00000000..3be6a13c
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleApplicationToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.auth.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface RoleApplicationToEntityMapper extends BaseMapper {
+
+ static RoleApplicationToEntityMapper initialize() {
+ return Mappers.getMapper(RoleApplicationToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleEntityToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleEntityToDomainMapper.java
new file mode 100644
index 00000000..41c3c4c2
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/mapper/RoleEntityToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.auth.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleEntity;
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface RoleEntityToDomainMapper extends BaseMapper {
+
+ static RoleEntityToDomainMapper initialize() {
+ return Mappers.getMapper(RoleEntityToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenReadPort.java
new file mode 100644
index 00000000..e42b271d
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenReadPort.java
@@ -0,0 +1,7 @@
+package org.gelecekbilimde.scienceplatform.auth.port;
+
+public interface InvalidTokenReadPort {
+
+ boolean existsByTokenId(String tokenId);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenSavePort.java
new file mode 100644
index 00000000..075f7971
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/InvalidTokenSavePort.java
@@ -0,0 +1,11 @@
+package org.gelecekbilimde.scienceplatform.auth.port;
+
+import org.gelecekbilimde.scienceplatform.auth.model.InvalidToken;
+
+import java.util.List;
+
+public interface InvalidTokenSavePort {
+
+ void saveAll(List invalidTokens);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationReadPort.java
new file mode 100644
index 00000000..1036e57f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationReadPort.java
@@ -0,0 +1,21 @@
+package org.gelecekbilimde.scienceplatform.auth.port;
+
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplicationAbstractFilter;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+
+import java.util.Optional;
+
+public interface RoleApplicationReadPort {
+
+ BasePage findAll(BasePageable basePageable, RoleApplicationAbstractFilter filter);
+
+ Optional findById(String id);
+
+ Optional findByUserIdAndStatus(String userId, RoleApplicationStatus status);
+
+ boolean existsByUserIdAndStatus(String userId, RoleApplicationStatus status);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationSavePort.java
new file mode 100644
index 00000000..e161d977
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleApplicationSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.auth.port;
+
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
+
+public interface RoleApplicationSavePort {
+
+ RoleApplication save(RoleApplication roleApplication);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleReadPort.java
new file mode 100644
index 00000000..5aa3976d
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/RoleReadPort.java
@@ -0,0 +1,12 @@
+package org.gelecekbilimde.scienceplatform.auth.port;
+
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
+
+import java.util.Optional;
+
+public interface RoleReadPort {
+
+ Optional findByName(RoleName name);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/InvalidTokenAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/InvalidTokenAdapter.java
new file mode 100644
index 00000000..ade7b24f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/InvalidTokenAdapter.java
@@ -0,0 +1,36 @@
+package org.gelecekbilimde.scienceplatform.auth.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.auth.model.InvalidToken;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.InvalidTokenEntity;
+import org.gelecekbilimde.scienceplatform.auth.model.mapper.InvalidTokenToEntityMapper;
+import org.gelecekbilimde.scienceplatform.auth.port.InvalidTokenReadPort;
+import org.gelecekbilimde.scienceplatform.auth.port.InvalidTokenSavePort;
+import org.gelecekbilimde.scienceplatform.auth.repository.InvalidTokenRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+class InvalidTokenAdapter implements InvalidTokenReadPort, InvalidTokenSavePort {
+
+ private final InvalidTokenRepository invalidTokenRepository;
+
+
+ private final InvalidTokenToEntityMapper invalidTokenToEntityMapper = InvalidTokenToEntityMapper.initialize();
+
+
+ @Override
+ public boolean existsByTokenId(final String tokenId) {
+ return invalidTokenRepository.existsByTokenId(tokenId);
+ }
+
+
+ @Override
+ public void saveAll(final List invalidTokens) {
+ final List invalidTokenEntities = invalidTokenToEntityMapper.map(invalidTokens);
+ invalidTokenRepository.saveAll(invalidTokenEntities);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleAdapter.java
new file mode 100644
index 00000000..be21626e
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleAdapter.java
@@ -0,0 +1,29 @@
+package org.gelecekbilimde.scienceplatform.auth.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
+import org.gelecekbilimde.scienceplatform.auth.model.mapper.RoleEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleReadPort;
+import org.gelecekbilimde.scienceplatform.auth.repository.RoleRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class RoleAdapter implements RoleReadPort {
+
+ private final RoleRepository roleRepository;
+
+
+ private final RoleEntityToDomainMapper roleEntityToDomainMapper = RoleEntityToDomainMapper.initialize();
+
+
+ @Override
+ public Optional findByName(RoleName name) {
+ return roleRepository.findByName(name)
+ .map(roleEntityToDomainMapper::map);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleApplicationAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleApplicationAdapter.java
new file mode 100644
index 00000000..8e01abe7
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/port/adapter/RoleApplicationAdapter.java
@@ -0,0 +1,90 @@
+package org.gelecekbilimde.scienceplatform.auth.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
+import org.gelecekbilimde.scienceplatform.auth.model.RoleApplicationAbstractFilter;
+import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
+import org.gelecekbilimde.scienceplatform.auth.model.mapper.RoleApplicationEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.auth.model.mapper.RoleApplicationToEntityMapper;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationReadPort;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationSavePort;
+import org.gelecekbilimde.scienceplatform.auth.repository.RoleApplicationRepository;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class RoleApplicationAdapter implements RoleApplicationReadPort, RoleApplicationSavePort {
+
+ private final RoleApplicationRepository roleApplicationRepository;
+
+
+ private final RoleApplicationEntityToDomainMapper roleApplicationEntityToDomainMapper = RoleApplicationEntityToDomainMapper.initialize();
+ private final RoleApplicationToEntityMapper roleApplicationToEntityMapper = RoleApplicationToEntityMapper.initialize();
+
+
+ @Override
+ public BasePage findAll(final BasePageable basePageable,
+ final RoleApplicationAbstractFilter filter) {
+
+ final Pageable pageable = basePageable.toPageable();
+
+ final Specification specification = Optional
+ .ofNullable(filter)
+ .map(RoleApplicationAbstractFilter::toSpecification)
+ .orElse(Specification.allOf());
+
+ final Page roleApplicationEntitiesPage = roleApplicationRepository
+ .findAll(specification, pageable);
+
+ final List roleApplications = roleApplicationEntityToDomainMapper
+ .map(roleApplicationEntitiesPage.getContent());
+
+ return BasePage.of(
+ filter,
+ roleApplicationEntitiesPage,
+ roleApplications
+ );
+ }
+
+
+ @Override
+ public Optional findById(final String id) {
+ return roleApplicationRepository.findById(id)
+ .map(roleApplicationEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public Optional findByUserIdAndStatus(final String userId,
+ final RoleApplicationStatus status) {
+
+ return roleApplicationRepository.findByUserIdAndStatus(userId, status)
+ .map(roleApplicationEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public boolean existsByUserIdAndStatus(final String userId,
+ final RoleApplicationStatus status) {
+
+ return roleApplicationRepository.existsByUserIdAndStatus(userId, status);
+ }
+
+
+ @Override
+ public RoleApplication save(final RoleApplication roleApplication) {
+ final RoleApplicationEntity roleApplicationEntity = roleApplicationToEntityMapper.map(roleApplication);
+ final RoleApplicationEntity savedRoleApplicationEntity = roleApplicationRepository.save(roleApplicationEntity);
+ return roleApplicationEntityToDomainMapper.map(savedRoleApplicationEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/AuthorRequestRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/AuthorRequestRepository.java
deleted file mode 100644
index ebb18fcf..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/AuthorRequestRepository.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.gelecekbilimde.scienceplatform.auth.repository;
-
-import org.gelecekbilimde.scienceplatform.auth.model.entity.AuthorRequestEntity;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface AuthorRequestRepository extends JpaRepository {
-
- Optional findByUserId(String id);
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/InvalidTokenRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/InvalidTokenRepository.java
index f22b7d5c..2dd3db8f 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/InvalidTokenRepository.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/InvalidTokenRepository.java
@@ -3,10 +3,8 @@
import org.gelecekbilimde.scienceplatform.auth.model.entity.InvalidTokenEntity;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.Optional;
-
public interface InvalidTokenRepository extends JpaRepository {
- Optional findByTokenId(String tokenId);
+ boolean existsByTokenId(String tokenId);
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/RoleRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/RoleRepository.java
index 6ba28173..add577e8 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/RoleRepository.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/repository/RoleRepository.java
@@ -1,12 +1,13 @@
package org.gelecekbilimde.scienceplatform.auth.repository;
import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleEntity;
+import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface RoleRepository extends JpaRepository {
- Optional findByName(String role);
+ Optional findByName(RoleName name);
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/AuthenticationServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/AuthenticationServiceImpl.java
index 4a6e7c7f..4a854e5b 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/AuthenticationServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/AuthenticationServiceImpl.java
@@ -9,15 +9,14 @@
import org.gelecekbilimde.scienceplatform.auth.exception.UserPasswordNotValidException;
import org.gelecekbilimde.scienceplatform.auth.model.Identity;
import org.gelecekbilimde.scienceplatform.auth.model.Token;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleEntity;
import org.gelecekbilimde.scienceplatform.auth.model.enums.TokenClaims;
import org.gelecekbilimde.scienceplatform.auth.model.request.LoginRequest;
import org.gelecekbilimde.scienceplatform.auth.model.request.RefreshRequest;
import org.gelecekbilimde.scienceplatform.auth.service.AuthenticationService;
import org.gelecekbilimde.scienceplatform.auth.service.InvalidTokenService;
import org.gelecekbilimde.scienceplatform.auth.service.TokenService;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-import org.gelecekbilimde.scienceplatform.user.repository.UserRepository;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.port.UserReadPort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@@ -27,30 +26,32 @@
@RequiredArgsConstructor
class AuthenticationServiceImpl implements AuthenticationService {
- private final UserRepository userRepository;
+ private final UserReadPort userReadPort;
private final PasswordEncoder passwordEncoder;
private final TokenService tokenService;
private final InvalidTokenService invalidTokenService;
private final Identity identity;
+
@Override
public Token login(LoginRequest request) {
- UserEntity userEntity = userRepository.findByEmail(request.getEmail())
+ User user = userReadPort.findByEmail(request.getEmail())
.orElseThrow(() -> new UserNotFoundByEmailException(request.getEmail()));
- if (!userEntity.isVerified()) {
+ if (!user.isVerified()) {
throw new UserNotVerifiedException(request.getEmail());
}
- if (!passwordEncoder.matches(request.getPassword(), userEntity.getPassword())) {
+ if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new UserPasswordNotValidException();
}
- final Claims claims = this.getClaimsBuilder(userEntity);
+ final Claims claims = this.generateClaims(user);
return tokenService.generate(claims);
}
+
@Override
public Token refresh(RefreshRequest refreshRequest) {
@@ -58,28 +59,27 @@ public Token refresh(RefreshRequest refreshRequest) {
final Claims payload = tokenService.getPayload(refreshToken);
final String email = payload.get(TokenClaims.USER_MAIL.getValue(), String.class);
- final UserEntity userEntity = this.userRepository.findByEmail(email)
+ final User user = userReadPort.findByEmail(email)
.orElseThrow(() -> new UserNotFoundByEmailException(email));
- final Claims claims = this.getClaimsBuilder(userEntity);
+ final Claims claims = this.generateClaims(user);
return tokenService.generate(claims, refreshToken);
}
- private Claims getClaimsBuilder(UserEntity userEntity) {
- RoleEntity role = userEntity.getRole();
-
+ private Claims generateClaims(User user) {
final ClaimsBuilder claimsBuilder = Jwts.claims();
- claimsBuilder.add(TokenClaims.USER_ID.getValue(), userEntity.getId());
- claimsBuilder.add(TokenClaims.USER_FIRST_NAME.getValue(), userEntity.getFirstName());
- claimsBuilder.add(TokenClaims.USER_LAST_NAME.getValue(), userEntity.getLastName());
- claimsBuilder.add(TokenClaims.USER_STATUS.getValue(), userEntity.getStatus());
- claimsBuilder.add(TokenClaims.USER_MAIL.getValue(), userEntity.getEmail());
- claimsBuilder.add(TokenClaims.USER_ROLE.getValue(), role.getName());
- claimsBuilder.add(TokenClaims.USER_PERMISSIONS.getValue(), role.getPermissionNames());
+ claimsBuilder.add(TokenClaims.USER_ID.getValue(), user.getId());
+ claimsBuilder.add(TokenClaims.USER_FIRST_NAME.getValue(), user.getFirstName());
+ claimsBuilder.add(TokenClaims.USER_LAST_NAME.getValue(), user.getLastName());
+ claimsBuilder.add(TokenClaims.USER_STATUS.getValue(), user.getStatus());
+ claimsBuilder.add(TokenClaims.USER_MAIL.getValue(), user.getEmail());
+ claimsBuilder.add(TokenClaims.USER_ROLE.getValue(), user.getRole().getName());
+ claimsBuilder.add(TokenClaims.USER_PERMISSIONS.getValue(), user.getRole().getPermissionNames());
return claimsBuilder.build();
}
+
@Override
public void logout(String refreshToken) {
@@ -89,4 +89,5 @@ public void logout(String refreshToken) {
final List invalidTokenIds = List.of(refreshTokenId, tokenId);
invalidTokenService.saveAll(invalidTokenIds);
}
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/InvalidTokenServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/InvalidTokenServiceImpl.java
index 04197bbc..de7fa7d3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/InvalidTokenServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/InvalidTokenServiceImpl.java
@@ -2,8 +2,9 @@
import lombok.RequiredArgsConstructor;
import org.gelecekbilimde.scienceplatform.auth.exception.TokenNotValidException;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.InvalidTokenEntity;
-import org.gelecekbilimde.scienceplatform.auth.repository.InvalidTokenRepository;
+import org.gelecekbilimde.scienceplatform.auth.model.InvalidToken;
+import org.gelecekbilimde.scienceplatform.auth.port.InvalidTokenReadPort;
+import org.gelecekbilimde.scienceplatform.auth.port.InvalidTokenSavePort;
import org.gelecekbilimde.scienceplatform.auth.service.InvalidTokenService;
import org.springframework.stereotype.Service;
@@ -14,20 +15,25 @@
@RequiredArgsConstructor
class InvalidTokenServiceImpl implements InvalidTokenService {
- private final InvalidTokenRepository invalidTokenRepository;
+ private final InvalidTokenReadPort invalidTokenReadPort;
+ private final InvalidTokenSavePort invalidTokenSavePort;
public void checkForInvalidityOfToken(final String tokenId) {
- final boolean isTokenInvalid = invalidTokenRepository.findByTokenId(tokenId).isPresent();
+
+ final boolean isTokenInvalid = invalidTokenReadPort.existsByTokenId(tokenId);
+
if (isTokenInvalid) {
throw new TokenNotValidException();
}
}
public void saveAll(List invalidTokenIds) {
- List invalidTokenEntities = invalidTokenIds.stream()
- .map(invalidTokenId -> InvalidTokenEntity.builder().tokenId(invalidTokenId).build())
- .collect(Collectors.toUnmodifiableList());
- invalidTokenRepository.saveAll(invalidTokenEntities);
+
+ final List invalidTokens = invalidTokenIds.stream()
+ .map(invalidTokenId -> InvalidToken.builder().tokenId(invalidTokenId).build())
+ .collect(Collectors.toList());
+
+ invalidTokenSavePort.saveAll(invalidTokens);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RegistrationServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RegistrationServiceImpl.java
index 7549dc68..89663df3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RegistrationServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RegistrationServiceImpl.java
@@ -1,52 +1,54 @@
package org.gelecekbilimde.scienceplatform.auth.service.impl;
import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.auth.exception.AlreadyRegisteredException;
import org.gelecekbilimde.scienceplatform.auth.exception.RoleNotFoundByNameException;
+import org.gelecekbilimde.scienceplatform.auth.exception.UserAlreadyRegisteredException;
import org.gelecekbilimde.scienceplatform.auth.exception.UserNotFoundByIdException;
import org.gelecekbilimde.scienceplatform.auth.exception.UserVerificationAlreadyCompletedException;
import org.gelecekbilimde.scienceplatform.auth.exception.UserVerificationIsNotFoundException;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleEntity;
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
import org.gelecekbilimde.scienceplatform.auth.model.request.RegisterRequest;
import org.gelecekbilimde.scienceplatform.auth.model.request.VerifyRequest;
-import org.gelecekbilimde.scienceplatform.auth.repository.RoleRepository;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleReadPort;
import org.gelecekbilimde.scienceplatform.auth.service.RegistrationService;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserVerificationEntity;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
import org.gelecekbilimde.scienceplatform.user.model.enums.UserStatus;
import org.gelecekbilimde.scienceplatform.user.model.enums.UserVerificationStatus;
-import org.gelecekbilimde.scienceplatform.user.repository.UserRepository;
-import org.gelecekbilimde.scienceplatform.user.repository.UserVerificationRepository;
+import org.gelecekbilimde.scienceplatform.user.port.UserReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserSavePort;
+import org.gelecekbilimde.scienceplatform.user.port.UserVerificationReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserVerificationSavePort;
import org.gelecekbilimde.scienceplatform.user.service.UserEmailService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.concurrent.CompletableFuture;
-
@Service
@RequiredArgsConstructor
class RegistrationServiceImpl implements RegistrationService {
- private final UserRepository userRepository;
+ private final UserReadPort userReadPort;
+ private final UserSavePort userSavePort;
+ private final RoleReadPort roleReadPort;
private final PasswordEncoder passwordEncoder;
- private final RoleRepository roleRepository;
private final UserEmailService userEmailService;
- private final UserVerificationRepository userVerificationRepository;
+ private final UserVerificationReadPort userVerificationReadPort;
+ private final UserVerificationSavePort userVerificationSavePort;
@Override
@Transactional
public void register(RegisterRequest request) {
- if (userRepository.existsByEmail(request.getEmail())) {
- throw new AlreadyRegisteredException(request.getEmail());
+ if (userReadPort.existsByEmail(request.getEmail())) {
+ throw new UserAlreadyRegisteredException(request.getEmail());
}
- RoleEntity role = roleRepository.findByName(RoleName.USER.name())
+ Role role = roleReadPort.findByName(RoleName.USER)
.orElseThrow(() -> new RoleNotFoundByNameException(RoleName.USER.name()));
- UserEntity user = UserEntity.builder()
+ User user = User.builder()
.firstName(request.getFirstname())
.lastName(request.getLastname())
.email(request.getEmail())
@@ -59,40 +61,40 @@ public void register(RegisterRequest request) {
.password(passwordEncoder.encode(request.getPassword()))
.build();
- UserEntity savedUser = userRepository.save(user);
+ User savedUser = userSavePort.save(user);
- UserVerificationEntity userVerificationEntity = UserVerificationEntity.builder()
- .userId(savedUser.getId())
+ UserVerification userVerification = UserVerification.builder()
+ .user(savedUser)
.status(UserVerificationStatus.WAITING)
.build();
- userVerificationRepository.save(userVerificationEntity);
+ userVerificationSavePort.save(userVerification);
- CompletableFuture.runAsync(() -> userEmailService.sendVerifyMessage(savedUser.getEmail(), userVerificationEntity.getId()));
+ userEmailService.sendVerification(savedUser.getEmail(), userVerification.getId());
}
@Override
@Transactional
public void verify(VerifyRequest verifyRequest) {
- UserVerificationEntity userVerificationEntity = userVerificationRepository
+ UserVerification userVerification = userVerificationReadPort
.findById(verifyRequest.getVerificationId())
.orElseThrow(() -> new UserVerificationIsNotFoundException(verifyRequest.getVerificationId()));
- if (userVerificationEntity.isCompleted()) {
+ if (userVerification.isCompleted()) {
throw new UserVerificationAlreadyCompletedException();
}
- userVerificationEntity.complete();
- userVerificationRepository.save(userVerificationEntity);
+ userVerification.complete();
+ userVerificationSavePort.save(userVerification);
- UserEntity userEntity = userRepository.findById(userVerificationEntity.getUserId())
- .orElseThrow(() -> new UserNotFoundByIdException(userVerificationEntity.getUserId()));
+ User user = userReadPort.findById(userVerification.getUser().getId())
+ .orElseThrow(() -> new UserNotFoundByIdException(userVerification.getUser().getId()));
- userEntity.verify();
- userRepository.save(userEntity);
+ user.verify();
+ userSavePort.save(user);
- CompletableFuture.runAsync(() -> userEmailService.sendWelcomeMessage(userEntity.getEmail()));
+ userEmailService.sendWelcome(user.getEmail());
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleApplicationServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleApplicationServiceImpl.java
index df2ffb77..312b3194 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleApplicationServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleApplicationServiceImpl.java
@@ -4,84 +4,56 @@
import org.gelecekbilimde.scienceplatform.auth.exception.RoleApplicationAlreadyConcludedException;
import org.gelecekbilimde.scienceplatform.auth.exception.RoleApplicationNotFoundByIdException;
import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
-import org.gelecekbilimde.scienceplatform.auth.model.RoleApplicationFilter;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
-import org.gelecekbilimde.scienceplatform.auth.model.mapper.RoleApplicationEntityToDomainMapper;
import org.gelecekbilimde.scienceplatform.auth.model.request.RoleApplicationListRequest;
-import org.gelecekbilimde.scienceplatform.auth.repository.RoleApplicationRepository;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationReadPort;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationSavePort;
import org.gelecekbilimde.scienceplatform.auth.service.RoleApplicationService;
import org.gelecekbilimde.scienceplatform.common.model.BasePage;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-import org.gelecekbilimde.scienceplatform.user.repository.UserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.port.UserSavePort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.List;
-import java.util.Optional;
-
@Service
@RequiredArgsConstructor
class RoleApplicationServiceImpl implements RoleApplicationService {
- private final UserRepository userRepository;
- private final RoleApplicationRepository roleApplicationRepository;
-
-
- private final RoleApplicationEntityToDomainMapper roleApplicationEntityToDomainMapper = RoleApplicationEntityToDomainMapper.initialize();
+ private final RoleApplicationReadPort roleApplicationReadPort;
+ private final RoleApplicationSavePort roleApplicationSavePort;
+ private final UserSavePort userSavePort;
@Override
public BasePage findAll(final RoleApplicationListRequest listRequest) {
-
- final Pageable pageable = listRequest.getPageable().toPageable();
-
- final RoleApplicationFilter filter = listRequest.getFilter();
-
- final Specification specification = Optional
- .ofNullable(filter)
- .map(RoleApplicationFilter::toSpecification)
- .orElse(Specification.allOf());
-
- final Page roleApplicationEntitiesPage = roleApplicationRepository
- .findAll(specification, pageable);
-
- final List roleApplications = roleApplicationEntityToDomainMapper
- .map(roleApplicationEntitiesPage.getContent());
-
- return BasePage.of(
- filter,
- roleApplicationEntitiesPage,
- roleApplications
- );
+ return roleApplicationReadPort
+ .findAll(listRequest.getPageable(), listRequest.getFilter());
}
+
@Override
@Transactional
public void approve(final String id) {
- RoleApplicationEntity application = roleApplicationRepository.findById(id)
+ RoleApplication application = roleApplicationReadPort.findById(id)
.orElseThrow(() -> new RoleApplicationNotFoundByIdException(id));
if (application.isConcluded()) {
throw new RoleApplicationAlreadyConcludedException(id);
}
- UserEntity user = application.getUser();
+ User user = application.getUser();
user.setRole(application.getRole());
- userRepository.save(user);
+ userSavePort.save(user);
application.approve();
- roleApplicationRepository.save(application);
+ roleApplicationSavePort.save(application);
}
@Override
public void reject(final String id) {
- RoleApplicationEntity application = roleApplicationRepository.findById(id)
+ RoleApplication application = roleApplicationReadPort.findById(id)
.orElseThrow(() -> new RoleApplicationNotFoundByIdException(id));
if (application.isConcluded()) {
@@ -89,7 +61,7 @@ public void reject(final String id) {
}
application.reject();
- roleApplicationRepository.save(application);
+ roleApplicationSavePort.save(application);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleSelfApplicationServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleSelfApplicationServiceImpl.java
index a782211d..d5f67c16 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleSelfApplicationServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RoleSelfApplicationServiceImpl.java
@@ -5,44 +5,35 @@
import org.gelecekbilimde.scienceplatform.auth.exception.RoleApplicationNotFoundByUserIdAndStatusException;
import org.gelecekbilimde.scienceplatform.auth.exception.RoleNotFoundByNameException;
import org.gelecekbilimde.scienceplatform.auth.model.Identity;
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
import org.gelecekbilimde.scienceplatform.auth.model.RoleApplication;
import org.gelecekbilimde.scienceplatform.auth.model.RoleSelfApplicationFilter;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleApplicationEntity;
-import org.gelecekbilimde.scienceplatform.auth.model.entity.RoleEntity;
import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleApplicationStatus;
import org.gelecekbilimde.scienceplatform.auth.model.enums.RoleName;
-import org.gelecekbilimde.scienceplatform.auth.model.mapper.RoleApplicationEntityToDomainMapper;
import org.gelecekbilimde.scienceplatform.auth.model.request.RoleSelfApplicationListRequest;
-import org.gelecekbilimde.scienceplatform.auth.repository.RoleApplicationRepository;
-import org.gelecekbilimde.scienceplatform.auth.repository.RoleRepository;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationReadPort;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleApplicationSavePort;
+import org.gelecekbilimde.scienceplatform.auth.port.RoleReadPort;
import org.gelecekbilimde.scienceplatform.auth.service.RoleSelfApplicationService;
import org.gelecekbilimde.scienceplatform.common.model.BasePage;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
+import org.gelecekbilimde.scienceplatform.user.model.User;
import org.springframework.stereotype.Service;
-import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
class RoleSelfApplicationServiceImpl implements RoleSelfApplicationService {
- private final RoleApplicationRepository roleApplicationRepository;
- private final RoleRepository roleRepository;
+ private final RoleApplicationReadPort roleApplicationReadPort;
+ private final RoleApplicationSavePort roleApplicationSavePort;
+ private final RoleReadPort roleReadPort;
private final Identity identity;
- private final RoleApplicationEntityToDomainMapper roleApplicationEntityToDomainMapper = RoleApplicationEntityToDomainMapper.initialize();
-
-
@Override
public BasePage findAll(final RoleSelfApplicationListRequest listRequest) {
- final Pageable pageable = listRequest.getPageable().toPageable();
-
Optional.ofNullable(listRequest.getFilter())
.ifPresentOrElse(
filter -> filter.addUserId(identity.getUserId()),
@@ -53,60 +44,45 @@ public BasePage findAll(final RoleSelfApplicationListRequest li
}
);
- final Specification specification = Optional
- .ofNullable(listRequest.getFilter())
- .map(RoleSelfApplicationFilter::toSpecification)
- .orElse(Specification.allOf());
-
- final Page roleApplicationEntitiesPage = roleApplicationRepository
- .findAll(specification, pageable);
-
- final List roleApplications = roleApplicationEntityToDomainMapper
- .map(roleApplicationEntitiesPage.getContent());
-
- return BasePage.of(
- listRequest.getFilter(),
- roleApplicationEntitiesPage,
- roleApplications
- );
+ return roleApplicationReadPort.findAll(listRequest.getPageable(), listRequest.getFilter());
}
+
@Override
public void createAuthorApplication() {
this.createApplication(RoleName.AUTHOR);
}
-
@Override
public void createModeratorApplication() {
this.createApplication(RoleName.MODERATOR);
}
-
private void createApplication(final RoleName roleName) {
- boolean existAnyApplicationInReview = roleApplicationRepository
+ boolean existAnyApplicationInReview = roleApplicationReadPort
.existsByUserIdAndStatus(identity.getUserId(), RoleApplicationStatus.IN_REVIEW);
if (existAnyApplicationInReview) {
throw new RoleApplicationAlreadyExistException();
}
- final RoleEntity role = roleRepository.findByName(roleName.name())
+ final Role role = roleReadPort.findByName(roleName)
.orElseThrow(() -> new RoleNotFoundByNameException(roleName.name()));
- final RoleApplicationEntity application = RoleApplicationEntity.builder()
- .user(UserEntity.builder().id(identity.getUserId()).build())
+ final RoleApplication application = RoleApplication.builder()
+ .user(User.builder().id(identity.getUserId()).build())
.role(role)
.status(RoleApplicationStatus.IN_REVIEW)
.build();
- roleApplicationRepository.save(application);
+
+ roleApplicationSavePort.save(application);
}
@Override
public void cancel() {
- final RoleApplicationEntity application = roleApplicationRepository
+ final RoleApplication application = roleApplicationReadPort
.findByUserIdAndStatus(identity.getUserId(), RoleApplicationStatus.IN_REVIEW)
.orElseThrow(() -> new RoleApplicationNotFoundByUserIdAndStatusException(
identity.getUserId(),
@@ -115,7 +91,7 @@ public void cancel() {
);
application.cancel();
- roleApplicationRepository.save(application);
+ roleApplicationSavePort.save(application);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/util/AuthKeyPairUtil.java b/src/main/java/org/gelecekbilimde/scienceplatform/auth/util/AuthKeyPairUtil.java
index c6b1239a..b6fd2a0c 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/auth/util/AuthKeyPairUtil.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/auth/util/AuthKeyPairUtil.java
@@ -1,7 +1,6 @@
package org.gelecekbilimde.scienceplatform.auth.util;
import lombok.experimental.UtilityClass;
-import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMParser;
@@ -18,7 +17,6 @@
import java.security.PrivateKey;
import java.security.PublicKey;
-@Slf4j
@UtilityClass
public class AuthKeyPairUtil {
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/model/request/EmailSendRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/model/request/EmailSendRequest.java
deleted file mode 100644
index 3a8c96fe..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/model/request/EmailSendRequest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.common.mail.model.request;
-
-import lombok.Builder;
-import lombok.Getter;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Getter
-@Builder
-public class EmailSendRequest {
- private String to;
- private String templateFileName;
- @Builder.Default
- private Map templateVariables = new HashMap<>();
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/EmailService.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/EmailService.java
deleted file mode 100644
index 1ec2d0a3..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/EmailService.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.gelecekbilimde.scienceplatform.common.mail.service;
-
-import org.gelecekbilimde.scienceplatform.common.mail.model.request.EmailSendRequest;
-
-public interface EmailService {
-
- void send(EmailSendRequest sendRequest);
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/impl/EmailServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/impl/EmailServiceImpl.java
deleted file mode 100644
index b243cb95..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/mail/service/impl/EmailServiceImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.gelecekbilimde.scienceplatform.common.mail.service.impl;
-
-import jakarta.mail.internet.MimeMessage;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.gelecekbilimde.scienceplatform.common.mail.model.request.EmailSendRequest;
-import org.gelecekbilimde.scienceplatform.common.mail.service.EmailService;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.MimeMessageHelper;
-import org.springframework.stereotype.Service;
-import org.springframework.util.FileCopyUtils;
-
-import java.io.IOException;
-import java.util.Map;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-class EmailServiceImpl implements EmailService {
-
- private final JavaMailSender javaMailSender;
-
- @Override
- public void send(EmailSendRequest sendRequest) {
-
- try {
- MimeMessage mimeMessage = javaMailSender.createMimeMessage();
- MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, "utf-8");
-
- mimeMessageHelper.setTo(sendRequest.getTo());
- String emailContent = this.generateEmailContent(
- sendRequest.getTemplateFileName(),
- sendRequest.getTemplateVariables()
- );
- mimeMessageHelper.setSubject(this.getSubject(emailContent));
- mimeMessageHelper.setText(emailContent, true);
-
- javaMailSender.send(mimeMessage);
- } catch (Exception exception) {
- log.error("Error while sending email: {}", sendRequest.getTo(), exception);
- }
-
- }
-
- private String generateEmailContent(String templateName, Map templateVariables) throws IOException {
- ClassPathResource htmlTemplate = new ClassPathResource("static/mailtemplate/".concat(templateName));
- byte[] htmlBytes = FileCopyUtils.copyToByteArray(htmlTemplate.getInputStream());
- String emailContent = new String(htmlBytes);
-
- for (Map.Entry entry : templateVariables.entrySet()) {
- emailContent = emailContent.replace("${".concat(entry.getKey()).concat("}"), entry.getValue());
- }
- return emailContent;
- }
-
- private String getSubject(String emailContent) {
- return emailContent.split("")[1].split("")[0];
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/BaseSort.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/BaseSort.java
index 52ea5f50..04e21113 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/BaseSort.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/BaseSort.java
@@ -3,7 +3,11 @@
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
-import lombok.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.springframework.data.domain.Sort;
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/enums/MailTemplate.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/enums/MailTemplate.java
new file mode 100644
index 00000000..59a22611
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/enums/MailTemplate.java
@@ -0,0 +1,15 @@
+package org.gelecekbilimde.scienceplatform.common.model.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public enum MailTemplate {
+
+ USER_VERIFICATION("user-verification.html"),
+ USER_WELCOME("user-welcome.html");
+
+ private final String file;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/request/MailSendRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/request/MailSendRequest.java
new file mode 100644
index 00000000..8bc66300
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/request/MailSendRequest.java
@@ -0,0 +1,20 @@
+package org.gelecekbilimde.scienceplatform.common.model.request;
+
+import lombok.Builder;
+import lombok.Getter;
+import org.gelecekbilimde.scienceplatform.common.model.enums.MailTemplate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Getter
+@Builder
+public class MailSendRequest {
+
+ private List to;
+ private MailTemplate template;
+ @Builder.Default
+ private Map parameters = new HashMap<>();
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/response/SuccessResponse.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/response/SuccessResponse.java
index c74f4fad..3590df46 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/model/response/SuccessResponse.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/model/response/SuccessResponse.java
@@ -21,7 +21,7 @@ public class SuccessResponse {
private final Boolean isSuccess = true;
@JsonInclude(JsonInclude.Include.NON_NULL)
- private T content;
+ private T result;
public static SuccessResponse success() {
@@ -31,7 +31,7 @@ public static SuccessResponse success() {
public static SuccessResponse success(final T content) {
return SuccessResponse.builder()
- .content(content)
+ .result(content)
.build();
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/service/MailService.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/service/MailService.java
new file mode 100644
index 00000000..b755c5a4
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/service/MailService.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.common.service;
+
+import org.gelecekbilimde.scienceplatform.common.model.request.MailSendRequest;
+
+public interface MailService {
+
+ void send(MailSendRequest sendRequest);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/service/impl/MailServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/service/impl/MailServiceImpl.java
new file mode 100644
index 00000000..6e8ba377
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/service/impl/MailServiceImpl.java
@@ -0,0 +1,95 @@
+package org.gelecekbilimde.scienceplatform.common.service.impl;
+
+import jakarta.mail.Message;
+import jakarta.mail.MessagingException;
+import jakarta.mail.internet.InternetAddress;
+import jakarta.mail.internet.MimeMessage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.gelecekbilimde.scienceplatform.common.model.enums.MailTemplate;
+import org.gelecekbilimde.scienceplatform.common.model.request.MailSendRequest;
+import org.gelecekbilimde.scienceplatform.common.service.MailService;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+class MailServiceImpl implements MailService {
+
+ private final JavaMailSender mailSender;
+
+ @Override
+ public void send(MailSendRequest sendRequest) {
+
+ CompletableFuture.runAsync(() -> this.sendEmail(sendRequest))
+ .orTimeout(5, TimeUnit.SECONDS)
+ .exceptionally(throwable -> {
+ log.warn("Mail not sent to {} in 5 seconds with {} template", sendRequest.getTo(), sendRequest.getTemplate());
+ throw new AsyncRequestTimeoutException();
+ });
+
+ }
+
+ private void sendEmail(final MailSendRequest sendRequest) {
+ try {
+
+ MimeMessage mimeMessage = this.createMimeMessage(sendRequest);
+
+ mailSender.send(mimeMessage);
+
+ log.trace("Mail sent to {} with {} template", sendRequest.getTo(), sendRequest.getTemplate());
+
+ } catch (Exception exception) {
+ log.error("Received error while sending mail to {} with {} template", sendRequest.getTo(), sendRequest.getTemplate(), exception);
+ }
+ }
+
+ private MimeMessage createMimeMessage(final MailSendRequest sendRequest) throws IOException, MessagingException {
+
+ MimeMessage mimeMessage = mailSender.createMimeMessage();
+
+ String htmlContent = this.findTemplate(sendRequest.getTemplate());
+
+ String title = this.findTitle(htmlContent);
+ mimeMessage.setSubject(title);
+
+ String htmlContentWithParameters = this.addParameters(htmlContent, sendRequest.getParameters());
+ mimeMessage.setText(htmlContentWithParameters, "UTF-8", "html");
+
+ mimeMessage.setFrom(new InternetAddress("smtp@gelecekbilimde.net", "Gelecek Bilimde"));
+
+ for (String to : sendRequest.getTo()) {
+ mimeMessage.addRecipients(Message.RecipientType.TO, to);
+ }
+ return mimeMessage;
+ }
+
+ private String findTemplate(MailTemplate template) throws IOException {
+ ClassPathResource resource = new ClassPathResource("static/mail/template/" + template.getFile());
+ byte[] binaryData = FileCopyUtils.copyToByteArray(resource.getInputStream());
+ return new String(binaryData, StandardCharsets.UTF_8);
+ }
+
+ private String findTitle(String htmlContent) {
+ return htmlContent.split("")[1].split("")[0];
+ }
+
+ private String addParameters(String htmlContent, Map parameters) {
+ String template = htmlContent;
+ for (Map.Entry parameter : parameters.entrySet()) {
+ template = template.replace("{" + parameter.getKey() + "}", parameter.getValue().toString());
+ }
+ return template;
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/common/util/FileUtil.java b/src/main/java/org/gelecekbilimde/scienceplatform/common/util/FileUtil.java
index 08f6d02d..4f88d2e3 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/common/util/FileUtil.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/common/util/FileUtil.java
@@ -1,7 +1,6 @@
package org.gelecekbilimde.scienceplatform.common.util;
import lombok.experimental.UtilityClass;
-import lombok.extern.slf4j.Slf4j;
import org.gelecekbilimde.scienceplatform.common.exception.FileReadException;
import java.io.IOException;
@@ -9,7 +8,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
-@Slf4j
@UtilityClass
public class FileUtil {
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/exception/LastYouTubeVideoNotFoundException.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/exception/LastYouTubeVideoNotFoundException.java
index 56e7293f..8f49011a 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/notification/exception/LastYouTubeVideoNotFoundException.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/exception/LastYouTubeVideoNotFoundException.java
@@ -2,9 +2,13 @@
import java.io.Serial;
-public class LastYouTubeVideoNotFoundException extends RuntimeException {
+public final class LastYouTubeVideoNotFoundException extends RuntimeException {
@Serial
- private static final long serialVersionUID = -5775337541044176644L;
+ private static final long serialVersionUID = 3026069869731133992L;
+
+ public LastYouTubeVideoNotFoundException(Throwable cause) {
+ super("last YouTube video not found!", cause);
+ }
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/NotificationToken.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/NotificationToken.java
new file mode 100644
index 00000000..fc9b1d03
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/NotificationToken.java
@@ -0,0 +1,20 @@
+package org.gelecekbilimde.scienceplatform.notification.model;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
+
+@Getter
+@Setter
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+public class NotificationToken extends BaseDomainModel {
+
+ private Long id;
+ private String userId;
+ private String deviceId;
+ private String deviceToken;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/mapper/NotificationTokenEntityToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/mapper/NotificationTokenEntityToDomainMapper.java
new file mode 100644
index 00000000..393b2bc8
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/model/mapper/NotificationTokenEntityToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.notification.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.notification.model.NotificationToken;
+import org.gelecekbilimde.scienceplatform.notification.model.entity.NotificationTokenEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface NotificationTokenEntityToDomainMapper extends BaseMapper {
+
+ static NotificationTokenEntityToDomainMapper initialize() {
+ return Mappers.getMapper(NotificationTokenEntityToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/NotificationTokenReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/NotificationTokenReadPort.java
new file mode 100644
index 00000000..eedf3baa
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/NotificationTokenReadPort.java
@@ -0,0 +1,11 @@
+package org.gelecekbilimde.scienceplatform.notification.port;
+
+import org.gelecekbilimde.scienceplatform.notification.model.NotificationToken;
+
+import java.util.List;
+
+public interface NotificationTokenReadPort {
+
+ List findAllByUserId(String userId);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/adapter/NotificationTokenAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/adapter/NotificationTokenAdapter.java
new file mode 100644
index 00000000..6877c06a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/port/adapter/NotificationTokenAdapter.java
@@ -0,0 +1,30 @@
+package org.gelecekbilimde.scienceplatform.notification.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.notification.model.NotificationToken;
+import org.gelecekbilimde.scienceplatform.notification.model.entity.NotificationTokenEntity;
+import org.gelecekbilimde.scienceplatform.notification.model.mapper.NotificationTokenEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.notification.port.NotificationTokenReadPort;
+import org.gelecekbilimde.scienceplatform.notification.repository.NotificationTokenRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+class NotificationTokenAdapter implements NotificationTokenReadPort {
+
+ private final NotificationTokenRepository notificationTokenRepository;
+
+
+ private final NotificationTokenEntityToDomainMapper notificationTokenEntityToDomainMapper = NotificationTokenEntityToDomainMapper.initialize();
+
+
+ @Override
+ public List findAllByUserId(final String userId) {
+ final List notificationTokenEntities = notificationTokenRepository
+ .findAllByUserId(userId);
+ return notificationTokenEntityToDomainMapper.map(notificationTokenEntities);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/scheduler/YoutubeNotificationScheduler.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/scheduler/YoutubeNotificationScheduler.java
index beb5abc4..6c21a9bf 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/notification/scheduler/YoutubeNotificationScheduler.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/scheduler/YoutubeNotificationScheduler.java
@@ -22,17 +22,16 @@
@RequiredArgsConstructor
class YoutubeNotificationScheduler {
+ private final YoutubeClient youtubeClient;
+ private final PushNotificationService pushNotificationService;
+
+
@Value("${youtubeDataApi.playlistId}")
private String playlistId;
+
@Value("${youtubeDataApi.key}")
private String apiKey;
- public static final String YOUTUBE_NEW_VIDEO_TOPIC = "youtube-yeni-video";
- public static final String YOUTUBE_NEW_VIDEO_TITLE = "Yeni Video Yayınlandı!";
-
- private final YoutubeClient youtubeClient;
- private final PushNotificationService pushNotificationService;
-
private String lastVideoId;
@PostConstruct
@@ -40,6 +39,7 @@ private void init() {
this.lastVideoId = this.getLastVideo().getId();
}
+
/**
* This method will be executed every minute.
*/
@@ -51,15 +51,16 @@ private void sendNotificationForNewVideo() {
if (!this.lastVideoId.equals(videoId)) {
log.info("New video: {}", videoId);
- pushNotificationService.sendPushNotificationToTopic(
- PushNotificationTopicRequest.builder()
- .topic(YOUTUBE_NEW_VIDEO_TOPIC)
- .title(YOUTUBE_NEW_VIDEO_TITLE)
- .message("Yeni video: " + lastVideo.getTitle())
- .thumbnailLink(lastVideo.getThumbnailLink())
- .build()
- );
- log.info("Notifications has been sent to topic: {}", YOUTUBE_NEW_VIDEO_TOPIC);
+
+ PushNotificationTopicRequest notificationTopicRequest = PushNotificationTopicRequest.builder()
+ .topic("youtube-yeni-video")
+ .title("Yeni Video Yayınlandı!")
+ .message("Yeni video: " + lastVideo.getTitle())
+ .thumbnailLink(lastVideo.getThumbnailLink())
+ .build();
+
+ pushNotificationService.sendPushNotificationToTopic(notificationTopicRequest);
+ log.info("Notifications has been sent to topic: {}", notificationTopicRequest.getTopic());
this.lastVideoId = videoId;
}
@@ -76,8 +77,7 @@ private YoutubeVideo getLastVideo() {
.thumbnailLink(playlistItemsResponse.getItems().get(0).getSnippet().getThumbnails().getMaxres().getUrl())
.build();
} catch (Exception exception) {
- log.error(exception.getMessage(), exception);
- throw new LastYouTubeVideoNotFoundException();
+ throw new LastYouTubeVideoNotFoundException(exception);
}
}
@@ -88,4 +88,5 @@ private static class YoutubeVideo {
private String title;
private String thumbnailLink;
}
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/PushNotificationService.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/PushNotificationService.java
index 2da89d1b..85f69937 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/PushNotificationService.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/PushNotificationService.java
@@ -1,47 +1,12 @@
package org.gelecekbilimde.scienceplatform.notification.service;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationTopicRequest;
import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationUserRequest;
-import org.springframework.stereotype.Service;
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class PushNotificationService { // TODO : interface yazılmalı ve bu sınıf package-private olmalı
+public interface PushNotificationService {
- private final FCMService fcmService;
+ void sendPushNotificationToUser(PushNotificationUserRequest request);
- /**
- * Send push notification to user by user id.
- *
- * @param request PushNotificationTopicRequest
- */
- public void sendPushNotificationToUser(PushNotificationUserRequest request) {
- try {
- fcmService.sendMessageToTokenList(request);
- } catch (Exception exception) {
- log.error(exception.getMessage(), exception);
- }
- }
+ void sendPushNotificationToTopic(PushNotificationTopicRequest request);
- /**
- * Send push notification to topic.
- *
- * @param request PushNotificationTopicRequest
- * @implNote PushNotificationTopicRequest.builder()
- * .topic("youtube-yeni-video")
- * .title("Yeni video yok")
- * .message("Yeni video yok : " + videoTitle)
- * .build()
- * );
- */
- public void sendPushNotificationToTopic(PushNotificationTopicRequest request) {
- try {
- fcmService.sendMessageToTopic(request);
- } catch (Exception exception) {
- log.error(exception.getMessage(), exception);
- }
- }
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/FCMServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/FCMServiceImpl.java
index 8c241331..66445c16 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/FCMServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/FCMServiceImpl.java
@@ -10,14 +10,15 @@
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.gelecekbilimde.scienceplatform.notification.model.entity.NotificationTokenEntity;
+import org.gelecekbilimde.scienceplatform.notification.model.NotificationToken;
import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationTopicRequest;
import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationUserRequest;
-import org.gelecekbilimde.scienceplatform.notification.repository.NotificationTokenRepository;
+import org.gelecekbilimde.scienceplatform.notification.port.NotificationTokenReadPort;
import org.gelecekbilimde.scienceplatform.notification.service.FCMService;
import org.springframework.stereotype.Service;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.ExecutionException;
@Slf4j
@@ -25,7 +26,7 @@
@RequiredArgsConstructor
class FCMServiceImpl implements FCMService {
- private final NotificationTokenRepository userTokenRepository;
+ private final NotificationTokenReadPort notificationTokenReadPort;
private final FirebaseMessaging firebaseMessaging;
@Override
@@ -60,10 +61,10 @@ private Message.Builder getPreconfiguredMessageBuilder(PushNotificationTopicRequ
}
private MulticastMessage.Builder getPreconfiguredMulticastMessageBuilder(PushNotificationUserRequest request) {
- List deviceTokens = userTokenRepository.findAllByUserId(request.getUserId())
+ List deviceTokens = notificationTokenReadPort.findAllByUserId(request.getUserId())
.stream()
- .filter(notificationToken -> notificationToken.getDeviceToken() != null)
- .map(NotificationTokenEntity::getDeviceToken)
+ .map(NotificationToken::getDeviceToken)
+ .filter(Objects::nonNull)
.toList();
log.info("Find Device Tokens : {}", deviceTokens);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/PushNotificationServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/PushNotificationServiceImpl.java
new file mode 100644
index 00000000..583f3eec
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/notification/service/impl/PushNotificationServiceImpl.java
@@ -0,0 +1,55 @@
+package org.gelecekbilimde.scienceplatform.notification.service.impl;
+
+import com.google.firebase.messaging.FirebaseMessagingException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationTopicRequest;
+import org.gelecekbilimde.scienceplatform.notification.model.request.PushNotificationUserRequest;
+import org.gelecekbilimde.scienceplatform.notification.service.FCMService;
+import org.gelecekbilimde.scienceplatform.notification.service.PushNotificationService;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.ExecutionException;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+class PushNotificationServiceImpl implements PushNotificationService {
+
+ private final FCMService fcmService;
+
+ /**
+ * Send push notification to user by user id.
+ *
+ * @param request PushNotificationTopicRequest
+ */
+ public void sendPushNotificationToUser(PushNotificationUserRequest request) {
+ try {
+ fcmService.sendMessageToTokenList(request);
+ } catch (FirebaseMessagingException exception) {
+ log.error("Error while sending push notification to userId: {}", request.getUserId());
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Send push notification to topic.
+ *
+ * @param request PushNotificationTopicRequest
+ * @implNote PushNotificationTopicRequest.builder()
+ * .topic("youtube-yeni-video")
+ * .title("Yeni video yok")
+ * .message("Yeni video yok : " + videoTitle)
+ * .build()
+ * );
+ */
+ public void sendPushNotificationToTopic(PushNotificationTopicRequest request) {
+ try {
+ fcmService.sendMessageToTopic(request);
+ } catch (InterruptedException | ExecutionException exception) {
+ log.error("Error while sending push notification to topic: {}", request.getTopic());
+ Thread.currentThread().interrupt();
+ }
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/Category.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/Category.java
index a4aad826..3d5f384d 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/Category.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/Category.java
@@ -20,4 +20,9 @@ public class Category extends BaseDomainModel {
private String icon;
private Long parentId;
+
+ public void increaseOrderNumber() {
+ this.orderNumber++;
+ }
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/entity/CategoryEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/entity/CategoryEntity.java
index 63acebad..2fbdc94c 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/entity/CategoryEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/entity/CategoryEntity.java
@@ -51,7 +51,4 @@ public class CategoryEntity extends BaseEntity {
@JoinColumn(name = "parent_id", updatable = false, insertable = false)
private CategoryEntity parent;
- public void increaseOrder() {
- this.orderNumber++;
- }
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToDomainMapper.java
new file mode 100644
index 00000000..6162bfa2
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.post.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+import org.gelecekbilimde.scienceplatform.post.model.request.CategoryCreateRequest;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface CategoryCreateRequestToDomainMapper extends BaseMapper {
+
+ static CategoryCreateRequestToDomainMapper initialize() {
+ return Mappers.getMapper(CategoryCreateRequestToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToEntityMapper.java
deleted file mode 100644
index c70a3e55..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryCreateRequestToEntityMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.post.model.mapper;
-
-import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
-import org.gelecekbilimde.scienceplatform.post.model.entity.CategoryEntity;
-import org.gelecekbilimde.scienceplatform.post.model.request.CategoryCreateRequest;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-@Mapper
-public interface CategoryCreateRequestToEntityMapper extends BaseMapper {
-
- static CategoryCreateRequestToEntityMapper initialize() {
- return Mappers.getMapper(CategoryCreateRequestToEntityMapper.class);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryToEntityMapper.java
new file mode 100644
index 00000000..583b7fc5
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/model/mapper/CategoryToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.post.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+import org.gelecekbilimde.scienceplatform.post.model.entity.CategoryEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface CategoryToEntityMapper extends BaseMapper {
+
+ static CategoryToEntityMapper initialize() {
+ return Mappers.getMapper(CategoryToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryDeletePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryDeletePort.java
new file mode 100644
index 00000000..57bd2ef8
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryDeletePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.post.port;
+
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+
+public interface CategoryDeletePort {
+
+ void delete(Category category);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryReadPort.java
new file mode 100644
index 00000000..eae2c48d
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategoryReadPort.java
@@ -0,0 +1,28 @@
+package org.gelecekbilimde.scienceplatform.post.port;
+
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface CategoryReadPort {
+
+ List findAll();
+
+ BasePage findAll(BasePageable basePageable);
+
+ List findAllByParentId(Long parentId);
+
+ Optional findById(Long id);
+
+ Optional findBySlug(String slug);
+
+ boolean notExistsById(Long id);
+
+ boolean existsByParentId(Long parentId);
+
+ boolean existsBySlug(String slug);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategorySavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategorySavePort.java
new file mode 100644
index 00000000..064be81a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/CategorySavePort.java
@@ -0,0 +1,13 @@
+package org.gelecekbilimde.scienceplatform.post.port;
+
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+
+import java.util.List;
+
+public interface CategorySavePort {
+
+ void save(Category category);
+
+ void saveAll(List categories);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/port/adapter/CategoryAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/adapter/CategoryAdapter.java
new file mode 100644
index 00000000..272881a0
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/port/adapter/CategoryAdapter.java
@@ -0,0 +1,118 @@
+package org.gelecekbilimde.scienceplatform.post.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+import org.gelecekbilimde.scienceplatform.post.model.Category;
+import org.gelecekbilimde.scienceplatform.post.model.entity.CategoryEntity;
+import org.gelecekbilimde.scienceplatform.post.model.mapper.CategoryEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.post.model.mapper.CategoryToEntityMapper;
+import org.gelecekbilimde.scienceplatform.post.port.CategoryDeletePort;
+import org.gelecekbilimde.scienceplatform.post.port.CategoryReadPort;
+import org.gelecekbilimde.scienceplatform.post.port.CategorySavePort;
+import org.gelecekbilimde.scienceplatform.post.repository.CategoryRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class CategoryAdapter implements CategoryReadPort, CategorySavePort, CategoryDeletePort {
+
+ private final CategoryRepository categoryRepository;
+
+
+ private final CategoryEntityToDomainMapper categoryEntityToDomainMapper = CategoryEntityToDomainMapper.initialize();
+ private final CategoryToEntityMapper categoryToEntityMapper = CategoryToEntityMapper.initialize();
+
+
+ @Override
+ public List findAll() {
+ return categoryRepository.findAll().stream()
+ .map(categoryEntityToDomainMapper::map)
+ .toList();
+ }
+
+ @Override
+ public BasePage findAll(final BasePageable basePageable) {
+
+ final Pageable pageable = basePageable.toPageable();
+
+ final Page categoriesPage = categoryRepository
+ .findAll(Specification.allOf(), pageable);
+
+ final List categories = categoryEntityToDomainMapper
+ .map(categoriesPage.getContent());
+
+ return BasePage.of(
+ categoriesPage,
+ categories
+ );
+ }
+
+
+ @Override
+ public List findAllByParentId(final Long parentId) {
+ return categoryRepository.findAllByParentId(parentId).stream()
+ .map(categoryEntityToDomainMapper::map)
+ .toList();
+ }
+
+
+ @Override
+ public Optional findById(final Long id) {
+ return categoryRepository.findById(id)
+ .map(categoryEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public Optional findBySlug(final String slug) {
+ return categoryRepository.findBySlug(slug)
+ .map(categoryEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public boolean notExistsById(final Long id) {
+ return !categoryRepository.existsById(id);
+ }
+
+
+ @Override
+ public boolean existsByParentId(Long parentId) {
+ return categoryRepository.existsByParentId(parentId);
+ }
+
+
+ @Override
+ public boolean existsBySlug(final String slug) {
+ return categoryRepository.existsBySlug(slug);
+ }
+
+
+ @Override
+ public void save(final Category category) {
+ final CategoryEntity categoryEntity = categoryToEntityMapper.map(category);
+ categoryRepository.save(categoryEntity);
+ }
+
+
+ @Override
+ public void saveAll(final List categories) {
+ final List categoryEntities = categoryToEntityMapper.map(categories);
+ categoryRepository.saveAll(categoryEntities);
+ }
+
+
+ @Override
+ public void delete(final Category category) {
+ final CategoryEntity categoryEntity = categoryToEntityMapper.map(category);
+ categoryRepository.delete(categoryEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/repository/CategoryRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/repository/CategoryRepository.java
index ed0f6088..0314bc24 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/post/repository/CategoryRepository.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/repository/CategoryRepository.java
@@ -4,13 +4,13 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import java.util.List;
import java.util.Optional;
-import java.util.Set;
public interface CategoryRepository extends JpaRepository, JpaSpecificationExecutor {
- Set findAllByParentId(Long parentId);
+ List findAllByParentId(Long parentId);
Optional findBySlug(String slug);
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/post/service/impl/CategoryServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/post/service/impl/CategoryServiceImpl.java
index 50e0e8c7..639e223f 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/post/service/impl/CategoryServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/post/service/impl/CategoryServiceImpl.java
@@ -8,17 +8,14 @@
import org.gelecekbilimde.scienceplatform.post.exception.CategoryNotFoundException;
import org.gelecekbilimde.scienceplatform.post.exception.CategoryParentNotFoundException;
import org.gelecekbilimde.scienceplatform.post.model.Category;
-import org.gelecekbilimde.scienceplatform.post.model.entity.CategoryEntity;
-import org.gelecekbilimde.scienceplatform.post.model.mapper.CategoryCreateRequestToEntityMapper;
-import org.gelecekbilimde.scienceplatform.post.model.mapper.CategoryEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.post.model.mapper.CategoryCreateRequestToDomainMapper;
import org.gelecekbilimde.scienceplatform.post.model.request.CategoryCreateRequest;
import org.gelecekbilimde.scienceplatform.post.model.request.CategoryListRequest;
import org.gelecekbilimde.scienceplatform.post.model.request.CategoryUpdateRequest;
-import org.gelecekbilimde.scienceplatform.post.repository.CategoryRepository;
+import org.gelecekbilimde.scienceplatform.post.port.CategoryDeletePort;
+import org.gelecekbilimde.scienceplatform.post.port.CategoryReadPort;
+import org.gelecekbilimde.scienceplatform.post.port.CategorySavePort;
import org.gelecekbilimde.scienceplatform.post.service.CategoryService;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -27,113 +24,107 @@
@RequiredArgsConstructor
class CategoryServiceImpl implements CategoryService {
- private final CategoryRepository categoryRepository;
+ private final CategoryReadPort categoryReadPort;
+ private final CategorySavePort categorySavePort;
+ private final CategoryDeletePort categoryDeletePort;
- private final CategoryEntityToDomainMapper categoryEntityToDomainMapper = CategoryEntityToDomainMapper.initialize();
- private final CategoryCreateRequestToEntityMapper categoryCreateRequestToEntityMapper = CategoryCreateRequestToEntityMapper.initialize();
+ private final CategoryCreateRequestToDomainMapper categoryCreateRequestToDomainMapper = CategoryCreateRequestToDomainMapper.initialize();
@Override
public BasePage findAll(final CategoryListRequest listRequest) {
-
- final Pageable pageable = listRequest.getPageable().toPageable();
-
- final Page categoriesPage = categoryRepository
- .findAll(Specification.allOf(), pageable);
-
- final List categories = categoryEntityToDomainMapper
- .map(categoriesPage.getContent());
-
- return BasePage.of(
- categoriesPage,
- categories
- );
+ return categoryReadPort.findAll(listRequest.getPageable());
}
@Override
public List findAll() {
- List categories = categoryRepository.findAll();
- return categoryEntityToDomainMapper.map(categories);
+ return categoryReadPort.findAll();
}
@Override
public Category findById(Long id) {
- CategoryEntity categoryEntity = categoryRepository.findById(id)
+ return categoryReadPort.findById(id)
.orElseThrow(() -> new CategoryNotFoundException(id));
- return categoryEntityToDomainMapper.map(categoryEntity);
}
@Override
- public void create(CategoryCreateRequest request) {
+ public void create(CategoryCreateRequest createRequest) {
- final String slug = SlugUtil.slugging(request.getName());
- final boolean exists = categoryRepository.existsBySlug(slug);
+ final String slug = SlugUtil.slugging(createRequest.getName());
+ final boolean exists = categoryReadPort.existsBySlug(slug);
if (exists) {
- throw new CategoryAlreadyExistException(request.getName());
+ throw new CategoryAlreadyExistException(createRequest.getName());
}
- if (request.getParentId() != null && !categoryRepository.existsById(request.getParentId())) {
- throw new CategoryParentNotFoundException(request.getParentId());
+ if (createRequest.getParentId() != null && categoryReadPort.notExistsById(createRequest.getParentId())) {
+ throw new CategoryParentNotFoundException(createRequest.getParentId());
}
- List categories = categoryRepository.findAllByParentId(request.getParentId()).stream().toList();
- for (CategoryEntity categoryEntity : categories) {
- if (categoryEntity.getOrderNumber() >= request.getOrderNumber()) {
- categoryEntity.increaseOrder();
+ final List reorderedSubCategories = this.reorderSubCategories(
+ createRequest.getParentId(),
+ createRequest.getOrderNumber()
+ );
+
+ final Category category = categoryCreateRequestToDomainMapper.map(createRequest);
+ category.setSlug(slug);
+
+ categorySavePort.save(category);
+ categorySavePort.saveAll(reorderedSubCategories);
+ }
+
+ private List reorderSubCategories(final Long parentId, final Integer orderNumber) {
+ final List categories = categoryReadPort.findAllByParentId(parentId);
+ for (Category category : categories) {
+ if (category.getOrderNumber() >= orderNumber) {
+ category.increaseOrderNumber();
}
}
-
- CategoryEntity categoryEntity = categoryCreateRequestToEntityMapper.map(request);
- categoryEntity.setSlug(slug);
- categoryRepository.save(categoryEntity);
- categoryRepository.saveAll(categories);
+ return categories;
}
@Override
- public void update(Long id, CategoryUpdateRequest request) {
+ public void update(final Long id, final CategoryUpdateRequest updateRequest) {
- CategoryEntity categoryEntity = categoryRepository.findById(id)
+ final Category category = categoryReadPort.findById(id)
.orElseThrow(() -> new CategoryNotFoundException(id));
- final String slug = SlugUtil.slugging(request.getName());
- final boolean exists = categoryRepository.findBySlug(slug)
+ final String slug = SlugUtil.slugging(updateRequest.getName());
+ final boolean exists = categoryReadPort.findBySlug(slug)
.filter(existingCategory -> !existingCategory.getId().equals(id))
.isPresent();
if (exists) {
- throw new CategoryAlreadyExistException(request.getName());
+ throw new CategoryAlreadyExistException(updateRequest.getName());
}
- categoryEntity.setName(request.getName());
- categoryEntity.setSlug(slug);
-
- if (request.getParentId() != null) {
- if (!categoryRepository.existsById(request.getParentId())) {
- throw new CategoryParentNotFoundException(request.getParentId());
- }
- categoryEntity.setParentId(request.getParentId());
+ if (updateRequest.getParentId() != null && categoryReadPort.notExistsById(updateRequest.getParentId())) {
+ throw new CategoryParentNotFoundException(updateRequest.getParentId());
}
- categoryEntity.setDescription(request.getDescription());
+ category.setName(updateRequest.getName());
+ category.setSlug(slug);
+ category.setParentId(updateRequest.getParentId());
+ category.setDescription(updateRequest.getDescription());
- categoryRepository.save(categoryEntity);
+ categorySavePort.save(category);
}
+
@Override
public void delete(Long id) {
- CategoryEntity categoryEntity = categoryRepository.findById(id)
- .orElseThrow(() -> new CategoryNotFoundException(id));
- boolean isCategoryParent = categoryRepository.existsByParentId(id);
+ Category category = categoryReadPort.findById(id)
+ .orElseThrow(() -> new CategoryNotFoundException(id));
+ boolean isCategoryParent = categoryReadPort.existsByParentId(id);
if (isCategoryParent) {
throw new CategoryHasChildException(id);
}
- categoryRepository.delete(categoryEntity);
+ categoryDeletePort.delete(category);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/exception/SettingsNotFoundByGroupNameException.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/exception/SettingsNotFoundByGroupNameException.java
deleted file mode 100644
index dd9d1cbb..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/exception/SettingsNotFoundByGroupNameException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.exception;
-
-import org.gelecekbilimde.scienceplatform.common.exception.AbstractNotFoundException;
-
-import java.io.Serial;
-
-public final class SettingsNotFoundByGroupNameException extends AbstractNotFoundException {
-
- @Serial
- private static final long serialVersionUID = 6365994753340820279L;
-
- public SettingsNotFoundByGroupNameException(String groupName) {
- super("settings not found! groupName: " + groupName);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/entity/SettingsEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/entity/SettingsEntity.java
deleted file mode 100644
index 97c8f617..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/entity/SettingsEntity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.model.entity;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import lombok.experimental.SuperBuilder;
-import org.gelecekbilimde.scienceplatform.common.model.entity.BaseEntity;
-
-@Entity
-@Getter
-@Setter
-@SuperBuilder
-@NoArgsConstructor
-@AllArgsConstructor
-@Table(name = "gb_setting")
-public class SettingsEntity extends BaseEntity {
-
- @Id
- @Column(name = "id")
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @Column(name = "group_name")
- private String groupName;
-
- @Column(name = "name")
- private String name;
-
- @Column(name = "definition")
- private String definition;
-
- @Column(name = "is_hidden")
- private boolean isHidden;
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/mapper/SettingsEntityToSettingsMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/mapper/SettingsEntityToSettingsMapper.java
deleted file mode 100644
index 604d36ae..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/model/mapper/SettingsEntityToSettingsMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.model.mapper;
-
-import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
-import org.gelecekbilimde.scienceplatform.settings.model.Settings;
-import org.gelecekbilimde.scienceplatform.settings.model.entity.SettingsEntity;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-@Mapper
-public interface SettingsEntityToSettingsMapper extends BaseMapper {
-
- static SettingsEntityToSettingsMapper initialize() {
- return Mappers.getMapper(SettingsEntityToSettingsMapper.class);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/repository/SettingsRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/repository/SettingsRepository.java
deleted file mode 100644
index b369828b..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/repository/SettingsRepository.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.repository;
-
-import org.gelecekbilimde.scienceplatform.settings.model.entity.SettingsEntity;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.List;
-
-public interface SettingsRepository extends JpaRepository {
-
- List findAllByGroupName(String groupName);
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/SettingService.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/SettingService.java
deleted file mode 100644
index 50ac3d11..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/SettingService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.service;
-
-import org.gelecekbilimde.scienceplatform.settings.model.Settings;
-
-import java.util.List;
-
-public interface SettingService {
-
- List getSettings(String groupName, String name);
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/impl/SettingServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/impl/SettingServiceImpl.java
deleted file mode 100644
index 5be49e54..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/settings/service/impl/SettingServiceImpl.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.gelecekbilimde.scienceplatform.settings.service.impl;
-
-import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.settings.exception.SettingsNotFoundByGroupNameException;
-import org.gelecekbilimde.scienceplatform.settings.model.Settings;
-import org.gelecekbilimde.scienceplatform.settings.model.entity.SettingsEntity;
-import org.gelecekbilimde.scienceplatform.settings.model.mapper.SettingsEntityToSettingsMapper;
-import org.gelecekbilimde.scienceplatform.settings.repository.SettingsRepository;
-import org.gelecekbilimde.scienceplatform.settings.service.SettingService;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-
-import java.util.List;
-
-@Service
-@RequiredArgsConstructor
-class SettingServiceImpl implements SettingService {
-
- private final SettingsRepository settingsRepository;
-
- private final SettingsEntityToSettingsMapper settingsEntityToSettingsMapper = SettingsEntityToSettingsMapper.initialize();
-
- public List getSettings(String groupName, String name) {
-
- List settings = settingsRepository.findAllByGroupName(groupName);
-
- if (CollectionUtils.isEmpty(settings)) {
- throw new SettingsNotFoundByGroupNameException(groupName);
- }
-
- return settingsEntityToSettingsMapper.map(settings);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketCommentController.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketCommentController.java
new file mode 100644
index 00000000..6379772a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketCommentController.java
@@ -0,0 +1,56 @@
+package org.gelecekbilimde.scienceplatform.ticket.controller;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.Positive;
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketCommentToResponseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCommentAddRequest;
+import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketCommentResponse;
+import org.gelecekbilimde.scienceplatform.ticket.service.TicketCommentService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Validated
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/v1")
+class TicketCommentController {
+
+ private final TicketCommentService ticketService;
+
+
+ private final TicketCommentToResponseMapper ticketCommentToResponseMapper = TicketCommentToResponseMapper.initialize();
+
+
+ @GetMapping("/ticket/{id}/comments")
+ @PreAuthorize("hasAuthority('ticket:detail')")
+ SuccessResponse> findAllByTicketId(@PathVariable(name = "id") @Positive Long ticketId) {
+
+ final List ticketComments = ticketService.findAllByTicketId(ticketId);
+
+ final List ticketCommentResponses = ticketCommentToResponseMapper
+ .map(ticketComments);
+ return SuccessResponse.success(ticketCommentResponses);
+ }
+
+
+ @PostMapping("/ticket/{id}/comment")
+ @PreAuthorize("hasAuthority('ticket:comment:add')")
+ SuccessResponse add(@PathVariable(name = "id") @Positive Long ticketId,
+ @RequestBody @Valid TicketCommentAddRequest addRequest) {
+
+ ticketService.add(ticketId, addRequest);
+ return SuccessResponse.success();
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketController.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketController.java
index bef7901c..31cec4c5 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketController.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketController.java
@@ -1,40 +1,85 @@
package org.gelecekbilimde.scienceplatform.ticket.controller;
import jakarta.validation.Valid;
+import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketToResponseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketToTicketsResponseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCreateRequest;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketListRequest;
import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketUpdateRequest;
import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketResponse;
+import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketsResponse;
import org.gelecekbilimde.scienceplatform.ticket.service.TicketService;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+@Validated
@RestController
@RequiredArgsConstructor
-@RequestMapping("/api/v1/ticket")
+@RequestMapping("/api/v1")
class TicketController {
private final TicketService ticketService;
- @GetMapping
- @PreAuthorize("hasAuthority('ticket:read')")
- SuccessResponse> ticketRead(@Valid PagingRequest request) {
- final PagingResponse ticketResponses = ticketService.ticketRead(request);
- return SuccessResponse.success(ticketResponses);
+ private final TicketToTicketsResponseMapper ticketToTicketsResponseMapper = TicketToTicketsResponseMapper.initialize();
+ private final TicketToResponseMapper ticketToResponseMapper = TicketToResponseMapper.initialize();
+
+
+ @PostMapping("/tickets")
+ @PreAuthorize("hasAuthority('ticket:list')")
+ SuccessResponse> findAll(@RequestBody @Valid TicketListRequest listRequest) {
+
+ final BasePage pageOfTickets = ticketService.findAll(listRequest);
+
+ final PagingResponse pageResponseOfTicket = PagingResponse
+ .builder()
+ .of(pageOfTickets)
+ .content(
+ ticketToTicketsResponseMapper.map(pageOfTickets.getContent())
+ )
+ .filteredBy(listRequest.getFilter())
+ .build();
+
+ return SuccessResponse.success(pageResponseOfTicket);
}
- @PutMapping
- @PreAuthorize("hasAuthority('ticket:update')")
- SuccessResponse ticketUpdate(@RequestBody @Valid TicketUpdateRequest request) {
- Ticket ticketResponse = ticketService.updateTicket(request);
+
+ @GetMapping("/ticket/{id}")
+ @PreAuthorize("hasAuthority('ticket:detail')")
+ SuccessResponse findById(@PathVariable @Positive Long id) {
+ Ticket ticket = ticketService.findById(id);
+ TicketResponse ticketResponse = ticketToResponseMapper.map(ticket);
return SuccessResponse.success(ticketResponse);
}
+
+ @PostMapping("/ticket")
+ @PreAuthorize("hasAuthority('ticket:create')")
+ SuccessResponse create(@RequestBody @Valid TicketCreateRequest createRequest) {
+ ticketService.create(createRequest);
+ return SuccessResponse.success();
+ }
+
+
+ @PutMapping("/ticket/{id}")
+ @PreAuthorize("hasAuthority('ticket:update')")
+ SuccessResponse update(@PathVariable @Positive Long id,
+ @RequestBody @Valid TicketUpdateRequest request) {
+
+ ticketService.update(id, request);
+ return SuccessResponse.success();
+ }
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketMessageController.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketMessageController.java
deleted file mode 100644
index 814c4703..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketMessageController.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.controller;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
-import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketMessageResponse;
-import org.gelecekbilimde.scienceplatform.ticket.service.TicketMessageService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/api/v1/ticket-message")
-class TicketMessageController {
-
- private final TicketMessageService ticketService;
-
- @GetMapping
- @PreAuthorize("hasAuthority('ticket:read')")
- SuccessResponse> ticketMessageRead(@Valid TicketMessageRequest request) {
- final PagingResponse ticketResponses = ticketService.ticketMessageRead(request);
- return SuccessResponse.success(ticketResponses);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserController.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserController.java
deleted file mode 100644
index 8ad72387..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserController.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.controller;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
-import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
-import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCreateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketResponse;
-import org.gelecekbilimde.scienceplatform.ticket.service.TicketService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/api/v1/user/ticket")
-class TicketUserController {
-
- private final TicketService ticketService;
-
- @GetMapping
- @Valid
- @PreAuthorize("hasAuthority('self:ticket:read')")
- SuccessResponse> ticketReadSelf(PagingRequest request) {
- final PagingResponse ticketResponses = ticketService.ticketReadSelf(request);
- return SuccessResponse.success(ticketResponses);
- }
-
- @PostMapping
- @PreAuthorize("hasAuthority('self:ticket:create')")
- SuccessResponse ticketCreateSelf(@RequestBody @Valid TicketCreateRequest request) {
- Ticket ticketResponse = ticketService.ticketCreateSelf(request);
- return SuccessResponse.success(ticketResponse);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserMessageController.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserMessageController.java
deleted file mode 100644
index 8ff35bc8..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/controller/TicketUserMessageController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.controller;
-
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
-import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageCreateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketMessageResponse;
-import org.gelecekbilimde.scienceplatform.ticket.service.TicketMessageService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/api/v1/user/ticket-message")
-class TicketUserMessageController {
-
- private final TicketMessageService ticketService;
-
- @GetMapping
- @PreAuthorize("hasAuthority('self:ticket:read')")
- SuccessResponse> ticketMessageRead(@Valid TicketMessageRequest request) {
- final PagingResponse ticketResponses = ticketService.ticketMessageReadSelf(request);
- return SuccessResponse.success(ticketResponses);
- }
-
- @PostMapping
- @PreAuthorize("hasAuthority('self:ticket:create')")
- SuccessResponse ticketCreateSelf(@RequestBody @Valid TicketMessageCreateRequest request) {
- TicketMessageResponse ticketResponse = ticketService.ticketMessageCreate(request);
- return SuccessResponse.success(ticketResponse);
- }
-
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketAlreadyHasStatusException.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketAlreadyHasStatusException.java
new file mode 100644
index 00000000..58425343
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketAlreadyHasStatusException.java
@@ -0,0 +1,17 @@
+package org.gelecekbilimde.scienceplatform.ticket.exception;
+
+import org.gelecekbilimde.scienceplatform.common.exception.AbstractConflictException;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
+
+import java.io.Serial;
+
+public final class TicketAlreadyHasStatusException extends AbstractConflictException {
+
+ @Serial
+ private static final long serialVersionUID = -1475053585476383993L;
+
+ public TicketAlreadyHasStatusException(TicketStatus status) {
+ super("ticket already has " + status + " status");
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketNotFoundByIdException.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketNotFoundByIdException.java
new file mode 100644
index 00000000..ee9c469b
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/exception/TicketNotFoundByIdException.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.exception;
+
+import org.gelecekbilimde.scienceplatform.common.exception.AbstractNotFoundException;
+
+import java.io.Serial;
+
+public final class TicketNotFoundByIdException extends AbstractNotFoundException {
+
+ @Serial
+ private static final long serialVersionUID = 2578307933658765882L;
+
+ public TicketNotFoundByIdException(Long id) {
+ super("ticket not found by id: " + id);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/Ticket.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/Ticket.java
index 625f5c9d..75812edb 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/Ticket.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/Ticket.java
@@ -1,10 +1,12 @@
package org.gelecekbilimde.scienceplatform.ticket.model;
+import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
@Getter
@@ -15,7 +17,10 @@ public class Ticket extends BaseDomainModel {
private Long id;
private String userId;
- private String message;
- private TicketStatus status;
+ private TicketCategory category;
+ private String title;
+ private String description;
+ @Builder.Default
+ private TicketStatus status = TicketStatus.OPEN;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketComment.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketComment.java
new file mode 100644
index 00000000..59d8ba94
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketComment.java
@@ -0,0 +1,20 @@
+package org.gelecekbilimde.scienceplatform.ticket.model;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
+
+@Getter
+@Setter
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+public class TicketComment extends BaseDomainModel {
+
+ private Long id;
+ private String userId;
+ private Long ticketId;
+ private String content;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketFilter.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketFilter.java
new file mode 100644
index 00000000..3394c0da
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketFilter.java
@@ -0,0 +1,57 @@
+package org.gelecekbilimde.scienceplatform.ticket.model;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.common.model.BaseFilter;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Set;
+
+@Getter
+@Setter
+@Builder
+public class TicketFilter implements BaseFilter {
+
+ private Set categories;
+ private User user;
+
+ @Getter
+ @Setter
+ @Builder
+ public static class User {
+ private String id;
+ }
+
+ public void addUserId(String userId) {
+ this.user = User.builder()
+ .id(userId)
+ .build();
+ }
+
+
+ @Override
+ public Specification toSpecification() {
+
+ Specification specification = Specification.where(null);
+
+ if (!CollectionUtils.isEmpty(this.categories)) {
+
+ Specification categorySpecification = this.categories.stream()
+ .map(
+ category -> (Specification) (root, query, criteriaBuilder) ->
+ criteriaBuilder.equal(root.get("category"), category)
+ )
+ .reduce(Specification::or)
+ .orElse(null);
+
+ specification = specification.and(categorySpecification);
+ }
+
+ return specification;
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketMessageFilter.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketMessageFilter.java
deleted file mode 100644
index 2831fe6b..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/TicketMessageFilter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.model;
-
-import lombok.Getter;
-import lombok.Setter;
-import org.gelecekbilimde.scienceplatform.common.model.BaseFilter;
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
-import org.springframework.data.jpa.domain.Specification;
-
-@Getter
-@Setter
-public class TicketMessageFilter implements BaseFilter {
-
- private Integer id;
-
- @Override
- public Specification toSpecification() {
-
- Specification specification = Specification.where(null);
- if (id != null) {
- specification = specification.and((root, query, criteriaBuilder) ->
- criteriaBuilder.equal(root.get("id"), id)
- );
- }
- return specification;
- }
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketMessageEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketCommentEntity.java
similarity index 86%
rename from src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketMessageEntity.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketCommentEntity.java
index 0378d1b4..487c20cc 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketMessageEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketCommentEntity.java
@@ -21,8 +21,8 @@
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
-@Table(name = "gb_ticket_message")
-public class TicketMessageEntity extends BaseEntity {
+@Table(name = "gb_ticket_comment")
+public class TicketCommentEntity extends BaseEntity {
@Id
@Column(name = "id")
@@ -35,7 +35,7 @@ public class TicketMessageEntity extends BaseEntity {
@Column(name = "user_id")
private String userId;
- @Column(name = "message")
- private String message;
+ @Column(name = "content")
+ private String content;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketEntity.java
index 038babf7..ff28f065 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/entity/TicketEntity.java
@@ -9,14 +9,13 @@
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
-import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.gelecekbilimde.scienceplatform.common.model.entity.BaseEntity;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
-import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketSubject;
@Entity
@Getter
@@ -35,17 +34,18 @@ public class TicketEntity extends BaseEntity {
@Column(name = "user_id")
private String userId;
- @Builder.Default
- @Column(name = "subject")
+ @Column(name = "category")
@Enumerated(EnumType.STRING)
- private TicketSubject subject = TicketSubject.OTHER;
+ private TicketCategory category;
+
+ @Column(name = "title")
+ private String title;
@Column(name = "description")
- private String message;
+ private String description;
- @Builder.Default
@Column(name = "status")
@Enumerated(EnumType.STRING)
- private TicketStatus status = TicketStatus.OPEN;
+ private TicketStatus status;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketSubject.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketCategory.java
similarity index 83%
rename from src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketSubject.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketCategory.java
index 7e1c9b26..3be04d03 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketSubject.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/enums/TicketCategory.java
@@ -1,6 +1,6 @@
package org.gelecekbilimde.scienceplatform.ticket.model.enums;
-public enum TicketSubject {
+public enum TicketCategory {
TECHNICAL,
POST,
YOUR_QUESTION_REQUESTS,
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentEntityToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentEntityToDomainMapper.java
new file mode 100644
index 00000000..0d2aec66
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentEntityToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketCommentEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TicketCommentEntityToDomainMapper extends BaseMapper {
+
+ static TicketCommentEntityToDomainMapper initialize() {
+ return Mappers.getMapper(TicketCommentEntityToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToEntityMapper.java
new file mode 100644
index 00000000..8a0cab8a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketCommentEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TicketCommentToEntityMapper extends BaseMapper {
+
+ static TicketCommentToEntityMapper initialize() {
+ return Mappers.getMapper(TicketCommentToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToResponseMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToResponseMapper.java
new file mode 100644
index 00000000..8e09d160
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketCommentToResponseMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketCommentResponse;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TicketCommentToResponseMapper extends BaseMapper {
+
+ static TicketCommentToResponseMapper initialize() {
+ return Mappers.getMapper(TicketCommentToResponseMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketMessageEntityToMessageResponseMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketMessageEntityToMessageResponseMapper.java
deleted file mode 100644
index ff894a52..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketMessageEntityToMessageResponseMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
-
-import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketMessageEntity;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketMessageResponse;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-@Mapper
-public interface TicketMessageEntityToMessageResponseMapper extends BaseMapper {
-
- static TicketMessageEntityToMessageResponseMapper initialize() {
- return Mappers.getMapper(TicketMessageEntityToMessageResponseMapper.class);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToEntityMapper.java
new file mode 100644
index 00000000..224f3925
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TicketToEntityMapper extends BaseMapper {
+
+ static TicketToEntityMapper initialize() {
+ return Mappers.getMapper(TicketToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketEntityToResponseMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToResponseMapper.java
similarity index 51%
rename from src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketEntityToResponseMapper.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToResponseMapper.java
index 502da93f..cb0b2c34 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketEntityToResponseMapper.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToResponseMapper.java
@@ -1,16 +1,16 @@
package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketResponse;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
-public interface TicketEntityToResponseMapper extends BaseMapper {
+public interface TicketToResponseMapper extends BaseMapper {
- static TicketEntityToResponseMapper initialize() {
- return Mappers.getMapper(TicketEntityToResponseMapper.class);
+ static TicketToResponseMapper initialize() {
+ return Mappers.getMapper(TicketToResponseMapper.class);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToTicketsResponseMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToTicketsResponseMapper.java
new file mode 100644
index 00000000..96c2dfb2
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/mapper/TicketToTicketsResponseMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketsResponse;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface TicketToTicketsResponseMapper extends BaseMapper {
+
+ static TicketToTicketsResponseMapper initialize() {
+ return Mappers.getMapper(TicketToTicketsResponseMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCommentAddRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCommentAddRequest.java
new file mode 100644
index 00000000..58cdea45
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCommentAddRequest.java
@@ -0,0 +1,14 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.request;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class TicketCommentAddRequest {
+
+ @NotBlank
+ private String content;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCreateRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCreateRequest.java
index fba488a9..d0bb4187 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCreateRequest.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketCreateRequest.java
@@ -1,16 +1,26 @@
package org.gelecekbilimde.scienceplatform.ticket.model.request;
import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
@Getter
@Setter
@Builder
public class TicketCreateRequest {
+ @NotNull
+ private TicketCategory category;
+
+ @NotBlank
+ @Size(min = 2, max = 512)
+ private String title;
+
@NotBlank
- private String message;
+ private String description;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketListRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketListRequest.java
new file mode 100644
index 00000000..2fc5401c
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketListRequest.java
@@ -0,0 +1,29 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.request;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.AssertTrue;
+import lombok.Getter;
+import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketFilter;
+
+import java.util.Set;
+
+@Getter
+@Setter
+public class TicketListRequest extends PagingRequest {
+
+ @Valid
+ private TicketFilter filter;
+
+
+ @JsonIgnore
+ @AssertTrue
+ @Override
+ public boolean isOrderPropertyAccepted() {
+ final Set acceptedFilterFields = Set.of("createdAt");
+ return this.isPropertyAccepted(acceptedFilterFields);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageCreateRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageCreateRequest.java
deleted file mode 100644
index 3d34eb1e..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageCreateRequest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.model.request;
-
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
-import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketSubject;
-
-@Getter
-@Setter
-@Builder
-public class TicketMessageCreateRequest {
-
- @NotNull
- private Long id;
-
- @NotNull
- private String message;
-
- @Enumerated(EnumType.STRING)
- private TicketSubject subject;
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageRequest.java
deleted file mode 100644
index 014465f8..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketMessageRequest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.model.request;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.TicketMessageFilter;
-
-import java.util.Set;
-
-@Getter
-@Setter
-public class TicketMessageRequest extends PagingRequest {
-
- @NotNull
- private TicketMessageFilter filter;
-
- @Override
- public boolean isOrderPropertyAccepted() {
- final Set acceptedFilterFields = Set.of();
- return this.isPropertyAccepted(acceptedFilterFields);
- }
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketUpdateRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketUpdateRequest.java
index 94030328..af6d5faf 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketUpdateRequest.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/request/TicketUpdateRequest.java
@@ -1,20 +1,40 @@
package org.gelecekbilimde.scienceplatform.ticket.model.request;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
+import java.util.EnumSet;
+
@Getter
@Setter
public class TicketUpdateRequest {
@NotNull
- private Long id;
-
- @Enumerated(EnumType.STRING)
private TicketStatus status;
+
+ @JsonIgnore
+ @AssertTrue
+ @SuppressWarnings("This method is unused by the application directly but Spring is using it in the background.")
+ private boolean isStatusAccepted() {
+
+ if (this.status == null) {
+ return true;
+ }
+
+ final EnumSet acceptedStatuses = EnumSet.of(
+ TicketStatus.IN_PROGRESS,
+ TicketStatus.ON_HOLD,
+ TicketStatus.CLOSED,
+ TicketStatus.REOPENED,
+ TicketStatus.CANCELED,
+ TicketStatus.RESOLVED
+ );
+ return acceptedStatuses.contains(this.status);
+ }
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketMessageResponse.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketCommentResponse.java
similarity index 60%
rename from src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketMessageResponse.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketCommentResponse.java
index 5d06ccdb..aaf984e7 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketMessageResponse.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketCommentResponse.java
@@ -2,19 +2,16 @@
import lombok.Getter;
import lombok.Setter;
-import lombok.experimental.SuperBuilder;
import java.time.LocalDateTime;
@Getter
@Setter
-@SuperBuilder
-public class TicketMessageResponse {
+public class TicketCommentResponse {
private Long id;
- private Long userId;
- private Long ticketId;
- private String message;
+ private String userId;
+ private String content;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketResponse.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketResponse.java
index 685c662b..f946985d 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketResponse.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketResponse.java
@@ -2,21 +2,21 @@
import lombok.Getter;
import lombok.Setter;
-import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
import java.time.LocalDateTime;
@Getter
@Setter
-@SuperBuilder
public class TicketResponse {
private Long id;
private String userId;
- private String message;
+ private TicketCategory category;
+ private String title;
+ private String description;
private TicketStatus status;
private LocalDateTime createdAt;
- private LocalDateTime updatedAt;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketsResponse.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketsResponse.java
new file mode 100644
index 00000000..852cfa19
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/model/response/TicketsResponse.java
@@ -0,0 +1,21 @@
+package org.gelecekbilimde.scienceplatform.ticket.model.response;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketCategory;
+import org.gelecekbilimde.scienceplatform.ticket.model.enums.TicketStatus;
+
+import java.time.LocalDateTime;
+
+@Getter
+@Setter
+public class TicketsResponse {
+
+ private Long id;
+ private String userId;
+ private TicketCategory category;
+ private String title;
+ private TicketStatus status;
+ private LocalDateTime createdAt;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentReadPort.java
new file mode 100644
index 00000000..9062f95f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentReadPort.java
@@ -0,0 +1,11 @@
+package org.gelecekbilimde.scienceplatform.ticket.port;
+
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+
+import java.util.List;
+
+public interface TicketCommentReadPort {
+
+ List findAllByTicketId(Long ticketId);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentSavePort.java
new file mode 100644
index 00000000..2e7bf42e
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketCommentSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.ticket.port;
+
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+
+public interface TicketCommentSavePort {
+
+ void save(TicketComment ticketComment);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketReadPort.java
new file mode 100644
index 00000000..a5ca63fa
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketReadPort.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.ticket.port;
+
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketFilter;
+
+import java.util.Optional;
+
+public interface TicketReadPort {
+
+ BasePage findAll(BasePageable basePageable, TicketFilter filter);
+
+ Optional findById(Long id);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketSavePort.java
new file mode 100644
index 00000000..4bfa1d32
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/TicketSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.ticket.port;
+
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+
+public interface TicketSavePort {
+
+ void save(Ticket ticket);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketAdapter.java
new file mode 100644
index 00000000..f425e6bd
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketAdapter.java
@@ -0,0 +1,71 @@
+package org.gelecekbilimde.scienceplatform.ticket.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
+import org.gelecekbilimde.scienceplatform.common.model.BasePageable;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketFilter;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketEntityToTicketMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketToEntityMapper;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketReadPort;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketSavePort;
+import org.gelecekbilimde.scienceplatform.ticket.repository.TicketRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class TicketAdapter implements TicketReadPort, TicketSavePort {
+
+ private final TicketRepository ticketRepository;
+
+
+ private final TicketToEntityMapper ticketToEntityMapper = TicketToEntityMapper.initialize();
+ private final TicketEntityToTicketMapper ticketEntityToDomainMapper = TicketEntityToTicketMapper.initialize();
+
+
+ @Override
+ public BasePage findAll(final BasePageable basePageable,
+ final TicketFilter filter) {
+
+ final Pageable pageable = basePageable.toPageable();
+
+ final Specification specification = Optional
+ .ofNullable(filter)
+ .map(TicketFilter::toSpecification)
+ .orElse(Specification.allOf());
+
+ final Page ticketEntitiesPage = ticketRepository
+ .findAll(specification, pageable);
+
+ final List tickets = ticketEntityToDomainMapper
+ .map(ticketEntitiesPage.getContent());
+
+ return BasePage.of(
+ filter,
+ ticketEntitiesPage,
+ tickets
+ );
+ }
+
+
+ @Override
+ public Optional findById(Long id) {
+ return ticketRepository.findById(id)
+ .map(ticketEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public void save(Ticket ticket) {
+ final TicketEntity ticketEntity = ticketToEntityMapper.map(ticket);
+ ticketRepository.save(ticketEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketCommentAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketCommentAdapter.java
new file mode 100644
index 00000000..6579dd09
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/port/adapter/TicketCommentAdapter.java
@@ -0,0 +1,39 @@
+package org.gelecekbilimde.scienceplatform.ticket.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketCommentEntity;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketCommentEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketCommentToEntityMapper;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketCommentReadPort;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketCommentSavePort;
+import org.gelecekbilimde.scienceplatform.ticket.repository.TicketCommentRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+class TicketCommentAdapter implements TicketCommentReadPort, TicketCommentSavePort {
+
+ private final TicketCommentRepository ticketCommentRepository;
+
+
+ private final TicketCommentToEntityMapper ticketCommentToEntityMapper = TicketCommentToEntityMapper.initialize();
+ private final TicketCommentEntityToDomainMapper ticketCommentEntityToDomainMapper = TicketCommentEntityToDomainMapper.initialize();
+
+
+ @Override
+ public List findAllByTicketId(final Long ticketId) {
+ final List ticketCommentEntities = ticketCommentRepository.findAllByTicketId(ticketId);
+ return ticketCommentEntityToDomainMapper.map(ticketCommentEntities);
+ }
+
+
+ @Override
+ public void save(final TicketComment ticketComment) {
+ final TicketCommentEntity ticketCommentEntity = ticketCommentToEntityMapper.map(ticketComment);
+ ticketCommentRepository.save(ticketCommentEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketCommentRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketCommentRepository.java
new file mode 100644
index 00000000..4766c2c0
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketCommentRepository.java
@@ -0,0 +1,12 @@
+package org.gelecekbilimde.scienceplatform.ticket.repository;
+
+import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketCommentEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface TicketCommentRepository extends JpaRepository {
+
+ List findAllByTicketId(Long ticketId);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketMessageRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketMessageRepository.java
deleted file mode 100644
index 990d20a3..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/repository/TicketMessageRepository.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.repository;
-
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketMessageEntity;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-
-public interface TicketMessageRepository extends JpaRepository, JpaSpecificationExecutor {
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketCommentService.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketCommentService.java
new file mode 100644
index 00000000..fa6efde2
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketCommentService.java
@@ -0,0 +1,14 @@
+package org.gelecekbilimde.scienceplatform.ticket.service;
+
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCommentAddRequest;
+
+import java.util.List;
+
+public interface TicketCommentService {
+
+ List findAllByTicketId(Long ticketId);
+
+ void add(Long ticketId, TicketCommentAddRequest request);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketMessageService.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketMessageService.java
deleted file mode 100644
index 88aaac14..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketMessageService.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.service;
-
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageCreateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketMessageResponse;
-
-public interface TicketMessageService {
-
- PagingResponse ticketMessageRead(TicketMessageRequest request);
-
- PagingResponse ticketMessageReadSelf(TicketMessageRequest request);
-
- TicketMessageResponse ticketMessageCreate(TicketMessageCreateRequest request);
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketService.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketService.java
index 0568ba92..ebaad0bd 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketService.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/TicketService.java
@@ -1,21 +1,20 @@
package org.gelecekbilimde.scienceplatform.ticket.service;
-import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
+import org.gelecekbilimde.scienceplatform.common.model.BasePage;
import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCreateRequest;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketListRequest;
import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketUpdateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketResponse;
public interface TicketService {
- PagingResponse ticketRead(PagingRequest request);
+ BasePage findAll(final TicketListRequest listRequest);
- PagingResponse ticketReadSelf(PagingRequest request);
+ Ticket findById(Long id);
- Ticket updateTicket(TicketUpdateRequest request);
+ void create(TicketCreateRequest createRequest);
- Ticket ticketCreateSelf(TicketCreateRequest request);
+ void update(Long id, TicketUpdateRequest updateRequest);
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketCommentServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketCommentServiceImpl.java
new file mode 100644
index 00000000..708394f4
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketCommentServiceImpl.java
@@ -0,0 +1,60 @@
+package org.gelecekbilimde.scienceplatform.ticket.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.auth.model.Identity;
+import org.gelecekbilimde.scienceplatform.ticket.exception.TicketNotFoundByIdException;
+import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketComment;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCommentAddRequest;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketCommentReadPort;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketCommentSavePort;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketReadPort;
+import org.gelecekbilimde.scienceplatform.ticket.service.TicketCommentService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+class TicketCommentServiceImpl implements TicketCommentService {
+
+ private final TicketCommentReadPort ticketCommentReadPort;
+ private final TicketCommentSavePort ticketCommentSavePort;
+ private final TicketReadPort ticketReadPort;
+ private final Identity identity;
+
+
+ @Override
+ public List findAllByTicketId(final Long ticketId) {
+
+ this.validateTicketIdAndCurrentUserPermission(ticketId);
+
+ return ticketCommentReadPort.findAllByTicketId(ticketId);
+ }
+
+ @Override
+ public void add(final Long ticketId, final TicketCommentAddRequest request) {
+
+ this.validateTicketIdAndCurrentUserPermission(ticketId);
+
+ final TicketComment ticketComment = TicketComment.builder()
+ .ticketId(ticketId)
+ .userId(identity.getUserId())
+ .content(request.getContent())
+ .build();
+ ticketCommentSavePort.save(ticketComment);
+ }
+
+ private void validateTicketIdAndCurrentUserPermission(final Long ticketId) {
+
+ final Ticket ticket = ticketReadPort.findById(ticketId)
+ .orElseThrow(() -> new TicketNotFoundByIdException(ticketId));
+
+ boolean isNotAdmin = !identity.isAdmin();
+ boolean isNotOwner = !ticket.getUserId().equals(identity.getUserId());
+ if (isNotAdmin && isNotOwner) {
+ throw new TicketNotFoundByIdException(ticketId);
+ }
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketMessageServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketMessageServiceImpl.java
deleted file mode 100644
index 01213f0b..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketMessageServiceImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.gelecekbilimde.scienceplatform.ticket.service.impl;
-
-import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.auth.model.Identity;
-import org.gelecekbilimde.scienceplatform.common.model.BasePage;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketMessageEntity;
-import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketMessageEntityToMessageResponseMapper;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageCreateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketMessageRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketMessageResponse;
-import org.gelecekbilimde.scienceplatform.ticket.repository.TicketMessageRepository;
-import org.gelecekbilimde.scienceplatform.ticket.service.TicketMessageService;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-@RequiredArgsConstructor
-class TicketMessageServiceImpl implements TicketMessageService {
-
- private final Identity identity;
-
- private final TicketMessageRepository ticketMessageRepository;
-
- private final TicketMessageEntityToMessageResponseMapper ticketMessageEntityToMessageResponseMapper = TicketMessageEntityToMessageResponseMapper.initialize();
-
-
- @Override
- public PagingResponse ticketMessageRead(TicketMessageRequest request) {
- Pageable pageable = request.getPageable().toPageable();
- Page messagePage = ticketMessageRepository.findAll(pageable);
- List ticketResponses = ticketMessageEntityToMessageResponseMapper.map(messagePage.getContent());
- final BasePage posts = BasePage.of(messagePage, ticketResponses);
- return PagingResponse.builder()
- .of(posts)
- .content(ticketMessageEntityToMessageResponseMapper.map(messagePage.getContent()))
- .build();
- }
-
- @Override
- public PagingResponse ticketMessageReadSelf(TicketMessageRequest request) {
- Specification spec = (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("userId"), identity.getUserId());
- Page messagePage = ticketMessageRepository.findAll(spec, request.getPageable().toPageable());
- List ticketMessageRespons = ticketMessageEntityToMessageResponseMapper.map(messagePage.getContent());
- final BasePage messageResponsesPage = BasePage.of(messagePage, ticketMessageRespons);
- return PagingResponse.builder()
- .of(messageResponsesPage)
- .content(ticketMessageEntityToMessageResponseMapper.map(messagePage.getContent()))
- .build();
- }
-
- @Override
- public TicketMessageResponse ticketMessageCreate(TicketMessageCreateRequest request) {
- TicketMessageEntity message = TicketMessageEntity.builder().userId(identity.getUserId()).ticketId(request.getId()).message(request.getMessage()).build();
- TicketMessageEntity saveTicket = this.ticketMessageRepository.save(message);
- return ticketMessageEntityToMessageResponseMapper.map(saveTicket);
- }
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketServiceImpl.java
index 0ca9fefe..c21363da 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/ticket/service/impl/TicketServiceImpl.java
@@ -3,65 +3,92 @@
import lombok.RequiredArgsConstructor;
import org.gelecekbilimde.scienceplatform.auth.model.Identity;
import org.gelecekbilimde.scienceplatform.common.model.BasePage;
-import org.gelecekbilimde.scienceplatform.common.model.request.PagingRequest;
-import org.gelecekbilimde.scienceplatform.common.model.response.PagingResponse;
+import org.gelecekbilimde.scienceplatform.ticket.exception.TicketAlreadyHasStatusException;
+import org.gelecekbilimde.scienceplatform.ticket.exception.TicketNotFoundByIdException;
import org.gelecekbilimde.scienceplatform.ticket.model.Ticket;
-import org.gelecekbilimde.scienceplatform.ticket.model.entity.TicketEntity;
-import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketEntityToResponseMapper;
-import org.gelecekbilimde.scienceplatform.ticket.model.mapper.TicketEntityToTicketMapper;
+import org.gelecekbilimde.scienceplatform.ticket.model.TicketFilter;
import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketCreateRequest;
+import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketListRequest;
import org.gelecekbilimde.scienceplatform.ticket.model.request.TicketUpdateRequest;
-import org.gelecekbilimde.scienceplatform.ticket.model.response.TicketResponse;
-import org.gelecekbilimde.scienceplatform.ticket.repository.TicketRepository;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketReadPort;
+import org.gelecekbilimde.scienceplatform.ticket.port.TicketSavePort;
import org.gelecekbilimde.scienceplatform.ticket.service.TicketService;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
-import java.util.List;
+import java.util.Optional;
@Service
@RequiredArgsConstructor
class TicketServiceImpl implements TicketService {
+ private final TicketReadPort ticketReadPort;
+ private final TicketSavePort ticketSavePort;
private final Identity identity;
- private final TicketRepository ticketRepository;
-
- private final TicketEntityToResponseMapper ticketEntityToResponseMapper = TicketEntityToResponseMapper.initialize();
- private final TicketEntityToTicketMapper ticketEntityToTicketMapper = TicketEntityToTicketMapper.initialize();
@Override
- public PagingResponse ticketRead(PagingRequest request) {
- Pageable pageable = request.getPageable().toPageable();
- Page ticketPage = ticketRepository.findAll(pageable);
- List ticketResponses = ticketEntityToResponseMapper.map(ticketPage.getContent());
- final BasePage posts = BasePage.of(ticketPage, ticketResponses);
- return PagingResponse.builder().of(posts).content(ticketEntityToResponseMapper.map(ticketPage.getContent())).build();
+ public BasePage findAll(final TicketListRequest listRequest) {
+
+ if (identity.isAdmin()) {
+ return ticketReadPort.findAll(listRequest.getPageable(), listRequest.getFilter());
+ }
+
+ Optional.ofNullable(listRequest.getFilter())
+ .ifPresentOrElse(
+ filter -> filter.addUserId(identity.getUserId()),
+ () -> {
+ TicketFilter filter = TicketFilter.builder().build();
+ filter.addUserId(identity.getUserId());
+ listRequest.setFilter(filter);
+ }
+ );
+
+ return ticketReadPort.findAll(listRequest.getPageable(), listRequest.getFilter());
}
+
@Override
- public Ticket updateTicket(TicketUpdateRequest request) {
- TicketEntity ticketEntity = ticketRepository.getReferenceById(request.getId()); // TODO : getReferenceById yerine findById kullanılmalı
- ticketEntity.setStatus(request.getStatus());
- ticketRepository.save(ticketEntity);
- return ticketEntityToTicketMapper.map(ticketEntity);
+ public Ticket findById(final Long id) {
+
+ final Ticket ticket = ticketReadPort.findById(id)
+ .orElseThrow(() -> new TicketNotFoundByIdException(id));
+
+ boolean isNotAdmin = !identity.isAdmin();
+ boolean isNotOwner = !ticket.getUserId().equals(identity.getUserId());
+ if (isNotAdmin && isNotOwner) {
+ throw new TicketNotFoundByIdException(id);
+ }
+
+ return ticket;
}
+
@Override
- public Ticket ticketCreateSelf(TicketCreateRequest request) {
- TicketEntity ticketEntity = TicketEntity.builder().userId(identity.getUserId()).message(request.getMessage()).build();
- TicketEntity saveTicketEntity = this.ticketRepository.save(ticketEntity);
- return ticketEntityToTicketMapper.map(saveTicketEntity);
+ public void create(final TicketCreateRequest createRequest) {
+
+ final Ticket ticket = Ticket.builder()
+ .userId(identity.getUserId())
+ .title(createRequest.getTitle())
+ .description(createRequest.getDescription())
+ .build();
+
+ ticketSavePort.save(ticket);
}
+
@Override
- public PagingResponse ticketReadSelf(PagingRequest request) {
- Specification spec = (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("userId"), identity.getUserId());
- Page ticketPage = ticketRepository.findAll(spec, request.getPageable().toPageable());
- List ticketResponses = ticketEntityToResponseMapper.map(ticketPage.getContent());
- final BasePage posts = BasePage.of(ticketPage, ticketResponses);
- return PagingResponse.builder().of(posts).content(ticketEntityToResponseMapper.map(ticketPage.getContent())).build();
+ public void update(final Long id,
+ final TicketUpdateRequest updateRequest) {
+
+ final Ticket ticket = ticketReadPort.findById(id)
+ .orElseThrow(() -> new TicketNotFoundByIdException(id));
+
+ if (updateRequest.getStatus() == ticket.getStatus()) {
+ throw new TicketAlreadyHasStatusException(ticket.getStatus());
+ }
+
+ ticket.setStatus(updateRequest.getStatus());
+ ticketSavePort.save(ticket);
}
+
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/controller/UserFollowController.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/controller/UserFollowController.java
index f30560fa..8630790d 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/controller/UserFollowController.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/controller/UserFollowController.java
@@ -1,19 +1,17 @@
package org.gelecekbilimde.scienceplatform.user.controller;
-import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.gelecekbilimde.scienceplatform.common.model.response.SuccessResponse;
import org.gelecekbilimde.scienceplatform.user.model.User;
import org.gelecekbilimde.scienceplatform.user.model.mapper.UserToUserFollowResponseMapper;
-import org.gelecekbilimde.scienceplatform.user.model.request.UnfollowRequest;
import org.gelecekbilimde.scienceplatform.user.model.response.UserFollowResponse;
import org.gelecekbilimde.scienceplatform.user.service.UserFollowService;
import org.hibernate.validator.constraints.UUID;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -22,36 +20,34 @@
@Validated
@RestController
@RequiredArgsConstructor
-@RequestMapping("/api/v1/users")
+@RequestMapping("/api/v1")
class UserFollowController {
private final UserFollowService userFollowService;
private final UserToUserFollowResponseMapper userToUserFollowResponseMapper = UserToUserFollowResponseMapper.initialize();
- @PostMapping("/{id}/follow/toggle")
- SuccessResponse followToggle(@PathVariable @UUID String id) {
- this.userFollowService.followToggle(id);
- return SuccessResponse.success();
- }
- @PostMapping("/followers/remove")
- SuccessResponse removeFollowers(@RequestBody @Valid UnfollowRequest request) {
- this.userFollowService.removeFollower(request);
- return SuccessResponse.success();
+ @GetMapping("/user/{id}/followings")
+ SuccessResponse> findAllFollowings(@PathVariable @UUID String id) {
+ List users = this.userFollowService.findAllFollowings(id);
+ List userFollowResponses = userToUserFollowResponseMapper.map(users);
+ return SuccessResponse.success(userFollowResponses);
}
- @GetMapping("/{id}/followers")
+
+ @GetMapping("/user/{id}/followers")
SuccessResponse> findAllFollowers(@PathVariable @UUID String id) {
List users = this.userFollowService.findAllFollowers(id);
List userFollowResponses = userToUserFollowResponseMapper.map(users);
return SuccessResponse.success(userFollowResponses);
}
- @GetMapping("/{id}/followings")
- SuccessResponse> findAllFollowings(@PathVariable @UUID String id) {
- List users = this.userFollowService.findAllFollowings(id);
- List userFollowResponses = userToUserFollowResponseMapper.map(users);
- return SuccessResponse.success(userFollowResponses);
+
+ @PostMapping("/user/{id}/follow/toggle")
+ @PreAuthorize("hasAnyAuthority('user:follow', 'user:unfollow')")
+ SuccessResponse followToggle(@PathVariable @UUID String id) {
+ this.userFollowService.followToggle(id);
+ return SuccessResponse.success();
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserAlreadyUnfollowedException.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserAlreadyUnfollowedException.java
deleted file mode 100644
index 01b7e465..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserAlreadyUnfollowedException.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.user.exception;
-
-import org.gelecekbilimde.scienceplatform.common.exception.AbstractConflictException;
-
-import java.io.Serial;
-
-public class UserAlreadyUnfollowedException extends AbstractConflictException {
-
- @Serial
- private static final long serialVersionUID = -5943822734840037155L;
-
- public UserAlreadyUnfollowedException(String followerUserId, String followedUserId) {
- super("user with id " + followerUserId + " already unfollowed user with id " + followedUserId);
- }
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserCannotFollowItselfException.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserCannotFollowItselfException.java
new file mode 100644
index 00000000..33cbce9a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/exception/UserCannotFollowItselfException.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.exception;
+
+import org.gelecekbilimde.scienceplatform.common.exception.AbstractConflictException;
+
+import java.io.Serial;
+
+public final class UserCannotFollowItselfException extends AbstractConflictException {
+
+ @Serial
+ private static final long serialVersionUID = -1651758308998005837L;
+
+ public UserCannotFollowItselfException(String userId) {
+ super("user cannot follow itself by userId:" + userId);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/User.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/User.java
index 3f0a5cf6..1cdd862c 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/User.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/User.java
@@ -4,6 +4,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.auth.model.Role;
import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
import org.gelecekbilimde.scienceplatform.user.model.enums.UserDegree;
import org.gelecekbilimde.scienceplatform.user.model.enums.UserGender;
@@ -19,6 +20,7 @@ public class User extends BaseDomainModel {
private String id;
private String email;
+ private String password;
private String firstName;
private String lastName;
private String avatarPath;
@@ -27,5 +29,16 @@ public class User extends BaseDomainModel {
private UserDegree degree;
private UserGender gender;
private UserStatus status;
+ private Role role;
+
+
+ public boolean isVerified() {
+ return this.status == UserStatus.VERIFIED;
+ }
+
+
+ public void verify() {
+ this.status = UserStatus.VERIFIED;
+ }
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserFollow.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserFollow.java
new file mode 100644
index 00000000..4484ea7a
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserFollow.java
@@ -0,0 +1,19 @@
+package org.gelecekbilimde.scienceplatform.user.model;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
+
+@Getter
+@Setter
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+public class UserFollow extends BaseDomainModel {
+
+ private Long id;
+ private User follower;
+ private User followed;
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserVerification.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserVerification.java
new file mode 100644
index 00000000..7096ecf8
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/UserVerification.java
@@ -0,0 +1,30 @@
+package org.gelecekbilimde.scienceplatform.user.model;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.SuperBuilder;
+import org.gelecekbilimde.scienceplatform.common.model.BaseDomainModel;
+import org.gelecekbilimde.scienceplatform.user.model.enums.UserVerificationStatus;
+
+@Getter
+@Setter
+@SuperBuilder
+@EqualsAndHashCode(callSuper = true)
+public class UserVerification extends BaseDomainModel {
+
+ private String id;
+ private User user;
+ private UserVerificationStatus status;
+
+
+ public void complete() {
+ this.status = UserVerificationStatus.COMPLETED;
+ }
+
+
+ public boolean isCompleted() {
+ return this.status == UserVerificationStatus.COMPLETED;
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserEntity.java
index c0c1bba3..9c19af83 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserEntity.java
@@ -100,14 +100,4 @@ public class UserEntity extends BaseEntity {
@OneToMany(mappedBy = "userEntity", cascade = CascadeType.ALL)
private List postEntity;
-
- public void verify() {
- this.status = UserStatus.VERIFIED;
- }
-
-
- public boolean isVerified() {
- return this.status == UserStatus.VERIFIED;
- }
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserFollowEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserFollowEntity.java
index e550389a..ba14c4dd 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserFollowEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserFollowEntity.java
@@ -1,7 +1,18 @@
package org.gelecekbilimde.scienceplatform.user.model.entity;
-import jakarta.persistence.*;
-import lombok.*;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToOne;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
import org.gelecekbilimde.scienceplatform.common.model.entity.BaseEntity;
@Entity
@@ -18,10 +29,12 @@ public class UserFollowEntity extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
- @Column(name = "follower_user_id")
- private String followerUserId;
+ @OneToOne
+ @JoinColumn(name = "follower_user_id")
+ private UserEntity follower;
- @Column(name = "followed_user_id")
- private String followedUserId;
+ @OneToOne
+ @JoinColumn(name = "followed_user_id")
+ private UserEntity followed;
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserVerificationEntity.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserVerificationEntity.java
index 047a8e58..ebcdeb87 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserVerificationEntity.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserVerificationEntity.java
@@ -7,6 +7,8 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -30,21 +32,12 @@ public class UserVerificationEntity extends BaseEntity {
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
- @Column(name = "user_id")
- private String userId;
+ @OneToOne
+ @JoinColumn(name = "user_id")
+ private UserEntity user;
@Enumerated(EnumType.STRING)
@Column(name = "status")
private UserVerificationStatus status;
-
- public void complete() {
- this.status = UserVerificationStatus.COMPLETED;
- }
-
-
- public boolean isCompleted() {
- return this.status == UserVerificationStatus.COMPLETED;
- }
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowEntityToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowEntityToDomainMapper.java
new file mode 100644
index 00000000..d9f8e5bc
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowEntityToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserFollowEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserFollowEntityToDomainMapper extends BaseMapper {
+
+ static UserFollowEntityToDomainMapper initialize() {
+ return Mappers.getMapper(UserFollowEntityToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowToEntityMapper.java
new file mode 100644
index 00000000..9d91509f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserFollowToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserFollowEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserFollowToEntityMapper extends BaseMapper {
+
+ static UserFollowToEntityMapper initialize() {
+ return Mappers.getMapper(UserFollowToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserToEntityMapper.java
new file mode 100644
index 00000000..2b353319
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserToEntityMapper extends BaseMapper {
+
+ static UserToEntityMapper initialize() {
+ return Mappers.getMapper(UserToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationEntityToDomainMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationEntityToDomainMapper.java
new file mode 100644
index 00000000..f4fedf11
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationEntityToDomainMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserVerificationEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserVerificationEntityToDomainMapper extends BaseMapper {
+
+ static UserVerificationEntityToDomainMapper initialize() {
+ return Mappers.getMapper(UserVerificationEntityToDomainMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationToEntityMapper.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationToEntityMapper.java
new file mode 100644
index 00000000..8625e231
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/mapper/UserVerificationToEntityMapper.java
@@ -0,0 +1,16 @@
+package org.gelecekbilimde.scienceplatform.user.model.mapper;
+
+import org.gelecekbilimde.scienceplatform.common.model.mapper.BaseMapper;
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserVerificationEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface UserVerificationToEntityMapper extends BaseMapper {
+
+ static UserVerificationToEntityMapper initialize() {
+ return Mappers.getMapper(UserVerificationToEntityMapper.class);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/request/UnfollowRequest.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/request/UnfollowRequest.java
deleted file mode 100644
index 6edc3232..00000000
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/model/request/UnfollowRequest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gelecekbilimde.scienceplatform.user.model.request;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Getter;
-import lombok.Setter;
-import org.hibernate.validator.constraints.UUID;
-
-@Getter
-@Setter
-public class UnfollowRequest {
-
- @UUID
- @NotBlank
- private String followerId;
-
-}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/auth/model/response/UserFollowResponse.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/model/response/UserFollowResponse.java
similarity index 100%
rename from src/main/java/org/gelecekbilimde/scienceplatform/auth/model/response/UserFollowResponse.java
rename to src/main/java/org/gelecekbilimde/scienceplatform/user/model/response/UserFollowResponse.java
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowDeletePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowDeletePort.java
new file mode 100644
index 00000000..30726afb
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowDeletePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+
+public interface UserFollowDeletePort {
+
+ void delete(UserFollow userFollow);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowReadPort.java
new file mode 100644
index 00000000..d341b32f
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowReadPort.java
@@ -0,0 +1,17 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface UserFollowReadPort {
+
+ List findAllByFollowed(User followed);
+
+ List findAllByFollower(User follower);
+
+ Optional findByFollowedAndFollower(User followed, User follower);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowSavePort.java
new file mode 100644
index 00000000..10b4f70e
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserFollowSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+
+public interface UserFollowSavePort {
+
+ void save(UserFollow userFollow);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserReadPort.java
new file mode 100644
index 00000000..d39ebedb
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserReadPort.java
@@ -0,0 +1,15 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.User;
+
+import java.util.Optional;
+
+public interface UserReadPort {
+
+ Optional findById(String id);
+
+ Optional findByEmail(String email);
+
+ boolean existsByEmail(String email);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserSavePort.java
new file mode 100644
index 00000000..169a0fc9
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.User;
+
+public interface UserSavePort {
+
+ User save(User user);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationReadPort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationReadPort.java
new file mode 100644
index 00000000..99d91f5c
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationReadPort.java
@@ -0,0 +1,11 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
+
+import java.util.Optional;
+
+public interface UserVerificationReadPort {
+
+ Optional findById(String id);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationSavePort.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationSavePort.java
new file mode 100644
index 00000000..5cf27680
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserVerificationSavePort.java
@@ -0,0 +1,9 @@
+package org.gelecekbilimde.scienceplatform.user.port;
+
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
+
+public interface UserVerificationSavePort {
+
+ UserVerification save(UserVerification userVerification);
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserAdapter.java
new file mode 100644
index 00000000..65a3d573
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserAdapter.java
@@ -0,0 +1,53 @@
+package org.gelecekbilimde.scienceplatform.user.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserEntityToUserMapper;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserToEntityMapper;
+import org.gelecekbilimde.scienceplatform.user.port.UserReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserSavePort;
+import org.gelecekbilimde.scienceplatform.user.repository.UserRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class UserAdapter implements UserReadPort, UserSavePort {
+
+ private final UserRepository userRepository;
+
+
+ private final UserEntityToUserMapper userEntityToUserMapper = UserEntityToUserMapper.initialize();
+ private final UserToEntityMapper userToEntityMapper = UserToEntityMapper.initialize();
+
+
+ @Override
+ public Optional findById(final String id) {
+ return userRepository.findById(id)
+ .map(userEntityToUserMapper::map);
+ }
+
+
+ @Override
+ public Optional findByEmail(final String email) {
+ return userRepository.findByEmail(email)
+ .map(userEntityToUserMapper::map);
+ }
+
+
+ @Override
+ public boolean existsByEmail(final String email) {
+ return userRepository.existsByEmail(email);
+ }
+
+
+ @Override
+ public User save(User user) {
+ final UserEntity userEntity = userToEntityMapper.map(user);
+ final UserEntity savedUserEntity = userRepository.save(userEntity);
+ return userEntityToUserMapper.map(savedUserEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserFollowAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserFollowAdapter.java
new file mode 100644
index 00000000..12ca97a0
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserFollowAdapter.java
@@ -0,0 +1,75 @@
+package org.gelecekbilimde.scienceplatform.user.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.user.model.User;
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserFollowEntity;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserFollowEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserFollowToEntityMapper;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserToEntityMapper;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowDeletePort;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowSavePort;
+import org.gelecekbilimde.scienceplatform.user.repository.UserFollowRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class UserFollowAdapter implements UserFollowReadPort, UserFollowSavePort, UserFollowDeletePort {
+
+ private final UserFollowRepository userFollowRepository;
+
+ private final UserToEntityMapper userToEntityMapper = UserToEntityMapper.initialize();
+ private final UserFollowEntityToDomainMapper userFollowEntityToDomainMapper = UserFollowEntityToDomainMapper.initialize();
+ private final UserFollowToEntityMapper userFollowToEntityMapper = UserFollowToEntityMapper.initialize();
+
+
+ @Override
+ public List findAllByFollowed(User followed) {
+ final UserEntity followedEntity = userToEntityMapper.map(followed);
+ return userFollowRepository.findAllByFollowed(followedEntity)
+ .stream()
+ .map(userFollowEntityToDomainMapper::map)
+ .toList();
+ }
+
+
+ @Override
+ public List findAllByFollower(User follower) {
+ final UserEntity followerEntity = userToEntityMapper.map(follower);
+ return userFollowRepository.findAllByFollower(followerEntity)
+ .stream()
+ .map(userFollowEntityToDomainMapper::map)
+ .toList();
+ }
+
+
+ @Override
+ public Optional findByFollowedAndFollower(final User followed,
+ final User follower) {
+
+ final UserEntity followedEntity = userToEntityMapper.map(followed);
+ final UserEntity followerEntity = userToEntityMapper.map(follower);
+ return userFollowRepository.findByFollowedAndFollower(followedEntity, followerEntity)
+ .map(userFollowEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public void save(final UserFollow userFollow) {
+ final UserFollowEntity userFollowEntity = userFollowToEntityMapper.map(userFollow);
+ userFollowRepository.save(userFollowEntity);
+ }
+
+
+ @Override
+ public void delete(final UserFollow userFollow) {
+ final UserFollowEntity userFollowEntity = userFollowToEntityMapper.map(userFollow);
+ userFollowRepository.delete(userFollowEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserVerificationAdapter.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserVerificationAdapter.java
new file mode 100644
index 00000000..36ac38ad
--- /dev/null
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserVerificationAdapter.java
@@ -0,0 +1,40 @@
+package org.gelecekbilimde.scienceplatform.user.port.adapter;
+
+import lombok.RequiredArgsConstructor;
+import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserVerificationEntity;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserVerificationEntityToDomainMapper;
+import org.gelecekbilimde.scienceplatform.user.model.mapper.UserVerificationToEntityMapper;
+import org.gelecekbilimde.scienceplatform.user.port.UserVerificationReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserVerificationSavePort;
+import org.gelecekbilimde.scienceplatform.user.repository.UserVerificationRepository;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+class UserVerificationAdapter implements UserVerificationReadPort, UserVerificationSavePort {
+
+ private final UserVerificationRepository userVerificationRepository;
+
+
+ private final UserVerificationEntityToDomainMapper userVerificationEntityToDomainMapper = UserVerificationEntityToDomainMapper.initialize();
+ private final UserVerificationToEntityMapper userVerificationToEntityMapper = UserVerificationToEntityMapper.initialize();
+
+
+ @Override
+ public Optional findById(final String id) {
+ return userVerificationRepository.findById(id)
+ .map(userVerificationEntityToDomainMapper::map);
+ }
+
+
+ @Override
+ public UserVerification save(final UserVerification userVerification) {
+ final UserVerificationEntity userVerificationEntity = userVerificationToEntityMapper.map(userVerification);
+ final UserVerificationEntity savedUserVerificationEntity = userVerificationRepository.save(userVerificationEntity);
+ return userVerificationEntityToDomainMapper.map(savedUserVerificationEntity);
+ }
+
+}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/repository/UserFollowRepository.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/repository/UserFollowRepository.java
index 60f36ab5..6bef50b9 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/repository/UserFollowRepository.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/repository/UserFollowRepository.java
@@ -1,12 +1,18 @@
package org.gelecekbilimde.scienceplatform.user.repository;
+import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
import org.gelecekbilimde.scienceplatform.user.model.entity.UserFollowEntity;
import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
import java.util.Optional;
public interface UserFollowRepository extends JpaRepository {
- Optional findByFollowedUserIdAndFollowerUserId(String followedUserId, String followerUserId);
+ List findAllByFollowed(UserEntity followed);
+
+ List findAllByFollower(UserEntity follower);
+
+ Optional findByFollowedAndFollower(UserEntity followed, UserEntity follower);
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserEmailService.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserEmailService.java
index 7727fd6a..a65d5c75 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserEmailService.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserEmailService.java
@@ -2,8 +2,8 @@
public interface UserEmailService {
- void sendVerifyMessage(String email, String verificationId);
+ void sendVerification(String email, String verificationId);
- void sendWelcomeMessage(String email);
+ void sendWelcome(String email);
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserFollowService.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserFollowService.java
index 04593cc4..64092f83 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserFollowService.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/UserFollowService.java
@@ -1,7 +1,6 @@
package org.gelecekbilimde.scienceplatform.user.service;
import org.gelecekbilimde.scienceplatform.user.model.User;
-import org.gelecekbilimde.scienceplatform.user.model.request.UnfollowRequest;
import java.util.List;
@@ -13,6 +12,4 @@ public interface UserFollowService {
void followToggle(String id);
- void removeFollower(UnfollowRequest request);
-
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserEmailServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserEmailServiceImpl.java
index d252d7f4..bbedc010 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserEmailServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserEmailServiceImpl.java
@@ -1,12 +1,14 @@
package org.gelecekbilimde.scienceplatform.user.service.impl;
import lombok.RequiredArgsConstructor;
-import org.gelecekbilimde.scienceplatform.common.mail.model.request.EmailSendRequest;
-import org.gelecekbilimde.scienceplatform.common.mail.service.EmailService;
+import org.gelecekbilimde.scienceplatform.common.model.enums.MailTemplate;
+import org.gelecekbilimde.scienceplatform.common.model.request.MailSendRequest;
+import org.gelecekbilimde.scienceplatform.common.service.MailService;
import org.gelecekbilimde.scienceplatform.user.service.UserEmailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
+import java.util.List;
import java.util.Map;
@Service
@@ -14,30 +16,36 @@
class UserEmailServiceImpl implements UserEmailService {
@Value("${application.front-end.url}")
- public String frontEndUrl;
+ private String frontEndUrl;
- private final EmailService emailService;
+ private final MailService mailService;
@Override
- public void sendVerifyMessage(String email, String verificationId) {
- Map templateVariables = Map.of(
- "BASE_URL", frontEndUrl + "/auth/verify?verificationId=" + verificationId // todo frontendten url istenecek
+ public void sendVerification(final String email,
+ final String verificationId) {
+
+ final Map parameters = Map.of(
+ "BASE_URL", frontEndUrl + "/auth/verify?verificationId=" + verificationId
);
- EmailSendRequest emailSendRequest = EmailSendRequest.builder()
- .to(email)
- .templateFileName("user-verification.html")
- .templateVariables(templateVariables)
+
+ final MailSendRequest mailSendRequest = MailSendRequest.builder()
+ .to(List.of(email))
+ .template(MailTemplate.USER_VERIFICATION)
+ .parameters(parameters)
.build();
- emailService.send(emailSendRequest);
+
+ mailService.send(mailSendRequest);
}
@Override
- public void sendWelcomeMessage(String email) {
- EmailSendRequest emailSendRequest = EmailSendRequest.builder()
- .to(email)
- .templateFileName("user-welcome.html")
+ public void sendWelcome(final String email) {
+
+ final MailSendRequest mailSendRequest = MailSendRequest.builder()
+ .to(List.of(email))
+ .template(MailTemplate.USER_WELCOME)
.build();
- emailService.send(emailSendRequest);
+
+ mailService.send(mailSendRequest);
}
}
diff --git a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserFollowServiceImpl.java b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserFollowServiceImpl.java
index b947ef84..2d878a6e 100644
--- a/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserFollowServiceImpl.java
+++ b/src/main/java/org/gelecekbilimde/scienceplatform/user/service/impl/UserFollowServiceImpl.java
@@ -3,14 +3,13 @@
import lombok.RequiredArgsConstructor;
import org.gelecekbilimde.scienceplatform.auth.exception.UserNotFoundByIdException;
import org.gelecekbilimde.scienceplatform.auth.model.Identity;
-import org.gelecekbilimde.scienceplatform.user.exception.UserAlreadyUnfollowedException;
+import org.gelecekbilimde.scienceplatform.user.exception.UserCannotFollowItselfException;
import org.gelecekbilimde.scienceplatform.user.model.User;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserEntity;
-import org.gelecekbilimde.scienceplatform.user.model.entity.UserFollowEntity;
-import org.gelecekbilimde.scienceplatform.user.model.mapper.UserEntityToUserMapper;
-import org.gelecekbilimde.scienceplatform.user.model.request.UnfollowRequest;
-import org.gelecekbilimde.scienceplatform.user.repository.UserFollowRepository;
-import org.gelecekbilimde.scienceplatform.user.repository.UserRepository;
+import org.gelecekbilimde.scienceplatform.user.model.UserFollow;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowDeletePort;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowReadPort;
+import org.gelecekbilimde.scienceplatform.user.port.UserFollowSavePort;
+import org.gelecekbilimde.scienceplatform.user.port.UserReadPort;
import org.gelecekbilimde.scienceplatform.user.service.UserFollowService;
import org.springframework.stereotype.Service;
@@ -19,70 +18,72 @@
@Service
@RequiredArgsConstructor
-public class UserFollowServiceImpl implements UserFollowService {
+class UserFollowServiceImpl implements UserFollowService {
+ private final UserFollowReadPort userFollowReadPort;
+ private final UserFollowSavePort userFollowSavePort;
+ private final UserFollowDeletePort userFollowDeletePort;
+ private final UserReadPort userReadPort;
private final Identity identity;
- private final UserRepository userRepository;
- private final UserFollowRepository userFollowRepository;
- private final UserEntityToUserMapper userEntityToUserMapper = UserEntityToUserMapper.initialize();
+
@Override
- public List findAllFollowings(String id) {
- final UserEntity userEntity = userRepository.findById(id)
+ public List findAllFollowings(final String id) {
+
+ final User user = userReadPort.findById(id)
.orElseThrow(() -> new UserNotFoundByIdException(id));
- return userEntityToUserMapper.map(userEntity.getFollowings());
+ return userFollowReadPort.findAllByFollower(user)
+ .stream()
+ .map(UserFollow::getFollowed)
+ .toList();
}
@Override
- public List findAllFollowers(String id) {
- final UserEntity userEntity = userRepository.findById(id)
+ public List findAllFollowers(final String id) {
+
+ final User user = userReadPort.findById(id)
.orElseThrow(() -> new UserNotFoundByIdException(id));
- return userEntityToUserMapper.map(userEntity.getFollowers());
+ return userFollowReadPort.findAllByFollowed(user)
+ .stream()
+ .map(UserFollow::getFollower)
+ .toList();
}
@Override
- public void followToggle(String id) {
- final UserEntity userEntity = userRepository.findById(id)
+ public void followToggle(final String id) {
+
+ if (identity.getUserId().equals(id)) {
+ throw new UserCannotFollowItselfException(id);
+ }
+
+ final User user = userReadPort.findById(id)
.orElseThrow(() -> new UserNotFoundByIdException(id));
- Optional followerUserFromDatabase = userFollowRepository
- .findByFollowedUserIdAndFollowerUserId(userEntity.getId(), identity.getUserId());
+ Optional followerUserFromDatabase = userFollowReadPort
+ .findByFollowedAndFollower(user, User.builder().id(identity.getUserId()).build());
if (followerUserFromDatabase.isPresent()) {
this.unfollowUser(followerUserFromDatabase.get());
return;
}
- this.followUser(userEntity);
+ this.followUser(user);
}
- private void unfollowUser(UserFollowEntity followerUserFromDatabase) {
- userFollowRepository.delete(followerUserFromDatabase);
+ private void unfollowUser(UserFollow userFollow) {
+ userFollowDeletePort.delete(userFollow);
}
- private void followUser(UserEntity userEntity) {
- UserFollowEntity userFollowEntity = UserFollowEntity.builder()
- .followerUserId(identity.getUserId())
- .followedUserId(userEntity.getId())
+ private void followUser(User user) {
+ UserFollow userFollow = UserFollow.builder()
+ .follower(User.builder().id(identity.getUserId()).build())
+ .followed(user)
.build();
- userFollowRepository.save(userFollowEntity);
+ userFollowSavePort.save(userFollow);
}
-
- @Override
- public void removeFollower(UnfollowRequest request) {
-
- final UserEntity userEntity = userRepository.findById(request.getFollowerId())
- .orElseThrow(() -> new UserNotFoundByIdException(request.getFollowerId()));
-
- final UserFollowEntity userFollowEntity = userFollowRepository
- .findByFollowedUserIdAndFollowerUserId(identity.getUserId(), userEntity.getId())
- .orElseThrow(() -> new UserAlreadyUnfollowedException(userEntity.getId(), identity.getUserId()));
-
- userFollowRepository.delete(userFollowEntity);
- }
}
diff --git a/src/main/resources/db/migration/V1__ddl.sql b/src/main/resources/db/migration/V1__ddl.sql
index 53ebcf2a..1c011656 100644
--- a/src/main/resources/db/migration/V1__ddl.sql
+++ b/src/main/resources/db/migration/V1__ddl.sql
@@ -85,6 +85,7 @@ create table if not exists gb_user_follow
updated_by varchar(255),
updated_at timestamp(0),
constraint u__gb_user_follow__follower_user_id__followed_user_id unique (follower_user_id, followed_user_id),
+ constraint c__gb_user_follow__follower_user_id__followed_user_id check (follower_user_id != followed_user_id),
constraint fk__gb_user_follow__follower_user_id foreign key (follower_user_id) references gb_user (id),
constraint fk__gb_user_follow__followed_user_id foreign key (followed_user_id) references gb_user (id)
);
@@ -261,26 +262,25 @@ create table if not exists gb_invalid_token
);
-create table if not exists gb_setting
+create table if not exists gb_parameter
(
id bigint generated always as identity primary key,
- group_name varchar(100) not null,
name varchar(100) not null,
definition text,
is_hidden boolean,
created_by varchar(255) not null,
created_at timestamp(0) not null,
updated_by varchar(255),
- updated_at timestamp(0),
- constraint u__gb_setting__name__group_name unique (group_name, name)
+ updated_at timestamp(0)
);
create table if not exists gb_ticket
(
- id varchar(36) not null primary key,
+ id bigint generated always as identity primary key,
user_id varchar(36) not null,
- subject varchar(255) not null,
+ category varchar(255) not null,
+ title varchar(512) not null,
description text not null,
status varchar(50) not null,
created_by varchar(255) not null,
@@ -288,23 +288,25 @@ create table if not exists gb_ticket
updated_by varchar(255),
updated_at timestamp(0),
constraint fk__gb_ticket__user_id foreign key (user_id) references gb_user (id),
- constraint c__gb_ticket__subject check ( status in ('TECHNICAL', 'POST', 'YOUR_QUESTION_REQUESTS', 'FEEDBACK',
- 'COLLABORATION', 'OTHER')),
+ constraint c__gb_ticket__category check ( category in ('TECHNICAL', 'POST', 'YOUR_QUESTION_REQUESTS', 'FEEDBACK',
+ 'COLLABORATION', 'OTHER')),
constraint c__gb_ticket__status check ( status in ('OPEN', 'IN_PROGRESS', 'ON_HOLD', 'CLOSED',
'REOPENED', 'CANCELED', 'RESOLVED'))
);
-create table if not exists gb_ticket_message
+create table if not exists gb_ticket_comment
(
id bigint generated always as identity primary key,
- ticket_id varchar(36) not null,
+ ticket_id bigint not null,
user_id varchar(36) not null,
- message text,
+ content text,
created_by varchar(255) not null,
created_at timestamp(0) not null,
updated_by varchar(255),
- updated_at timestamp(0)
+ updated_at timestamp(0),
+ constraint fk__gb_ticket_message__ticket_id foreign key (ticket_id) references gb_ticket (id),
+ constraint fk__gb_ticket_message__user_id foreign key (user_id) references gb_user (id)
);
diff --git a/src/main/resources/db/migration/V2__dml.sql b/src/main/resources/db/migration/V2__dml.sql
index 5e1609d8..c92fdf86 100644
--- a/src/main/resources/db/migration/V2__dml.sql
+++ b/src/main/resources/db/migration/V2__dml.sql
@@ -46,18 +46,21 @@ insert into gb_permission (id, description, name, is_hidden, created_by, created
values ('d16020f2-1331-4e2f-94aa-7f6d08b6e157', 'Yorum Beğenir',
'comment:like', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
-values ('0150a560-8536-427e-8e76-fb1f6d41f5e7', 'Kendi Çağrısı Kayıtlarını Listeler',
- 'self:ticket:read', false, 'gelecekbilimde', current_timestamp);
-insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
values ('b7c4f0d1-3f0e-46aa-9c02-ee7e7cbf49bb', 'Bütün Çağrı Kayıtlarını Listeler',
- 'ticket:read', false, 'gelecekbilimde', current_timestamp);
+ 'ticket:list', false, 'gelecekbilimde', current_timestamp);
+insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
+values ('6270e6e9-28a4-4811-bf20-a7c4b7dc41b5', 'Çağrı Kaydının Detayını Görüntüler',
+ 'ticket:detail', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
values ('1bb69fdf-d470-4c37-8075-58ff0fa0d19e', 'Çağrı Kaydı Oluşturur',
- 'self:ticket:create', false, 'gelecekbilimde', current_timestamp);
+ 'ticket:create', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
values ('7572d942-b048-40bf-8cf4-c7a87d9be586', 'Çağrı Kaydını Günceller',
'ticket:update', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
+values ('08cc7245-ed0f-47ee-a892-702f000a2ab5', 'Çağrı Kaydına Yorum Ekler',
+ 'ticket:comment:add', false, 'gelecekbilimde', current_timestamp);
+insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
values ('f8217f8d-8d67-496f-8761-53201e690078', 'Profil Düzenler',
'profile:edit', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
@@ -79,6 +82,12 @@ insert into gb_permission (id, description, name, is_hidden, created_by, created
values ('d7a49ea4-fae1-4dac-8e07-c1d823841b50', 'Kendi Adına Var Olan Rol Başvurusunu İptal Eder',
'role:application:cancel:self', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
+values ('26474155-f207-45e9-8798-a4cdd9cf8f31', 'Kullanıcıyı Takip Eder',
+ 'user:follow', false, 'gelecekbilimde', current_timestamp);
+insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
+values ('91e30d16-b9f7-40a2-a4f6-eecf3157aa74', 'Kullanıcıyı Takibi Bırakır',
+ 'user:unfollow', false, 'gelecekbilimde', current_timestamp);
+insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
values ('5a32defb-14c0-44b2-b518-fb482ca768e6', 'Kategorileri Listeler',
'category:list', false, 'gelecekbilimde', current_timestamp);
insert into gb_permission (id, description, name, is_hidden, created_by, created_at)
@@ -95,7 +104,6 @@ values ('889c4c62-73c8-465f-a6e3-ee54ab790007', 'Kategori Siler',
'category:delete', false, 'gelecekbilimde', current_timestamp);
-
insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '836e0a9c-b2bb-4ecf-bf8b-870ea7bb8bc7');
insert into gb_role_permission (role_id, permission_id)
@@ -111,12 +119,20 @@ values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '35bc91b4-3b92-4ff5-b204-439ef21
insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', 'b7c4f0d1-3f0e-46aa-9c02-ee7e7cbf49bb');
insert into gb_role_permission (role_id, permission_id)
+values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '6270e6e9-28a4-4811-bf20-a7c4b7dc41b5');
+insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '7572d942-b048-40bf-8cf4-c7a87d9be586');
insert into gb_role_permission (role_id, permission_id)
+values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '08cc7245-ed0f-47ee-a892-702f000a2ab5');
+insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '0352ee79-e844-4e91-968f-c9f3e4a27515');
insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '31366d9d-5282-4fe2-9d45-4551e114bc7d');
insert into gb_role_permission (role_id, permission_id)
+values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '26474155-f207-45e9-8798-a4cdd9cf8f31');
+insert into gb_role_permission (role_id, permission_id)
+values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '91e30d16-b9f7-40a2-a4f6-eecf3157aa74');
+insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '5a32defb-14c0-44b2-b518-fb482ca768e6');
insert into gb_role_permission (role_id, permission_id)
values ('c147b5c2-87f7-4bb7-a165-368f639d8c3c', '9e25ae21-9b35-4511-bdd5-c0e2ec96b8d4');
@@ -138,18 +154,24 @@ VALUES ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '6842cfea-0568-4970-af2e-bc9e3f7
INSERT INTO gb_role_permission (role_id, permission_id)
VALUES ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', 'd16020f2-1331-4e2f-94aa-7f6d08b6e157');
insert into gb_role_permission (role_id, permission_id)
-values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '01bc1089-bd27-4b41-bfde-8e63c988fec3');
-insert into gb_role_permission (role_id, permission_id)
-values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '0150a560-8536-427e-8e76-fb1f6d41f5e7');
+values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '6270e6e9-28a4-4811-bf20-a7c4b7dc41b5');
insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '1bb69fdf-d470-4c37-8075-58ff0fa0d19e');
insert into gb_role_permission (role_id, permission_id)
+values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '01bc1089-bd27-4b41-bfde-8e63c988fec3');
+insert into gb_role_permission (role_id, permission_id)
+values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '08cc7245-ed0f-47ee-a892-702f000a2ab5');
+insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '5b27d86c-ae00-49c2-8adc-07ed762920ce');
insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', 'e7c0ddb6-5371-449f-841e-65b14f53f200');
insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', 'f8217f8d-8d67-496f-8761-53201e690078');
insert into gb_role_permission (role_id, permission_id)
+values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '26474155-f207-45e9-8798-a4cdd9cf8f31');
+insert into gb_role_permission (role_id, permission_id)
+values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '91e30d16-b9f7-40a2-a4f6-eecf3157aa74');
+insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '5a32defb-14c0-44b2-b518-fb482ca768e6');
insert into gb_role_permission (role_id, permission_id)
values ('1ed82a25-d348-4576-b4e6-1f2a7c430ca7', '9e25ae21-9b35-4511-bdd5-c0e2ec96b8d4');
@@ -169,12 +191,14 @@ VALUES ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '6842cfea-0568-4970-af2e-bc9e3f7
INSERT INTO gb_role_permission (role_id, permission_id)
VALUES ('4d98a76c-9841-4aea-b296-2f27aa610b6c', 'd16020f2-1331-4e2f-94aa-7f6d08b6e157');
insert into gb_role_permission (role_id, permission_id)
-values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '01bc1089-bd27-4b41-bfde-8e63c988fec3');
-insert into gb_role_permission (role_id, permission_id)
-values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '0150a560-8536-427e-8e76-fb1f6d41f5e7');
+values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '6270e6e9-28a4-4811-bf20-a7c4b7dc41b5');
insert into gb_role_permission (role_id, permission_id)
values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '1bb69fdf-d470-4c37-8075-58ff0fa0d19e');
insert into gb_role_permission (role_id, permission_id)
+values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '01bc1089-bd27-4b41-bfde-8e63c988fec3');
+insert into gb_role_permission (role_id, permission_id)
+values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '08cc7245-ed0f-47ee-a892-702f000a2ab5');
+insert into gb_role_permission (role_id, permission_id)
values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '5b27d86c-ae00-49c2-8adc-07ed762920ce');
insert into gb_role_permission (role_id, permission_id)
values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', 'e7c0ddb6-5371-449f-841e-65b14f53f200');
@@ -186,6 +210,10 @@ insert into gb_role_permission (role_id, permission_id)
values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', 'd7a49ea4-fae1-4dac-8e07-c1d823841b50');
insert into gb_role_permission (role_id, permission_id)
values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '2902d3c0-040e-47f6-b894-e72484252a0a');
+insert into gb_role_permission (role_id, permission_id)
+values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '26474155-f207-45e9-8798-a4cdd9cf8f31');
+insert into gb_role_permission (role_id, permission_id)
+values ('4d98a76c-9841-4aea-b296-2f27aa610b6c', '91e30d16-b9f7-40a2-a4f6-eecf3157aa74');
insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '01bc1089-bd27-4b41-bfde-8e63c988fec3');
@@ -194,10 +222,12 @@ values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '6842cfea-0568-4970-af2e-bc9e3f7
insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', 'd16020f2-1331-4e2f-94aa-7f6d08b6e157');
insert into gb_role_permission (role_id, permission_id)
-values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '0150a560-8536-427e-8e76-fb1f6d41f5e7');
+values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '6270e6e9-28a4-4811-bf20-a7c4b7dc41b5');
insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '1bb69fdf-d470-4c37-8075-58ff0fa0d19e');
insert into gb_role_permission (role_id, permission_id)
+values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '08cc7245-ed0f-47ee-a892-702f000a2ab5');
+insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '5b27d86c-ae00-49c2-8adc-07ed762920ce');
insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', 'e7c0ddb6-5371-449f-841e-65b14f53f200');
@@ -209,7 +239,10 @@ insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', 'd7a49ea4-fae1-4dac-8e07-c1d823841b50');
insert into gb_role_permission (role_id, permission_id)
values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '2902d3c0-040e-47f6-b894-e72484252a0a');
-
+insert into gb_role_permission (role_id, permission_id)
+values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '26474155-f207-45e9-8798-a4cdd9cf8f31');
+insert into gb_role_permission (role_id, permission_id)
+values ('e3a1a32d-fcd7-46f0-bb2b-201df6b2b808', '91e30d16-b9f7-40a2-a4f6-eecf3157aa74');
insert into gb_category (order_number, parent_id, name, description, slug, icon, created_by, created_at)
diff --git a/src/main/resources/static/mailtemplate/user-verification.html b/src/main/resources/static/mail/template/user-verification.html
similarity index 98%
rename from src/main/resources/static/mailtemplate/user-verification.html
rename to src/main/resources/static/mail/template/user-verification.html
index 56565084..603d791a 100644
--- a/src/main/resources/static/mailtemplate/user-verification.html
+++ b/src/main/resources/static/mail/template/user-verification.html
@@ -1,5 +1,5 @@
-
+
Hesabınızı Onaylayın!
diff --git a/src/main/resources/static/mailtemplate/user-welcome.html b/src/main/resources/static/mail/template/user-welcome.html
similarity index 98%
rename from src/main/resources/static/mailtemplate/user-welcome.html
rename to src/main/resources/static/mail/template/user-welcome.html
index 9a5e4397..34399c5a 100644
--- a/src/main/resources/static/mailtemplate/user-welcome.html
+++ b/src/main/resources/static/mail/template/user-welcome.html
@@ -1,5 +1,5 @@
-
+
Gelecek Bilimde Ekibine Hoşgeldiniz!