meloning / mega-coffee-employee-manage-project Goto Github PK
View Code? Open in Web Editor NEW클린 아키텍처, 멀티모듈기반 사이드 프로젝트입니다.
클린 아키텍처, 멀티모듈기반 사이드 프로젝트입니다.
유저(직원)가 교육 장소를 등록할때 동시에 같은 장소를 등록할 경우 수강인원 검증 처리에 대한 작업이 필요합니다.
현재 신청된 수강인원을 매핑 테이블을 통해 count하여 가져와 비교하는데 역정규화하여 현재 수강인원 필드를 추가함과 동시에 동시성 처리를 위한 Lock을 적용할지등 고민이 필요한 부분입니다. (Redis 이용도 고려할 것)
교육프로그램은 여러 교육장소들을 가질 수 있으며, 하나의 교육장소는 반드시 하나의 교육프로그램에 속해야한다.
매장은 여러 교육프로그램을 들을 수 있고, 하나의 교육 프로그램은 여러 매장이 들어야할 교육 프로그램이 될수 있다.
유저는 여러 교육장소를 선택하여 등록할 수 있으며, 하나의 교육장소는 여러 참여자(유저)들을 수용할 수 있다.
#2 이슈를 통해 Redoc 문서 템플릿으로 generate될 수 있도록 OAS Spec에 맞게 yaml파일을 성공적으로 만들었습니다.
이제 API 문서를 보여줄 Github Pages용 저장소를 만들고, redoc cli 명령어와 Github Action workflow를 통해 문서 배포 파이프라인을 구축할려고 합니다.
(이거 끝나고 Redoc 도입과정에 대한 내용과 함께 wiki 문서를 전반적으로 깔끔하게 정리한 후, README.md 내용도 그에 맞게 변경할 예정입니다.)
Q. MySQL과 같은 RDB에도 적용해야 할까?
2024-05-06T07:36:29.152638Z 0 [ERROR] [MY-000068] [Server] unknown option '--skip-host-cache'.
2024-05-06T07:36:29.153652Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
특정 매장이 들어야할 교육 프로그램을 등록할때 교육 프로그램에 대한 간략한 내용을 프로그램 대상자들에게 알림을 주는 기능입니다.
EducationAddress 보단 EducationPlace가 더 직관적으로 도메인 이름을 알수 있다.
구현된 코드의 일부분에는 Place 이름으로 함수나 변수명을 활용한게 있는데 나중에 바꿔야지하면서 쭉 미뤄온터라 이제야 올바른 이름으로 변경할려고 합니다.
클래스명, 변수명, 함수명, Api Path까지 address를 place로 적절하게 변경할 예정입니다.
교육 프로그램 내에서 신청한 교육 장소들의 시작 시간을 기준으로 당일 1시간전 알림을 주는 기능입니다.
Quartz의 Trigger와 Job Chaining을 활용하여 기능 구현할 예정입니다.
DomainFixture 클래스를 통해 어느정도 변하지 않은 테스트 객체 생성을 한곳에서 관리하고자 만들어 사용했습니다.
하지만 매번 상황에 따른 필요한 데이터를 만드는 시점에 별도로 넣어 만들고 사용할려다 보니 유지보수하기 어려운 부분이 있었습니다.
Type 또는 상황별 만들고자 하는 테스트 객체를 고정값으로 factory method를 통해 만들도록 처리하고, validation 조건에서 벗어나지 않은 범위 내에서 랜덤하게 값을 생성하여 테스트객체가 generate 되도록 하는 것이 필요했습니다.
이를 Object Mother 패턴 구조와 EasyRandom 을 활용하여 테스트 객체 생성 구조를 개선하고자 합니다.
GithubAction CI로 PR 올릴시 자동으로 테스트코드가 돌아갈 수 있도록 설정할 예정입니다.
유저는 Soft Delete를 하지만 read하는 과정에서 조건이 포함되어 있지 않다.
매장은 Hard Delete로 실제 매장 정보를 삭제하는 기능으로 구현되어져 있다.
이를 Soft Delete로 변경하고 read 구현부분에서 조건을 추가해 테스트해야 한다.
Transaction 과 강결합 된 코드나 TransactionalEventListener 는 자원 활용 측면에서 효율적인지 고민 해보시면 좋을 것 같습니다
UserService 의 경우는 전역적으로 Transaction 가 걸려있는데
자세히 살펴보진 않았지만 registerEducationAddress 에서 Transaction 이 필요한 부분은 국소적일 것 같습니다
Q. 전역적으로 Transaction을 반드시 걸어야할까?
[Reference]
https://www.youtube.com/watch?v=18C2A56ialY
레퍼런스 영상에서는 트랜잭션 처리를 3가지 방법으로 소개하고 있습니다.
@Transactional
을 붙이는 것 (spring-context를 추가한 이유와 같음)@Transactional
을 활용하는 것
현재 프로젝트에서는 core 모듈 내 @Transactional
적용을 위해 spring-tx 라이브러리를 추가하여 활용하는 것으로 결정하였습니다.
당연하게도 데이터 무결성을 지키고자 비즈니스 로직 전반에 트랜잭션을 걸어주었는데
위 피드백 의견으로 볼때 과연 트랜잭션 범위가 비즈니스 로직 전체 범위로 잡아야하는지, 전부 무결성 보장을 위한 롤백 대상이 되어야하는지 의구심이 들어 이를 해결해보고자 합니다.
프로젝트 root 내 build.gradle.kts
plugins {
id("org.springframework.boot") apply false
id("io.spring.dependency-management") apply false
id("org.jmailen.kotlinter")
id("com.epages.restdocs-api-spec") apply false // epages 플러그인 추가 version은 settings.gradle에서 적용할 것.
kotlin("jvm")
kotlin("kapt")
kotlin("plugin.spring") apply false
kotlin("plugin.jpa") apply false
}
...
val restDocsProject = listOf(
project(":mega-coffee-api"), // Admin API가 추가될 수 있으니 list로 미리 선언
)
configure(restDocsProject) {
apply(plugin = "com.epages.restdocs-api-spec")
extensions.extraProperties["snippetsDir"] = file("build/generated-snippets")
val epagesVersion: String by project
dependencies {
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
testImplementation("com.epages:restdocs-api-spec:$epagesVersion")
testImplementation("com.epages:restdocs-api-spec-mockmvc:$epagesVersion")
}
/**
* @see <a href="https://github.com/ePages-de/restdocs-api-spec">Spring REST Docs API specification Integration</a>
*/
configure<OpenApi3Extension> {
setServer("http://localhost:9000")
title = "MGC Employee Manage OpenApi Specification"
version = "1.0.0"
format = "yaml"
}
tasks.named("bootJar") {
doLast {
val sourceDir = project.file("swagger-ui")
val yamlFile = project.file("${project.buildDir}/api-spec/openapi3.yaml")
val targetDir = project.file("build/classes/kotlin/main/BOOT-INF/classes/static/swagger-ui")
copy {
from(sourceDir) {
into(targetDir)
}
from(yamlFile) {
into(targetDir)
}
}
}
}
}
이렇게 구성한 후 Redoc으로 열어서 API 문서들을 확인하면 될것 같다.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.