Skip to content

Commit 4531d0f

Browse files
committed
Merge branch 'master' of https://github.com/GSM-MSG/SMS-BackEnd into develop
2 parents de08ba4 + a8f8796 commit 4531d0f

33 files changed

+520
-5
lines changed

.github/workflows/sms_backend_master_cd.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
on:
22
push:
33
branches: [ "master" ]
4+
workflow_dispatch:
45

56
jobs:
67
CD:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package team.msg.sms.common.util
2+
3+
import java.security.SecureRandom
4+
import java.util.stream.Collectors
5+
import java.util.stream.IntStream
6+
7+
object PasswordUtil {
8+
// 소문자와 숫자로 이루어진 length 만큼의 길이를 가진 문자열을 생성하는 함수
9+
fun generateSecret(length: Int): String {
10+
val secureRandom = SecureRandom()
11+
12+
val password = IntStream.concat(
13+
IntStream.rangeClosed(48, 57),
14+
IntStream.rangeClosed(97, 122)
15+
).mapToObj { i -> i.toChar().toString() }.collect(Collectors.joining())
16+
17+
val builder = StringBuilder()
18+
19+
for (i in 0 until length) {
20+
builder.append(password[secureRandom.nextInt(password.length)])
21+
}
22+
23+
return builder.toString()
24+
}
25+
}

