Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ .env.AWS_REGION }}
aws-region: ${{ env.AWS_REGION }}

- name: S3 업로드 (변경된 것만 선택적 업로드)
if: steps.filter.outputs.backend == 'true' || steps.filter.outputs.frontend == 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
* MoMoGo API Application Engine
* Trigger CI/CD Multi-Instance Production Deployment
*/
@SpringBootApplication(scanBasePackages = "com.momogo")
@EntityScan(basePackages = "com.momogo.core.domain")
@EnableJpaRepositories(basePackages = "com.momogo.core.domain")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ public CorsConfigurationSource corsConfigurationSource() {
"X-XSRF-TOKEN",
"X-Requested-With",
"Accept",
"Last-Event-ID"
"Last-Event-ID",
"Idempotency-Key"
));

configuration.setExposedHeaders(List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import com.momogo.api.auth.util.PasswordGenerator;
import com.momogo.core.common.exception.BusinessException;
import com.momogo.core.common.exception.GlobalErrorCode;
import com.momogo.core.domain.user.dto.response.UserResponse;
import com.momogo.core.domain.user.entity.User;
import com.momogo.core.domain.user.entity.enums.SocialType;
import com.momogo.core.domain.user.event.TemporaryPasswordGeneratedEvent;
import com.momogo.core.domain.user.exception.UserErrorCode;
import com.momogo.core.domain.user.mapper.UserMapper;
import com.momogo.core.domain.user.repository.UserRepository;
import com.momogo.core.common.util.EmailFormatter;
import lombok.RequiredArgsConstructor;
Expand All @@ -33,6 +35,7 @@ public class AuthServiceImpl implements AuthService {

private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final UserMapper userMapper;

// Jwt
private final JwtTokenProvider jwtTokenProvider;
Expand Down Expand Up @@ -61,13 +64,14 @@ public JwtDto refresh(String refreshToken) {
}

try {
MoMoGoUserDetails userDetails = jwtTokenProvider.parseAccessToken(refreshToken);
UserResponse userResponse = userMapper.toResponse(user);
MoMoGoUserDetails userDetails = new MoMoGoUserDetails(userResponse, null);

String newAccessToken = jwtTokenProvider.generateAccessToken(userDetails);
String newRefreshToken = jwtTokenProvider.generateRefreshToken(userDetails);

JwtInformation next = new JwtInformation(
current.user(),
userResponse,
newAccessToken,
newRefreshToken
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ public ResponseEntity<Void> deleteProblem(
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<List<ProblemResponse>> createProblemsByAi(
@PathVariable UUID spaceId,
@RequestHeader("Idempotency-Key") UUID idempotencyKey,
@RequestHeader(value = "Idempotency-Key", required = false) UUID idempotencyKey,
@RequestBody @Valid ProblemAiCreateRequest request) {

List<ProblemResponse> response = problemService.createProblemsByAi(spaceId, idempotencyKey, request);
UUID key = (idempotencyKey != null) ? idempotencyKey : UUID.randomUUID();
List<ProblemResponse> response = problemService.createProblemsByAi(spaceId, key, request);

return ResponseEntity
.status(HttpStatus.CREATED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,12 @@ public ResponseEntity<Void> deleteRoomProblem(
public ResponseEntity<List<RoomProblemResponse>> createRoomProblemsByAi(
@AuthenticationPrincipal MoMoGoUserDetails userDetails,
@PathVariable UUID roomId,
@RequestHeader("Idempotency-Key") UUID idempotencyKey,
@RequestHeader(value = "Idempotency-Key", required = false) UUID idempotencyKey,
@Valid @RequestBody RoomProblemAiCreateRequest request) {

UUID key = (idempotencyKey != null) ? idempotencyKey : UUID.randomUUID();
List<RoomProblemResponse> response = roomProblemService.
createRoomProblemsByAi(userDetails.getUserResponse().id(), roomId, idempotencyKey, request);
createRoomProblemsByAi(userDetails.getUserResponse().id(), roomId, key, request);

return ResponseEntity
.status(HttpStatus.CREATED)
Expand Down
1 change: 1 addition & 0 deletions momogo-api/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ app:

server:
port: 8080
forward-headers-strategy: framework

# monitoring
management:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.momogo.core.domain.space.repository.SpaceRepository;
import com.momogo.core.domain.user.entity.User;
import com.momogo.core.domain.user.entity.enums.UserRole;
import com.momogo.core.domain.user.event.UserCacheEvictEvent;
import com.momogo.core.domain.user.repository.UserRepository;
import java.time.OffsetDateTime;
import java.util.List;
Expand Down Expand Up @@ -60,7 +61,8 @@ public Space createSpace(UUID userId, SpaceCreateRequest request) {
Space savedSpace = spaceRepository.save(space);

// 개설한 유저의 공간 정보 및 역할을 ADMIN으로 업데이트
user.joinSpace(savedSpace, UserRole.ADMIN);
user.joinSpace(savedSpace, UserRole.ADMIN);
eventPublisher.publishEvent(new UserCacheEvictEvent(user.getEmail()));

return savedSpace;
}
Expand All @@ -87,6 +89,7 @@ public void joinSpace(UUID userId, UUID spaceId, String password) {

// 공간 가입 처리
user.joinSpace(space, UserRole.USER);
eventPublisher.publishEvent(new UserCacheEvictEvent(user.getEmail()));

// 공간 ADMIN에게 알림을 보내기 위한 이벤트 발행
eventPublisher.publishEvent(new SpaceUserJoinedEvent(spaceId, userId));
Expand Down Expand Up @@ -190,6 +193,7 @@ public void changeUserRole(UUID adminUserId, UUID spaceId, UUID targetUserId, Us

// 권한 변경
targetUser.changeRole(role);
eventPublisher.publishEvent(new UserCacheEvictEvent(targetUser.getEmail()));

// 권한이 변경된 유저에게 알림을 보내기 위한 이벤트 발행
eventPublisher.publishEvent(new SpaceUserRoleChangedEvent(targetUserId, spaceId, role));
Expand Down
13 changes: 12 additions & 1 deletion momogo-frontend/src/pages/SpacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ import type { UserResponse } from '../types/user';
import type { SpaceResponse } from '../types/space';
import { request, getAccessToken, connectNotificationSse } from '../services/api';

const generateUUID = (): string => {
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};

interface SpacePageProps {
user: UserResponse;
space: SpaceResponse;
Expand Down Expand Up @@ -470,7 +481,7 @@ export const SpacePage: React.FC<SpacePageProps> = ({ user, space, onBack, showT
setLoading(true);
await request(`/api/spaces/${space.id}/problems/ai`, {
method: 'POST',
headers: { 'Idempotency-Key': crypto.randomUUID() },
headers: { 'Idempotency-Key': generateUUID() },
body: JSON.stringify({
categoryId: aiCategory,
referenceText: aiRefData,
Expand Down