diff --git a/README.md b/README.md
index ce13fabf..f368c28d 100644
--- a/README.md
+++ b/README.md
@@ -1,46 +1,38 @@
# 프로젝트에 대한 간단한 설명
## 📌Project Overview
-- HaRu는 소규모 팀을 위한 All-In-One 운영 관리 플랫폼입니다.,
-- 보다 효율적인 팀 운영을 위한 고민에서 시작된 HaRu는, 각자의 자리에서 치열하게 움직이는 소규모 팀들의 하루를 돕고자 합니다.,
-- 회의 진행 보조, SNS 이벤트 진행 관리, 팀 분위기 체크까지.HaRu는 모든 팀이 더 가치 있는 순간에 집중할 수 있도록 돕습니다.,
+- HaRu는 소규모 팀을 위한 All-In-One 운영 관리 플랫폼입니다.
+- 보다 효율적인 팀 운영을 위한 고민에서 시작된 HaRu는, 각자의 자리에서 치열하게 움직이는 소규모 팀들의 하루를 돕고자 합니다.
+- 회의 진행 보조, SNS 이벤트 진행 관리, 팀 분위기 체크까지.HaRu는 모든 팀이 더 가치 있는 순간에 집중할 수 있도록 돕습니다.
## 🚀HaRu Key Features,
-- **AI 회의 진행 매니저**,
- - 실시간 STT 변환,
- - HaRu AI 회의 진행 질문 추천,
- - 회의록 자동 생성,
-- **SNS 이벤트 어시스턴트**,
- - Instagram 계정 연동,
- - 이벤트 URL 등록,
- - 이벤트 참여자 및 당첨자 리스트 추출,
-- **팀 분위기 트래커**,
- - 설문지 작성 및 배포,
- - 팀 분위기 리포트 자동 생성,
- - 운영자 맞춤 HaRu 인사이트 제공,
-
+- **AI 회의 진행 매니저**
+ - 실시간 STT
+ - HaRu AI 회의 진행 질문 추천
+ - 회의록 자동 생성
+- **SNS 이벤트 어시스턴트**
+ - Instagram 계정 연동
+ - 이벤트 URL 등록
+ - 이벤트 참여자 및 당첨자 리스트 추출 및 pdf, word 다운로드
+- **팀 분위기 트래커**
+ - 설문지 작성 및 배포
+ - 팀 분위기 리포트 자동 생성
+ - 운영자 맞춤 HaRu 인사이트 제공
+---
## ⚒️Technical Overview,
- **FrontEnd**: Next.js · React · TypeScript · Tailwind CSS · Storybook · Vercel,
- **BackEnd**: Spring · FastAPI · Docker · MySQL · AWS(EC2, S3, RDS) · Redis
---
----
-
----
-
# 사용한 브랜치 전략 및 기술 스택, 프로젝트 구조 등
## 브랜치 전략
-
-
-- 위 git flow를 따름
-- release브랜치는 제외
-- dev 브랜치 왼편에 feature브랜치말고 refactor, fix브랜치도 존재
-
+
+- 위 github flow를 따름
- 브랜치
- `main` - 배포용 브랜치
@@ -77,7 +69,7 @@
| Version Control | Git |
| Cloud Services | AWS Route53 / EC2 / RDS(MySQL) / S3 / Docker |
| Database & Caches | MySQL / Redis |
-| Deployment Tools | Nginx (프록시 서버) |
+| Deployment Tools | Nginx (프록시 서버) / Github Actions |
| Extra Library | Swagger / WebSockets / elevenlabs |
---
diff --git a/src/main/java/com/haru/api/domain/user/controller/UserController.java b/src/main/java/com/haru/api/domain/user/controller/UserController.java
index 6c9564c9..d634388a 100644
--- a/src/main/java/com/haru/api/domain/user/controller/UserController.java
+++ b/src/main/java/com/haru/api/domain/user/controller/UserController.java
@@ -87,7 +87,7 @@ public ApiResponse> logout(
@Operation(summary = "회원 정보 조회", description =
"# 회원 정보 조회 API 입니다. \n" +
- "현재는 jwt token을 구현하지 않아 pathvariable로 userId를 넣어주세요.추후 jwt token이 구현되면 수정하겠습니다."
+ "access token을 header에 입력해주세요."
)
@GetMapping("/info")
public ApiResponse getUserInfo(
@@ -100,7 +100,7 @@ public ApiResponse getUserInfo(
@Operation(summary = "회원 정보 수정", description =
"# 회원 정보 수정 API 입니다. \n" +
- "현재는 jwt token을 구현하지 않아 pathvariable로 userId를 넣어주세요.추후 jwt token이 구현되면 수정하겠습니다."
+ "access token을 header에 입력해주세요."
)
@PatchMapping("/info")
public ApiResponse updateUserInfo(
@@ -114,8 +114,7 @@ public ApiResponse updateUserInfo(
@Operation(summary = "이메일로 회원 리스트 조회", description =
"# 유사한 이메일을 가진 회원을 최대 4명까지 조회하는 API 입니다. \n" +
- "workspace에서 회원을 초대할 때 사용할 기능입니다. \n" +
- "현재는 jwt token을 구현하지 않아 pathvariable로 userId를 넣어주세요.추후 jwt token이 구현되면 수정하겠습니다."
+ "workspace에서 회원을 초대할 때 사용할 기능입니다. \n"
)
@GetMapping("/search")
public ApiResponse> searchUsers(
@@ -153,4 +152,17 @@ public ApiResponse checkOriginalP
) {
return ApiResponse.onSuccess(userCommandService.checkOriginalPassword(request, user));
}
+
+ @Operation(summary = "회원가입 후 로그인", description =
+ "# [v1.0 (2025-08-15)](https://www.notion.so/2505da7802c5808583b9d0b08087b8e5)" +
+ " 회원가입 후 로그인까지 진행하는 API입니다."
+ )
+ @PostMapping("/signup-and-login")
+ public ApiResponse signUpAndLogin(
+ @RequestBody @Valid UserRequestDTO.SignUpRequest request
+ ) {
+ UserResponseDTO.LoginResponse response = userCommandService.signupAndLogin(request);
+
+ return ApiResponse.onSuccess(response);
+ }
}
diff --git a/src/main/java/com/haru/api/domain/user/security/jwt/JwtAuthenticationFilter.java b/src/main/java/com/haru/api/domain/user/security/jwt/JwtAuthenticationFilter.java
index 97533f27..b214cb73 100644
--- a/src/main/java/com/haru/api/domain/user/security/jwt/JwtAuthenticationFilter.java
+++ b/src/main/java/com/haru/api/domain/user/security/jwt/JwtAuthenticationFilter.java
@@ -32,6 +32,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String[] whitelist = {
"/api/v1/users/signup",
"/api/v1/users/login",
+ "/api/v1/users/signup-and-login",
"/swagger-ui/**",
"/v3/**",
"/users/admin/**",
@@ -41,6 +42,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
"/api/v1/sns/oauth/callback",
"/api/v1/users/signup/same",
"/favicon.ico"
+
};
private final JwtUtils jwtUtils;
private final RedisTemplate redisTemplate;
diff --git a/src/main/java/com/haru/api/domain/user/service/UserCommandService.java b/src/main/java/com/haru/api/domain/user/service/UserCommandService.java
index 79a34945..30c6d905 100644
--- a/src/main/java/com/haru/api/domain/user/service/UserCommandService.java
+++ b/src/main/java/com/haru/api/domain/user/service/UserCommandService.java
@@ -21,4 +21,6 @@ public interface UserCommandService {
UserResponseDTO.CheckEmailDuplicationResponse checkEmailDuplication(UserRequestDTO.CheckEmailDuplicationRequest request);
UserResponseDTO.CheckOriginalPasswordResponse checkOriginalPassword(UserRequestDTO.CheckOriginalPasswordRequest request, User user);
+
+ UserResponseDTO.LoginResponse signupAndLogin(UserRequestDTO.SignUpRequest request);
}
diff --git a/src/main/java/com/haru/api/domain/user/service/UserCommandServiceImpl.java b/src/main/java/com/haru/api/domain/user/service/UserCommandServiceImpl.java
index a4c75981..c3dd87e1 100644
--- a/src/main/java/com/haru/api/domain/user/service/UserCommandServiceImpl.java
+++ b/src/main/java/com/haru/api/domain/user/service/UserCommandServiceImpl.java
@@ -161,4 +161,24 @@ public UserResponseDTO.CheckEmailDuplicationResponse checkEmailDuplication(UserR
public UserResponseDTO.CheckOriginalPasswordResponse checkOriginalPassword(UserRequestDTO.CheckOriginalPasswordRequest request, User user) {
return UserConverter.toCheckOriginalPassword(passwordEncoder.matches(request.getRequestPassword(), user.getPassword()));
}
+
+ @Override
+ public UserResponseDTO.LoginResponse signupAndLogin(UserRequestDTO.SignUpRequest request) {
+
+ String password = passwordEncoder.encode(request.getPassword());
+
+ User foundUser = userRepository.findByEmail(request.getEmail()).orElse(null);
+
+ if (foundUser != null) {
+ throw new MemberHandler(ErrorStatus.MEMBER_ALREADY_EXISTS);
+ } else {
+ User user = UserConverter.toUsers(request, password);
+ userRepository.save(user);
+
+ return login(UserRequestDTO.LoginRequest.builder()
+ .email(request.getEmail())
+ .password(request.getPassword())
+ .build());
+ }
+ }
}