From 66e935c8d0cfd5503c1c67ff8cd7b2657288a1ab Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:02:46 +0900 Subject: [PATCH 01/11] add: added mongodb --- settings.gradle | 1 + smeem-bootstrap/build.gradle | 1 + smeem-bootstrap/src/main/resources/application-dev.yml | 1 + .../src/main/resources/application-local.yml | 1 + .../src/main/resources/application-prod.yml | 1 + smeem-output-persistence/build.gradle | 9 +++++++++ .../main/resources/mongo-config/application-dev.yml | 10 ++++++++++ .../main/resources/mongo-config/application-local.yml | 10 ++++++++++ .../main/resources/mongo-config/application-prod.yml | 10 ++++++++++ 9 files changed, 44 insertions(+) create mode 100644 smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml create mode 100644 smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml create mode 100644 smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml diff --git a/settings.gradle b/settings.gradle index d3c84324..318cbef3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ include 'smeem-input-http' include 'smeem-application' include 'smeem-output-persistence' include 'smeem-output-persistence:postgresql' +include 'smeem-output-persistence:mongodb' include 'smeem-output-notification' include 'smeem-output-notification:firebase' include 'smeem-output-oauth' diff --git a/smeem-bootstrap/build.gradle b/smeem-bootstrap/build.gradle index bfd66c7b..09cb101d 100644 --- a/smeem-bootstrap/build.gradle +++ b/smeem-bootstrap/build.gradle @@ -4,6 +4,7 @@ dependencies { implementation project(':smeem-input-http') implementation project(':smeem-output-persistence') implementation project(':smeem-output-persistence:postgresql') + implementation project(':smeem-output-persistence:mongodb') implementation project(':smeem-output-notification') implementation project(':smeem-output-notification:firebase') implementation project(':smeem-output-oauth') diff --git a/smeem-bootstrap/src/main/resources/application-dev.yml b/smeem-bootstrap/src/main/resources/application-dev.yml index 84548e8e..06b783d4 100644 --- a/smeem-bootstrap/src/main/resources/application-dev.yml +++ b/smeem-bootstrap/src/main/resources/application-dev.yml @@ -4,6 +4,7 @@ spring: on-profile: dev import: - classpath:postgres-config/application-dev.yml + - classpath:mongo-config/application-dev.yml - classpath:smeem-config/application-dev.yml - classpath:notification-config/application-dev.yml - classpath:common-config/application-dev.yml diff --git a/smeem-bootstrap/src/main/resources/application-local.yml b/smeem-bootstrap/src/main/resources/application-local.yml index c4efcc01..85fc1df1 100644 --- a/smeem-bootstrap/src/main/resources/application-local.yml +++ b/smeem-bootstrap/src/main/resources/application-local.yml @@ -4,6 +4,7 @@ spring: on-profile: local import: - classpath:postgres-config/application-local.yml + - classpath:mongo-config/application-local.yml - classpath:smeem-config/application-local.yml - classpath:notification-config/application-local.yml - classpath:common-config/application-local.yml diff --git a/smeem-bootstrap/src/main/resources/application-prod.yml b/smeem-bootstrap/src/main/resources/application-prod.yml index bf3eb50b..49c558b8 100644 --- a/smeem-bootstrap/src/main/resources/application-prod.yml +++ b/smeem-bootstrap/src/main/resources/application-prod.yml @@ -4,6 +4,7 @@ spring: on-profile: prod import: - classpath:postgres-config/application-prod.yml + - classpath:mongo-config/application-prod.yml - classpath:smeem-config/application-prod.yml - classpath:notification-config/application-prod.yml - classpath:common-config/application-prod.yml diff --git a/smeem-output-persistence/build.gradle b/smeem-output-persistence/build.gradle index 61245d57..c0b90e2e 100644 --- a/smeem-output-persistence/build.gradle +++ b/smeem-output-persistence/build.gradle @@ -1,6 +1,8 @@ project(':smeem-output-persistence:postgresql') { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // postgresql implementation 'org.postgresql:postgresql' // QueryDSL @@ -11,6 +13,13 @@ project(':smeem-output-persistence:postgresql') { } } +project(':smeem-output-persistence:mongodb') { + dependencies { + // mongodb + implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' + } +} + allprojects { dependencies { implementation project(':smeem-common') diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml new file mode 100644 index 00000000..d7dae272 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml @@ -0,0 +1,10 @@ +spring: + config: + activate: + on-profile: dev + + data: + mongodb: + uri: mongodb://${MONGO_HOST}:27017/smeem + username: ${MONGO_USERNAME} + password: ${MONGO_PASSWORD} diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml new file mode 100644 index 00000000..8d4a8d01 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml @@ -0,0 +1,10 @@ +spring: + config: + activate: + on-profile: local + + data: + mongodb: + uri: mongodb://${MONGO_HOST}:27017/smeem + username: ${MONGO_USERNAME} + password: ${MONGO_PASSWORD} diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml new file mode 100644 index 00000000..c0a387a4 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml @@ -0,0 +1,10 @@ +spring: + config: + activate: + on-profile: prod + + data: + mongodb: + uri: mongodb://${MONGO_HOST}:27017/smeem + username: ${MONGO_USERNAME} + password: ${MONGO_PASSWORD} From 2919f3f9dab7da6770f1190d6df06544de18e234 Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:03:23 +0900 Subject: [PATCH 02/11] delete: deleted CorrectionEntity from postgresql --- .../postgresql/adapter/CorrectionAdapter.java | 42 ------------------- .../diary/CorrectionRepository.java | 15 ------- .../custom/CorrectionCustomRepository.java | 7 ---- .../custom/CorrectionRepositoryImpl.java | 33 --------------- 4 files changed, 97 deletions(-) delete mode 100644 smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/CorrectionAdapter.java delete mode 100644 smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/CorrectionRepository.java delete mode 100644 smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionCustomRepository.java delete mode 100644 smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionRepositoryImpl.java diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/CorrectionAdapter.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/CorrectionAdapter.java deleted file mode 100644 index 808fd27a..00000000 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/CorrectionAdapter.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.smeem.persistence.postgresql.adapter; - -import com.smeem.application.domain.diary.Correction; -import com.smeem.application.domain.diary.Diary; -import com.smeem.application.port.output.persistence.CorrectionPort; -import com.smeem.persistence.postgresql.persistence.entity.CorrectionEntity; -import com.smeem.persistence.postgresql.persistence.repository.diary.CorrectionRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -import java.time.LocalDate; -import java.util.List; -import java.util.UUID; - -@Component -@RequiredArgsConstructor -public class CorrectionAdapter implements CorrectionPort { - private final CorrectionRepository correctionRepository; - - @Override - public List saveAll(List corrections, Diary diary) { - UUID key = UUID.randomUUID(); - return correctionRepository.saveAll( - corrections.stream().map(it -> new CorrectionEntity(it, diary, key)).toList() - ).stream().map(CorrectionEntity::toDomain).toList(); - } - - @Override - public int countDistinctByMemberAndDate(long memberId, LocalDate date) { - return correctionRepository.countDistinctKeyByMemberIdAndCreatedAt(memberId, date); - } - - @Override - public List findByDiary(long diaryId) { - return correctionRepository.findByDiaryId(diaryId).stream().map(CorrectionEntity::toDomain).toList(); - } - - @Override - public void deleteByDiary(long diaryId) { - correctionRepository.deleteByDiaryId(diaryId); - } -} diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/CorrectionRepository.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/CorrectionRepository.java deleted file mode 100644 index 11a22a92..00000000 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/CorrectionRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.smeem.persistence.postgresql.persistence.repository.diary; - -import com.smeem.persistence.postgresql.persistence.entity.CorrectionEntity; -import com.smeem.persistence.postgresql.persistence.repository.diary.custom.CorrectionCustomRepository; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface CorrectionRepository extends JpaRepository, CorrectionCustomRepository { - void deleteByDiaryId(long diaryId); - - void deleteByMemberId(long memberId); - - List findByDiaryId(long diaryId); -} diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionCustomRepository.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionCustomRepository.java deleted file mode 100644 index 02dc21a8..00000000 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionCustomRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.smeem.persistence.postgresql.persistence.repository.diary.custom; - -import java.time.LocalDate; - -public interface CorrectionCustomRepository { - int countDistinctKeyByMemberIdAndCreatedAt(long memberId, LocalDate date); -} diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionRepositoryImpl.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionRepositoryImpl.java deleted file mode 100644 index 6cfc21e1..00000000 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/repository/diary/custom/CorrectionRepositoryImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.smeem.persistence.postgresql.persistence.repository.diary.custom; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; - -import static com.smeem.persistence.postgresql.persistence.entity.QCorrectionEntity.correctionEntity; - -@Repository -@RequiredArgsConstructor -public class CorrectionRepositoryImpl implements CorrectionCustomRepository { - private final JPAQueryFactory queryFactory; - - @Override - public int countDistinctKeyByMemberIdAndCreatedAt(long memberId, LocalDate date) { - LocalDateTime startOfDay = date.atStartOfDay(); - LocalDateTime endOfDay = date.atTime(LocalTime.MAX); - - return (int) queryFactory - .select(correctionEntity.key) - .from(correctionEntity) - .where( - correctionEntity.createdAt.between(startOfDay, endOfDay), - correctionEntity.memberId.eq(memberId) - ) - .distinct() - .stream().count(); - } -} From 3eff3250f792e65d300b32c97a606637a2fbcd3a Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:03:56 +0900 Subject: [PATCH 03/11] fix: updated correction of mongodb --- .../java/com/smeem/application/domain/auth/AuthService.java | 3 +++ .../smeem/persistence/postgresql/adapter/MemberAdapter.java | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smeem-application/src/main/java/com/smeem/application/domain/auth/AuthService.java b/smeem-application/src/main/java/com/smeem/application/domain/auth/AuthService.java index f854bfac..006bca2c 100644 --- a/smeem-application/src/main/java/com/smeem/application/domain/auth/AuthService.java +++ b/smeem-application/src/main/java/com/smeem/application/domain/auth/AuthService.java @@ -7,6 +7,7 @@ import com.smeem.application.port.input.dto.response.auth.GenerateTokenResponse; import com.smeem.application.port.input.dto.response.auth.SignInResponse; import com.smeem.application.port.output.oauth.OauthPort; +import com.smeem.application.port.output.persistence.CorrectionPort; import com.smeem.application.port.output.persistence.MemberPort; import com.smeem.common.logger.HookLogger; import com.smeem.common.logger.LoggingMessage; @@ -19,6 +20,7 @@ @RequiredArgsConstructor @Transactional(readOnly = true) public class AuthService implements AuthUseCase { + private final CorrectionPort correctionPort; private final MemberPort memberPort; private final OauthPort oauthPort; private final TokenGenerator tokenGenerator; @@ -54,6 +56,7 @@ public void signOut(long memberId) { @Transactional public void withdraw(long memberId, WithdrawRequest request) { + correctionPort.deleteByMember(memberId); memberPort.deleteById(memberId); createWithdrawal(request); } diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/MemberAdapter.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/MemberAdapter.java index 7974539f..70a46b46 100644 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/MemberAdapter.java +++ b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/adapter/MemberAdapter.java @@ -8,7 +8,6 @@ import com.smeem.persistence.postgresql.persistence.entity.MemberEntity; import com.smeem.persistence.postgresql.persistence.entity.WithdrawEntity; import com.smeem.persistence.postgresql.persistence.repository.*; -import com.smeem.persistence.postgresql.persistence.repository.diary.CorrectionRepository; import lombok.RequiredArgsConstructor; import lombok.val; import org.springframework.stereotype.Repository; @@ -20,7 +19,6 @@ @Repository @RequiredArgsConstructor public class MemberAdapter implements MemberPort { - private final CorrectionRepository correctionRepository; private final MemberRepository memberRepository; private final MemberBadgeRepository memberBadgeRepository; private final DeletedDiaryRepository deletedDiaryRepository; @@ -57,7 +55,6 @@ public void deleteById(long id) { diaryRepository.deleteByMemberId(id); trainingTimeRepository.deleteByMemberId(id); memberRepository.deleteById(id); - correctionRepository.deleteByMemberId(id); } @Override From e3c8abf2dbd3c32552d702b574fcb34555b30e21 Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:05:12 +0900 Subject: [PATCH 04/11] add: added correction document --- .../mongodb/adapter/CorrectionAdapter.java | 50 +++++++++++++++ .../mongodb/config/MongoConfig.java | 29 +++++++++ .../document/CorrectionDocument.java | 61 +++++++++++++++++++ .../repository/CorrectionRepository.java | 19 ++++++ .../persistence/entity/CorrectionEntity.java | 53 ---------------- 5 files changed, 159 insertions(+), 53 deletions(-) create mode 100644 smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/adapter/CorrectionAdapter.java create mode 100644 smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/config/MongoConfig.java create mode 100644 smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java create mode 100644 smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/repository/CorrectionRepository.java delete mode 100644 smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/entity/CorrectionEntity.java diff --git a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/adapter/CorrectionAdapter.java b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/adapter/CorrectionAdapter.java new file mode 100644 index 00000000..1a8c76a2 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/adapter/CorrectionAdapter.java @@ -0,0 +1,50 @@ +package com.smeem.output.persistence.mongodb.adapter; + +import com.smeem.application.domain.diary.Correction; +import com.smeem.application.domain.diary.Diary; +import com.smeem.application.port.output.persistence.CorrectionPort; +import com.smeem.output.persistence.mongodb.persistence.document.CorrectionDocument; +import com.smeem.output.persistence.mongodb.persistence.repository.CorrectionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class CorrectionAdapter implements CorrectionPort { + private final CorrectionRepository correctionRepository; + + @Override + public List save(List corrections, Diary diary) { + CorrectionDocument savedCorrection = correctionRepository.save(new CorrectionDocument(corrections, diary)); + return savedCorrection.toDomain(); + } + + @Override + public int countDistinctByMemberAndDate(long memberId, LocalDate date) { + LocalDateTime startOfDay = date.atStartOfDay(); + LocalDateTime endOfDay = date.plusDays(1).atStartOfDay(); + return correctionRepository.countByMemberIdAndCreatedAtBetween(memberId, startOfDay, endOfDay); + } + + @Override + public List findByDiary(long diaryId) { + return correctionRepository.findByDiaryId(diaryId) + .map(CorrectionDocument::toDomain) + .orElseGet(ArrayList::new); + } + + @Override + public void deleteByDiary(long diaryId) { + correctionRepository.deleteByDiaryId(diaryId); + } + + @Override + public void deleteByMember(long memberId) { + correctionRepository.deleteByMemberId(memberId); + } +} diff --git a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/config/MongoConfig.java b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/config/MongoConfig.java new file mode 100644 index 00000000..2ed417a5 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/config/MongoConfig.java @@ -0,0 +1,29 @@ +package com.smeem.output.persistence.mongodb.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.config.EnableMongoAuditing; +import org.springframework.data.mongodb.core.convert.DbRefResolver; +import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; +import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper; +import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@Configuration +@EnableMongoAuditing +@EnableMongoRepositories(basePackages = "com.smeem.output.persistence.mongodb") +public class MongoConfig { + + @Bean + public MappingMongoConverter mappingMongoConverter( + MongoDatabaseFactory mongoDatabaseFactory, + MongoMappingContext mongoMappingContext + ) { + DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory); + MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext); + converter.setTypeMapper(new DefaultMongoTypeMapper(null)); + return converter; + } +} diff --git a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java new file mode 100644 index 00000000..14c3ee3b --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java @@ -0,0 +1,61 @@ +package com.smeem.output.persistence.mongodb.persistence.document; + +import com.smeem.application.domain.diary.Correction; +import com.smeem.application.domain.diary.Diary; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.LocalDateTime; +import java.util.List; + +@Document(collation = "smeem") +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CorrectionDocument { + @Id + private String id; + private List corrections; + private long memberId; + private long diaryId; + @CreatedDate + private LocalDateTime createdAt; + + @NoArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + private static class CorrectionDetail { + private String originContent; + private String correctedContent; + private String reason; + private boolean corrected; + + public CorrectionDetail(Correction correction) { + this.originContent = correction.originalSentence(); + this.correctedContent = correction.correctedSentence(); + this.corrected = correction.isCorrected(); + this.reason = corrected ? correction.reason() : null; + } + + public Correction toDomain() { + return Correction.builder() + .originalSentence(originContent) + .correctedSentence(correctedContent) + .reason(reason) + .isCorrected(corrected) + .build(); + } + } + + public CorrectionDocument(List corrections, Diary diary) { + this.corrections = corrections.stream().map(CorrectionDetail::new).toList(); + this.memberId = diary.getMemberId(); + this.diaryId = diary.getId(); + } + + public List toDomain() { + return this.corrections.stream().map(CorrectionDetail::toDomain).toList(); + } +} diff --git a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/repository/CorrectionRepository.java b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/repository/CorrectionRepository.java new file mode 100644 index 00000000..488e9bf7 --- /dev/null +++ b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/repository/CorrectionRepository.java @@ -0,0 +1,19 @@ +package com.smeem.output.persistence.mongodb.persistence.repository; + +import com.smeem.output.persistence.mongodb.persistence.document.CorrectionDocument; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; +import java.util.Optional; + +@Repository +public interface CorrectionRepository extends MongoRepository { + int countByMemberIdAndCreatedAtBetween(long memberId, LocalDateTime startAt, LocalDateTime endAt); + + Optional findByDiaryId(long diaryId); + + void deleteByDiaryId(long diaryId); + + void deleteByMemberId(long memberId); +} diff --git a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/entity/CorrectionEntity.java b/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/entity/CorrectionEntity.java deleted file mode 100644 index f213acd2..00000000 --- a/smeem-output-persistence/postgresql/src/main/java/com/smeem/persistence/postgresql/persistence/entity/CorrectionEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.smeem.persistence.postgresql.persistence.entity; - -import com.smeem.application.domain.diary.Correction; -import com.smeem.application.domain.diary.Diary; -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import java.util.UUID; - -@Entity -@Table(name = "correction", schema = "smeem") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class CorrectionEntity extends BaseEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(columnDefinition = "TEXT", nullable = false) - private String originContent; - - @Column(columnDefinition = "TEXT", nullable = false) - private String correctedContent; - - @Column(columnDefinition = "TEXT", nullable = false) - private String reason; - - @Column(nullable = false) - private long memberId; - - @Column(nullable = false) - private long diaryId; - - @Column(nullable = false) - private UUID key; - - public CorrectionEntity(Correction correction, Diary diary, UUID key) { - this.originContent = correction.originalSentence(); - this.correctedContent = correction.correctedSentence(); - this.reason = correction.reason(); - this.memberId = diary.getMemberId(); - this.diaryId = diary.getId(); - this.key = key; - } - - public Correction toDomain() { - return Correction.builder() - .originalSentence(originContent) - .correctedSentence(correctedContent) - .reason(reason) - .build(); - } -} From 59f4abbd655b94189aa31582cd8492c75d055188 Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:05:25 +0900 Subject: [PATCH 05/11] fix: updated method name --- .../smeem/application/domain/diary/CorrectionService.java | 5 ++++- .../application/port/output/persistence/CorrectionPort.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/smeem-application/src/main/java/com/smeem/application/domain/diary/CorrectionService.java b/smeem-application/src/main/java/com/smeem/application/domain/diary/CorrectionService.java index 6d18d248..1a0c60a3 100644 --- a/smeem-application/src/main/java/com/smeem/application/domain/diary/CorrectionService.java +++ b/smeem-application/src/main/java/com/smeem/application/domain/diary/CorrectionService.java @@ -30,12 +30,15 @@ public CorrectionsResponse correctDiary(long memberId, long diaryId) { LocalDate today = LocalDate.now(); String key = getCorrectionCacheKey(memberId, today); + // 제한 횟수 검증 int correctionCount = getOrUpdateCorrectionCount(key, memberId, today); smeemProperties.getLimit().validateCorrectionLimit(correctionCount); + // 일기 소유권 검증 Diary diary = diaryPort.findById(diaryId); diary.validateDiaryOwnership(memberId); + // AI 첨삭 및 캐시 업데이트 List corrections = createCorrections(diary); cachePort.incrementInt(key); @@ -60,6 +63,6 @@ private int updateCacheWithCorrectionCount(String key, long memberId, LocalDate private List createCorrections(Diary diary) { List corrections = openAiPort.promptCorrections(diary.getContent()); - return correctionPort.saveAll(corrections, diary); + return correctionPort.save(corrections, diary); } } diff --git a/smeem-application/src/main/java/com/smeem/application/port/output/persistence/CorrectionPort.java b/smeem-application/src/main/java/com/smeem/application/port/output/persistence/CorrectionPort.java index 0b2716cc..737a8178 100644 --- a/smeem-application/src/main/java/com/smeem/application/port/output/persistence/CorrectionPort.java +++ b/smeem-application/src/main/java/com/smeem/application/port/output/persistence/CorrectionPort.java @@ -7,11 +7,13 @@ import java.util.List; public interface CorrectionPort { - List saveAll(List corrections, Diary diary); + List save(List corrections, Diary diary); int countDistinctByMemberAndDate(long memberId, LocalDate date); List findByDiary(long diary); void deleteByDiary(long diaryId); + + void deleteByMember(long memberId); } From 00f8bf49901adcebb1cebe8ea9d87d16b37701b4 Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 16:05:42 +0900 Subject: [PATCH 06/11] fix: updated prompt --- .../application/domain/diary/Correction.java | 5 ++- .../output/web/gpt/adapter/OpenAiAdapter.java | 42 +++---------------- .../gpt/adapter/template/PromptTemplate.java | 15 +++++++ .../gpt/adapter/template/SchemeTemplate.java | 29 +++++++++++++ 4 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java create mode 100644 smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java diff --git a/smeem-application/src/main/java/com/smeem/application/domain/diary/Correction.java b/smeem-application/src/main/java/com/smeem/application/domain/diary/Correction.java index fc1c9e21..2baba242 100644 --- a/smeem-application/src/main/java/com/smeem/application/domain/diary/Correction.java +++ b/smeem-application/src/main/java/com/smeem/application/domain/diary/Correction.java @@ -14,6 +14,9 @@ public record Correction( String correctedSentence, @Schema(description = "교정 사유", example = "스펠링 틀림") @JsonProperty("reason") - String reason + String reason, + @Schema(description = "교정 여부", example = "true") + @JsonProperty("is_corrected") + boolean isCorrected ) { } diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/OpenAiAdapter.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/OpenAiAdapter.java index aa5becfa..b7d51fd7 100644 --- a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/OpenAiAdapter.java +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/OpenAiAdapter.java @@ -7,6 +7,8 @@ import com.smeem.common.exception.ExceptionCode; import com.smeem.common.exception.SmeemException; import com.smeem.output.web.gpt.adapter.dto.CorrectionsResponse; +import com.smeem.output.web.gpt.adapter.template.PromptTemplate; +import com.smeem.output.web.gpt.adapter.template.SchemeTemplate; import lombok.RequiredArgsConstructor; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatResponse; @@ -18,6 +20,8 @@ import java.util.List; +import static org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ResponseFormat.Type.JSON_SCHEMA; + @Component @RequiredArgsConstructor public class OpenAiAdapter implements OpenAiPort { @@ -39,34 +43,11 @@ public String prompt(String message) { @Override public List promptCorrections(String content) { - String jsonSchema = """ - { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "original_sentence": {"type": "string"}, - "corrected_sentence": {"type": "string"}, - "reason": {"type": "string"} - }, - "required": ["original_sentence", "corrected_sentence", "reason"], - "additionalProperties": false - } - } - }, - "required": ["results"], - "additionalProperties": false - } - """; - OpenAiChatOptions options = OpenAiChatOptions.builder() - .withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, jsonSchema)) + .withResponseFormat(new ResponseFormat(JSON_SCHEMA, SchemeTemplate.getCorrectionScheme())) .build(); - Prompt prompt = new Prompt(getCorrectionPrompt(content), options); + Prompt prompt = new Prompt(PromptTemplate.getCorrectionPrompt(content), options); ChatResponse call = chatModel.call(prompt); String response = call.getResult().getOutput().getContent(); @@ -76,15 +57,4 @@ public List promptCorrections(String content) { throw new SmeemException(ExceptionCode.OPEN_AI_SERVICE_AVAILABLE, e.getMessage()); } } - - private String getCorrectionPrompt(String content) { - return String.format(""" - Paragraph : %s - - JSON response description: - - original_sentence: Separate sentence from paragraph, including whitespace, spaces and special characters exactly as they appear in the original. - - corrected_sentence: corrected sentence including correct expressions. - - reason: this value MUST be Korean. reason is why the sentence is corrected. - """, content); - } } diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java new file mode 100644 index 00000000..ebd27c39 --- /dev/null +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java @@ -0,0 +1,15 @@ +package com.smeem.output.web.gpt.adapter.template; + +public class PromptTemplate { + public static String getCorrectionPrompt(String content) { + return String.format(""" + Paragraph : %s + + JSON response description: + - original_sentence: The original sentence exactly as it appears. + - corrected_sentence: The corrected sentence (if correct, repeat the original). + - reason: The reason for the correction, explained in Korean. + - is_correct: Whether the sentence has been corrected. Set to true if corrected, and false if unchanged. + """, content); + } +} diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java new file mode 100644 index 00000000..c9bca9a3 --- /dev/null +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java @@ -0,0 +1,29 @@ +package com.smeem.output.web.gpt.adapter.template; + +public class SchemeTemplate { + public static String getCorrectionScheme() { + return """ + { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "original_sentence": {"type": "string"}, + "corrected_sentence": {"type": "string"}, + "reason": {"type": "string"}, + "is_corrected": {"type": "boolean"}, + }, + "required": ["original_sentence", "corrected_sentence", "reason"], + "additionalProperties": false + } + } + }, + "required": ["results"], + "additionalProperties": false + } + """; + } +} From 6460260c86d731dfcd7f29e3edd2d8c55421727e Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 23:50:22 +0900 Subject: [PATCH 07/11] fix: updated uri --- .../src/main/resources/mongo-config/application-dev.yml | 4 +--- .../src/main/resources/mongo-config/application-local.yml | 4 +--- .../src/main/resources/mongo-config/application-prod.yml | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml index d7dae272..92508d89 100644 --- a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-dev.yml @@ -5,6 +5,4 @@ spring: data: mongodb: - uri: mongodb://${MONGO_HOST}:27017/smeem - username: ${MONGO_USERNAME} - password: ${MONGO_PASSWORD} + uri: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:27017/smeem?authSource=admin diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml index 8d4a8d01..f25539d2 100644 --- a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-local.yml @@ -5,6 +5,4 @@ spring: data: mongodb: - uri: mongodb://${MONGO_HOST}:27017/smeem - username: ${MONGO_USERNAME} - password: ${MONGO_PASSWORD} + uri: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:27017/smeem?authSource=admin diff --git a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml index c0a387a4..0864abba 100644 --- a/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml +++ b/smeem-output-persistence/mongodb/src/main/resources/mongo-config/application-prod.yml @@ -5,6 +5,4 @@ spring: data: mongodb: - uri: mongodb://${MONGO_HOST}:27017/smeem - username: ${MONGO_USERNAME} - password: ${MONGO_PASSWORD} + uri: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:27017/smeem?authSource=admin From 67f03a78341b871fc8e3932d32bc8bff137703bb Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 23:50:34 +0900 Subject: [PATCH 08/11] fix: updated option --- .../mongodb/persistence/document/CorrectionDocument.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java index 14c3ee3b..aaebc735 100644 --- a/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java +++ b/smeem-output-persistence/mongodb/src/main/java/com/smeem/output/persistence/mongodb/persistence/document/CorrectionDocument.java @@ -12,7 +12,7 @@ import java.time.LocalDateTime; import java.util.List; -@Document(collation = "smeem") +@Document(collection = "smeem") @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class CorrectionDocument { From dc05cc5298c8ffcfbad3be617c55c1062cc29ebf Mon Sep 17 00:00:00 2001 From: thguss Date: Sat, 26 Oct 2024 23:50:50 +0900 Subject: [PATCH 09/11] fix: updated correction scheme --- .../smeem/output/web/gpt/adapter/template/SchemeTemplate.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java index c9bca9a3..a83c6b4b 100644 --- a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/SchemeTemplate.java @@ -14,9 +14,9 @@ public static String getCorrectionScheme() { "original_sentence": {"type": "string"}, "corrected_sentence": {"type": "string"}, "reason": {"type": "string"}, - "is_corrected": {"type": "boolean"}, + "is_corrected": {"type": "boolean"} }, - "required": ["original_sentence", "corrected_sentence", "reason"], + "required": ["original_sentence", "corrected_sentence", "reason", "is_corrected"], "additionalProperties": false } } From 61c41544ebf1664dbd590ac92cde94983deae60a Mon Sep 17 00:00:00 2001 From: thguss Date: Tue, 29 Oct 2024 22:54:02 +0900 Subject: [PATCH 10/11] add: added sentence in prompt --- .../smeem/output/web/gpt/adapter/template/PromptTemplate.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java index ebd27c39..204d9372 100644 --- a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java @@ -4,6 +4,8 @@ public class PromptTemplate { public static String getCorrectionPrompt(String content) { return String.format(""" Paragraph : %s + + Please correct the following English sentences, determine whether each sentence is correct or incorrect, and generate a JSON response in the specified format. The JSON format should be as follows: JSON response description: - original_sentence: The original sentence exactly as it appears. From cdb01b6bb2f1f29a6899b9c16296462a5907dbb7 Mon Sep 17 00:00:00 2001 From: thguss Date: Tue, 29 Oct 2024 22:58:24 +0900 Subject: [PATCH 11/11] add: added sentence in prompt --- .../smeem/output/web/gpt/adapter/template/PromptTemplate.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java index 204d9372..aaf2246a 100644 --- a/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java +++ b/smeem-output-web/gpt/src/main/java/com/smeem/output/web/gpt/adapter/template/PromptTemplate.java @@ -5,7 +5,9 @@ public static String getCorrectionPrompt(String content) { return String.format(""" Paragraph : %s - Please correct the following English sentences, determine whether each sentence is correct or incorrect, and generate a JSON response in the specified format. The JSON format should be as follows: + Please correct the following English sentences, determine whether each sentence is correct or incorrect, and generate a JSON response in the specified format. + Make sure to keep the order of the sentences. + The JSON format should be as follows: JSON response description: - original_sentence: The original sentence exactly as it appears.