sms-core/src/main/kotlin/team/msg/sms/domain/auth/usecase/SignInUseCase.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,22 @@ class SignInUseCase(
3333
val role = userService.getRoleByGAuthInfo(gAuthUserInfo.email, gAuthUserInfo.role)
3434

3535
val isExistsUser = userService.checkUserExistByEmail(gAuthUserInfo.email)
36+
37+
val stuNum = getStuNumValid(role, gAuthUserInfo)
38+
3639
val user = userService.createUserWhenNotExistUser(
3740
isExistsUser,
3841
User(
3942
name = gAuthUserInfo.name,
4043
email = gAuthUserInfo.email,
41-
stuNum = getStuNumValid(role, gAuthUserInfo),
44+
stuNum = stuNum,
4245
roles = mutableListOf(role)
4346
)
4447
)
4548

49+
if(user.stuNum != stuNum)
50+
userService.updateStuNum(user, stuNum)
51+
4652
val (accessToken, accessTokenExp, refreshToken, refreshTokenExp) = jwtPort.receiveToken(user.id, role)
4753

4854
refreshTokenPort.saveRefreshToken(RefreshToken(refreshToken, user.id))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package team.msg.sms.domain.student.dto.req
2+
3+
import java.util.UUID
4+
5+
data class CreateStudentLinkRequestData (
6+
val studentId: UUID,
7+
val periodDay: Long
8+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package team.msg.sms.domain.student.dto.res
2+
3+
data class CreateStudentLinkResponseData (
4+
val token: String
5+
)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package team.msg.sms.domain.student.dto.res
2+
3+
import team.msg.sms.domain.languagecertificate.model.LanguageCertificate
4+
import team.msg.sms.domain.prize.dto.res.PrizeResponseData
5+
import team.msg.sms.domain.project.dto.res.ProjectResponseData
6+
import team.msg.sms.domain.student.model.Department
7+
import team.msg.sms.domain.student.model.FormOfEmployment
8+
import team.msg.sms.domain.student.model.MilitaryService
9+
10+
data class DetailStudentInfoTokenResponseData(
11+
val name: String,
12+
val introduce: String,
13+
val portfolioUrl: String?,
14+
val grade: Int,
15+
val classNum: Int,
16+
val number: Int,
17+
val department: Department,
18+
val major: String,
19+
val profileImg: String,
20+
val contactEmail: String,
21+
val gsmAuthenticationScore: Int,
22+
val formOfEmployment: FormOfEmployment,
23+
val regions: List<String>, // 근무지역
24+
val militaryService: MilitaryService,
25+
val salary: Int,
26+
val languageCertificates: List<LanguageCertificate.LanguageCertificateScore>,
27+
val certificates: List<String>,
28+
val techStacks: List<String>,
29+
val projects: List<ProjectResponseData>,
30+
val prizes: List<PrizeResponseData>
31+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package team.msg.sms.domain.student.exception
2+
3+
import team.msg.sms.common.error.SmsException
4+
import team.msg.sms.domain.student.exception.error.StudentErrorCode
5+
6+
object StudentLinkNotFoundException : SmsException(
7+
StudentErrorCode.STUDENT_LINK_NOT_FOUND
8+
)

sms-core/src/main/kotlin/team/msg/sms/domain/student/exception/error/StudentErrorCode.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum class StudentErrorCode(
1111
STUDENT_NOT_FOUND(ErrorStatus.NOT_FOUND, "학생이 존재하지 않습니다."),
1212
STU_NUM_NOR_RIGHT(ErrorStatus.BAD_REQUEST, "올바르지 않은 학번입니다."),
1313
STUDENT_ALREADY(ErrorStatus.CONFLICT, "학생 정보가 존재하는 유저입니다"),
14+
STUDENT_LINK_NOT_FOUND(ErrorStatus.CONFLICT, "학생 열람 정보가 존재하지 않습니다."),
1415
;
1516

1617
override fun status(): Int = status
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package team.msg.sms.domain.student.model
2+
3+
import team.msg.sms.common.annotation.Aggregate
4+
import java.util.UUID
5+
6+
@Aggregate
7+
data class StudentLink(
8+
val token: String,
9+
val studentId: UUID,
10+
val timeToLive: Long
11+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package team.msg.sms.domain.student.service
2+
3+
interface CheckStudentLinkService {
4+
fun checkExistsByToken(token: String): Boolean
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package team.msg.sms.domain.student.service
2+
3+
import team.msg.sms.domain.student.model.StudentLink
4+
5+
interface CommandStudentLinkService {
6+
fun save(
7+
studentLink: StudentLink
8+
): StudentLink
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package team.msg.sms.domain.student.service
2+
3+
import team.msg.sms.domain.student.model.Student.StudentWithUserInfo
4+
5+
interface GetStudentLinkService {
6+
fun getStudentUserInfoByToken(token: String) : StudentWithUserInfo
7+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package team.msg.sms.domain.student.service
2+
3+
import team.msg.sms.common.annotation.Service
4+
5+
@Service
6+
class StudentLinkService (
7+
commandStudentLinkService: CommandStudentLinkService,
8+
checkStudentLinkService: CheckStudentLinkService,
9+
getStudentLinkService: GetStudentLinkService
10+
) : CommandStudentLinkService by commandStudentLinkService,
11+
CheckStudentLinkService by checkStudentLinkService,
12+
GetStudentLinkService by getStudentLinkService
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package team.msg.sms.domain.student.service.impl
2+
3+
import team.msg.sms.common.annotation.Service
4+
import team.msg.sms.domain.student.service.CheckStudentLinkService
5+
import team.msg.sms.domain.student.spi.StudentLinkPort
6+
7+
@Service
8+
class CheckStudentLinkServiceImpl (
9+
private val studentLinkPort: StudentLinkPort
10+
) : CheckStudentLinkService {
11+
override fun checkExistsByToken(token: String): Boolean {
12+
return studentLinkPort.existsByToken(token)
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package team.msg.sms.domain.student.service.impl
2+
3+
import team.msg.sms.common.annotation.Service
4+
import team.msg.sms.domain.student.model.StudentLink
5+
import team.msg.sms.domain.student.service.CommandStudentLinkService
6+
import team.msg.sms.domain.student.spi.StudentLinkPort
7+
8+
@Service
9+
class CommandStudentLinkServiceImpl(
10+
private val studentLinkPort: StudentLinkPort
11+
): CommandStudentLinkService {
12+
override fun save(studentLink: StudentLink): StudentLink {
13+
return studentLinkPort.save(studentLink)
14+
}
15+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package team.msg.sms.domain.student.service.impl
2+
3+
import team.msg.sms.common.annotation.Service
4+
import team.msg.sms.domain.student.exception.StudentLinkNotFoundException
5+
import team.msg.sms.domain.student.exception.StudentNotFoundException
6+
import team.msg.sms.domain.student.model.Student.StudentWithUserInfo
7+
import team.msg.sms.domain.student.service.GetStudentLinkService
8+
import team.msg.sms.domain.student.spi.StudentLinkPort
9+
import team.msg.sms.domain.student.spi.StudentPort
10+
11+
@Service
12+
class GetStudentLinkServiceImpl(
13+
private val studentLinkPort: StudentLinkPort,
14+
private val studentPort: StudentPort
15+
) : GetStudentLinkService {
16+
override fun getStudentUserInfoByToken(token: String): StudentWithUserInfo {
17+
val studentId = studentLinkPort.findStudentIdByToken(token) ?: throw StudentNotFoundException
18+
val studentWithUserInfo = studentPort.queryStudentWithUserInfoById(studentId) ?: throw StudentLinkNotFoundException
19+
20+
return studentWithUserInfo
21+
}
22+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package team.msg.sms.domain.student.spi
2+
3+
import team.msg.sms.domain.student.model.StudentLink
4+
5+
interface CommandStudentLinkPort {
6+
fun save(studentLink: StudentLink): StudentLink
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package team.msg.sms.domain.student.spi
2+
3+
import java.util.UUID
4+
5+
interface QueryStudentLinkPort {
6+
fun existsByToken(token: String): Boolean
7+
fun findStudentIdByToken(token: String): UUID?
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package team.msg.sms.domain.student.spi
2+
3+
interface StudentLinkPort:
4+
CommandStudentLinkPort,
5+
QueryStudentLinkPort
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package team.msg.sms.domain.student.usecase
2+
3+
import team.msg.sms.common.annotation.UseCase
4+
import team.msg.sms.common.util.PasswordUtil.generateSecret
5+
import team.msg.sms.domain.student.dto.req.CreateStudentLinkRequestData
6+
import team.msg.sms.domain.student.dto.res.CreateStudentLinkResponseData
7+
import team.msg.sms.domain.student.model.StudentLink
8+
import team.msg.sms.domain.student.service.StudentLinkService
9+
import team.msg.sms.domain.student.service.StudentService
10+
import java.util.*
11+
12+
@UseCase
13+
class CreateStudentLinkUseCase (
14+
private val studentService: StudentService,
15+
private val studentLinkService: StudentLinkService,
16+
) {
17+
fun execute(createStudentLinkData: CreateStudentLinkRequestData): CreateStudentLinkResponseData {
18+
val student = studentService.getStudentById(createStudentLinkData.studentId)
19+
val token = generateSecret(32)
20+
21+
val studentLink = StudentLink(
22+
token = token,
23+
studentId = student.id,
24+
timeToLive = createStudentLinkData.periodDay * 86400
25+
)
26+
studentLinkService.save(studentLink)
27+
28+
return CreateStudentLinkResponseData(
29+
token = token
30+
)
31+
}
32+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package team.msg.sms.domain.student.usecase
2+
3+
import team.msg.sms.common.annotation.UseCase
4+
import team.msg.sms.common.util.PrizeUtil.generatePrizeResponseData
5+
import team.msg.sms.common.util.ProjectUtil.generateProjectResponseData
6+
import team.msg.sms.domain.certificate.service.CertificateService
7+
import team.msg.sms.domain.file.service.ImageService
8+
import team.msg.sms.domain.languagecertificate.model.LanguageCertificate
9+
import team.msg.sms.domain.languagecertificate.service.LanguageCertificateService
10+
import team.msg.sms.domain.prize.service.PrizeService
11+
import team.msg.sms.domain.project.service.ProjectLinkService
12+
import team.msg.sms.domain.project.service.ProjectService
13+
import team.msg.sms.domain.project.service.ProjectTechStackService
14+
import team.msg.sms.domain.region.service.RegionService
15+
import team.msg.sms.domain.student.dto.res.DetailStudentInfoTokenResponseData
16+
import team.msg.sms.domain.student.model.Student
17+
import team.msg.sms.domain.student.model.StudentTechStack
18+
import team.msg.sms.domain.student.service.StudentLinkService
19+
import team.msg.sms.domain.student.service.StudentService
20+
import team.msg.sms.domain.student.service.StudentTechStackService
21+
import team.msg.sms.domain.techstack.model.TechStack
22+
import team.msg.sms.domain.techstack.service.TechStackService
23+
24+
@UseCase
25+
class StudentInfoTokenUseCase(
26+
private val studentService: StudentService,
27+
private val certificateService: CertificateService,
28+
private val studentTechStackService: StudentTechStackService,
29+
private val projectService: ProjectService,
30+
private val techStackService: TechStackService,
31+
private val projectTechStackService: ProjectTechStackService,
32+
private val projectLinkService: ProjectLinkService,
33+
private val imageService: ImageService,
34+
private val languageCertificateService: LanguageCertificateService,
35+
private val regionService: RegionService,
36+
private val prizeService: PrizeService,
37+
private val studentLinkService: StudentLinkService
38+
) {
39+
fun execute(token: String): DetailStudentInfoTokenResponseData {
40+
val student: Student.StudentWithUserInfo = studentLinkService.getStudentUserInfoByToken(token)
41+
42+
val projects = projectService.getAllProjectByStudentId(studentId = student.id)
43+
val certificates = certificateService.getCertificateByUuid(student.id).map { it.certificateName }
44+
val languageCertificates =
45+
languageCertificateService.getLanguageCertificateByStudentUuid(student.id)
46+
.map { toLanguageCertificateScore(languageCertificate = it) }
47+
val regions = regionService.getRegionByStudentUuid(student.id).map { it.region }
48+
val techStacks = techStackService.getAllTechStack()
49+
val prizes = prizeService.getAllPrizeByStudentId(studentId = student.id)
50+
val studentTechStacks = studentTechStackService.getStudentTechStackByStudentId(student.id)
51+
52+
return DetailStudentInfoTokenResponseData(
53+
name = student.name,
54+
introduce = student.introduce,
55+
portfolioUrl = student.portfolioUrl,
56+
grade = student.stuNum.substring(0, 1).toInt(),
57+
classNum = student.stuNum.substring(1, 2).toInt(),
58+
number = student.stuNum.substring(2, 4).toInt(),
59+
department = student.department,
60+
major = student.major,
61+
profileImg = student.profileImgUrl,
62+
contactEmail = student.contactEmail,
63+
gsmAuthenticationScore = student.gsmAuthenticationScore,
64+
formOfEmployment = student.formOfEmployment,
65+
regions = regions,
66+
militaryService = student.militaryService,
67+
salary = student.salary,
68+
languageCertificates = languageCertificates,
69+
certificates = certificates,
70+
techStacks = studentTechStacks.map {
71+
toStudentTechStacks(techStacks, it)?.stack ?: ""
72+
},
73+
projects = generateProjectResponseData(
74+
projects = projects,
75+
projectLinkService = projectLinkService,
76+
projectTechStackService = projectTechStackService,
77+
imageService = imageService,
78+
techStacks = techStacks
79+
),
80+
prizes = generatePrizeResponseData(
81+
prizes = prizes
82+
)
83+
)
84+
}
85+
86+
private fun toLanguageCertificateScore(
87+
languageCertificate: LanguageCertificate,
88+
): LanguageCertificate.LanguageCertificateScore =
89+
LanguageCertificate.LanguageCertificateScore(
90+
languageCertificateName = languageCertificate.languageCertificateName,
91+
score = languageCertificate.score,
92+
)
93+
94+
private fun toStudentTechStacks(techStacks: List<TechStack>, studentTechStack: StudentTechStack): TechStack? =
95+
techStacks.find { it.id == studentTechStack.techStackId }
96+
}
97+

sms-core/src/main/kotlin/team/msg/sms/domain/user/service/CommandUserService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import java.util.UUID
66

77
interface CommandUserService {
88
fun createUserWhenNotExistUser(existUser: Boolean, user: User): User
9+
fun updateStuNum(user: User, stuNum: String): User
910
fun saveRoles(user: User, role: List<Role>): User
1011
fun deleteByUuid(userId: UUID)
1112
}

0 commit comments

Comments
 (0)