diff --git a/.gitignore b/.gitignore
index 97adfa9..c2065bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,3 @@ out/
### VS Code ###
.vscode/
-
-/src/main/resources/properties/env.properties
-/src/main/java/com/example/feeda/config/PropertyConfig.java
diff --git a/README.md b/README.md
index 7814902..283b096 100644
--- a/README.md
+++ b/README.md
@@ -1,102 +1,2 @@
-# 피다(Feeda)
-개발자, 학생, 그리고 자기 계발에 관심 있는 모두가 모여 서로의 스터디 정보와 노하우를 나누는 커뮤니티 SNS입니다.
-
-- 스터디 모집 및 경험 공유
-- 질문과 답변을 통한 지식 나눔
-- 성장과 동기부여를 위한 소통 공간
-- 함께 배우고, 함께 성장하는 즐거움을 경험 시켜 드릴수가 있을 것 같습니다.
-
-
-
-## 👨💻 Team
-- 팀명: 6pring (식스프링)
-- 소개: 4명의 아기자기한 팀
-- 팀원 및 역할 분담
-
-| 이름 | 역할 | 주요 담당 업무 |
-|-----|----|------------------------------------------------------------------------------------------|
-| 최경진 | 팀장 | - 발표 ✨
- 프로필 관련 API 개발
- 게시글 댓글 관련 API 개발 |
-| 김나경 | 팀원 | - ERD 작성 및 DB 설계
- JWT 인증/인가 관련 기능 구현
- 회원 관리 관련 API 개발
- 게시글 댓글 좋아요 관련 API 개발 |
-| 안요한 | 팀원 | - 와이어 프레임 작성
- 게시글 관련 API 개발
- 게시글 좋아요 관련 API 개발 |
-| 이의현 | 팀원 | - API 명세서 작성
- 팔로우(친구 관리) 관련 API 개발
- 전역 예외 처리 핸들러 개발
- 테스트 코드 작성 |
-
-
-
-
-## 🛠 사용 기술
-- Java 17
-- Gradle 8.5
-- Spring Boot 3.5.0
-- Spring Data JPA (Hibernate 6.6.13.Final)
-- Spring Security
-- MySQL 8.0 이상
-- Redis Cloud
-
-
-
-## 💻 개발 도구
-- IntelliJ IDEA
-- Redis Insight
-- Git
-- Postman
-
-
-
-## 📃 프로젝트 설계
-
-API 명세서
-
-Postman: [document](https://documenter.getpostman.com/view/44635744/2sB2qgeyJ7)
-
-Notion
-- [필수기능 명세서](https://www.notion.so/2002dc3ef5148050b741cdfba818f530?pvs=21)
-- [도전기능 명세서](https://www.notion.so/2022dc3ef51481939541e86c62aa7864?pvs=21)
-
-
-
-와이어 프레임
-
-
-
-
-
-DB 설계
-
-- 개념적 설계:
- - 
-- 논리적 설계(ERD):
- - 
-- 물리적 설계(SQL):
- - [newsFeed2.sql](./newsFeed2.sql)
- - 
-
-
-
-
-## 📁 폴더 구조
-```bash
-src
-├──── main.java.com.example.feeda
-│ ├──── config # 설정 관련
-│ ├──── domain # 도메인별 기능 분류
-│ │ ├──── account
-│ │ ├──── comment
-│ │ ├──── follow
-│ │ ├──── post
-│ │ └──── profile
-│ ├──── exception # 예외 클래스 및 처리
-│ ├──── filter # 인증 필터
-│ ├──── security # 보안 관련 (PasswordEncoder, JWT)
-│ └──── FeedaApplication.java
-└──── test # 테스트 코드
-```
-
-
-
-## 🔍 새로운 지식
-
-
-## 🧰 문제 해결 (트러블 슈팅)
-
-
-
+# spring-feeda
+모두가 모여 서로의 스터디 정보와 노하우를 나누는 커뮤니티 SNS입니다.
diff --git a/build.gradle b/build.gradle
index 6a3fa01..d630d05 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,50 +1,40 @@
plugins {
- id 'java'
- id 'org.springframework.boot' version '3.5.0'
- id 'io.spring.dependency-management' version '1.1.7'
+ id 'java'
+ id 'org.springframework.boot' version '3.5.0'
+ id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
- toolchain {
- languageVersion = JavaLanguageVersion.of(17)
- }
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(17)
+ }
}
configurations {
- compileOnly {
- extendsFrom annotationProcessor
- }
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
}
repositories {
- mavenCentral()
+ mavenCentral()
}
dependencies {
- implementation 'mysql:mysql-connector-java:8.0.33' // 추가
- implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- implementation 'org.springframework.boot:spring-boot-starter-security'
- implementation 'org.springframework.boot:spring-boot-starter-validation'
- implementation 'org.springframework.boot:spring-boot-starter-web'
- implementation 'org.springframework.boot:spring-boot-starter-data-redis'
- compileOnly 'org.projectlombok:lombok'
- annotationProcessor 'org.projectlombok:lombok'
- testImplementation 'org.springframework.boot:spring-boot-starter-test'
- testImplementation 'org.springframework.security:spring-security-test'
- runtimeOnly 'com.mysql:mysql-connector-j'
- testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
-
- // jwt
- compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
- runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
- runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
-
- testImplementation 'com.h2database:h2'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'org.springframework.boot:spring-boot-starter-security'
+ implementation 'org.springframework.boot:spring-boot-starter-validation'
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.projectlombok:lombok'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'org.springframework.security:spring-security-test'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
- useJUnitPlatform()
+ useJUnitPlatform()
}
diff --git a/images/er.png b/images/er.png
deleted file mode 100644
index 816fc2b..0000000
Binary files a/images/er.png and /dev/null differ
diff --git a/images/erd.png b/images/erd.png
deleted file mode 100644
index cf35035..0000000
Binary files a/images/erd.png and /dev/null differ
diff --git a/images/erdE.png b/images/erdE.png
deleted file mode 100644
index d2c6fb4..0000000
Binary files a/images/erdE.png and /dev/null differ
diff --git a/images/wireframe.png b/images/wireframe.png
deleted file mode 100644
index c8ec456..0000000
Binary files a/images/wireframe.png and /dev/null differ
diff --git a/newsFeed.sql b/newsFeed.sql
deleted file mode 100644
index c0cd7ba..0000000
--- a/newsFeed.sql
+++ /dev/null
@@ -1,49 +0,0 @@
-DROP DATABASE IF EXISTS newsFeed;
-CREATE DATABASE IF NOT EXISTS newsFeed;
-USE newsFeed;
-
--- 사용자 인증(accounts) 테이블 생성
-CREATE TABLE accounts (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '사용자 인증 ID (PK)',
- email VARCHAR(100) NOT NULL UNIQUE COMMENT '이메일',
- password VARCHAR(255) NOT NULL COMMENT '비밀번호',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일'
-) COMMENT = '사용자 인증 Table';
-
--- 사용자 정보(profile) 테이블 생성
-CREATE TABLE profiles (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '사용자 정보 ID (PK)',
- account_id BIGINT COMMENT '사용자 인증 ID (FK)',
- nickname VARCHAR(50) NOT NULL UNIQUE COMMENT '닉네임',
- birth DATE COMMENT '생년월일',
- bio TEXT COMMENT '자기소개',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일',
-
- FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE
-) COMMENT = '사용자 정보 Table';
-
--- 게시글(posts) 테이블 생성
-CREATE TABLE posts (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '게시글 ID (PK)',
- profile_id BIGINT NOT NULL COMMENT '작성자 ID (FK)',
- title VARCHAR(100) NOT NULL COMMENT '제목',
- content TEXT NOT NULL COMMENT '내용',
- category VARCHAR(50) COMMENT '카테고리',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일',
-
- FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '게시글 Table';
-
--- 팔로우 목록(follows) 테이블 생성
-CREATE TABLE follows (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '팔로우 ID (PK)',
- follower_id BIGINT NOT NULL COMMENT '팔로우한 사람 ID (PK)',
- following_id BIGINT NOT NULL COMMENT '팔로잉된 사람 ID (FK)',
- created_at DATETIME COMMENT '생성일',
-
- FOREIGN KEY (follower_id) REFERENCES profiles(id) ON DELETE CASCADE,
- FOREIGN KEY (following_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '팔로우 목록 Table'
\ No newline at end of file
diff --git a/newsFeed2.sql b/newsFeed2.sql
deleted file mode 100644
index e5baf2a..0000000
--- a/newsFeed2.sql
+++ /dev/null
@@ -1,84 +0,0 @@
-DROP DATABASE IF EXISTS newsFeed;
-CREATE DATABASE IF NOT EXISTS newsFeed;
-USE newsFeed;
-
--- 사용자 인증(accounts) 테이블 생성
-CREATE TABLE accounts (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '사용자 인증 ID (PK)',
- email VARCHAR(100) NOT NULL UNIQUE COMMENT '이메일',
- password VARCHAR(255) NOT NULL COMMENT '비밀번호',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일'
-) COMMENT = '사용자 인증 Table';
-
--- 사용자 정보(profile) 테이블 생성
-CREATE TABLE profiles (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '사용자 정보 ID (PK)',
- account_id BIGINT COMMENT '사용자 인증 ID (FK)',
- nickname VARCHAR(50) NOT NULL UNIQUE COMMENT '닉네임',
- birth DATE COMMENT '생년월일',
- bio TEXT COMMENT '자기소개',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일',
-
- FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE
-) COMMENT = '사용자 정보 Table';
-
--- 팔로우 목록(follows) 테이블 생성
-CREATE TABLE follows (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '팔로우 ID (PK)',
- follower_id BIGINT NOT NULL COMMENT '팔로우한 사람 ID (PK)',
- following_id BIGINT NOT NULL COMMENT '팔로잉된 사람 ID (FK)',
- created_at DATETIME COMMENT '생성일',
-
- FOREIGN KEY (follower_id) REFERENCES profiles(id) ON DELETE CASCADE,
- FOREIGN KEY (following_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '팔로우 목록 Table';
-
--- 게시글(posts) 테이블 생성
-CREATE TABLE posts (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '게시글 ID (PK)',
- profile_id BIGINT NOT NULL COMMENT '작성자 ID (FK)',
- title VARCHAR(100) NOT NULL COMMENT '제목',
- content TEXT NOT NULL COMMENT '내용',
- category VARCHAR(50) COMMENT '카테고리',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일',
-
- FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '게시글 Table';
-
--- 게시글 댓글(post_comments) 테이블 생성
-CREATE TABLE post_comments (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '댓글 ID (PK)',
- post_id BIGINT NOT NULL COMMENT '게시글 ID (FK)',
- profile_id BIGINT NOT NULL COMMENT '작성자 ID (FK)',
- content TEXT NOT NULL COMMENT '내용',
- created_at DATETIME COMMENT '생성일',
- updated_at DATETIME COMMENT '수정일',
-
- FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
- FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '게시글 댓글 Table';
-
--- 게시글 좋아요(post_likes) 테이블 생성
-CREATE TABLE post_likes (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '댓글 ID (PK)',
- post_id BIGINT NOT NULL COMMENT '게시글 ID (FK)',
- profile_id BIGINT NOT NULL COMMENT '사용자 ID (FK)',
- created_at DATETIME COMMENT '생성일',
-
- FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
- FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '게시글 좋아요 Table';
-
--- 게시글 댓글 좋아요(post_comment_likes) 테이블 생성
-CREATE TABLE post_comment_likes (
- id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '댓글 ID (PK)',
- post_comment_id BIGINT NOT NULL COMMENT '게시글 ID (FK)',
- profile_id BIGINT NOT NULL COMMENT '사용자 ID (FK)',
- created_at DATETIME COMMENT '생성일',
-
- FOREIGN KEY (post_comment_id) REFERENCES post_comments(id) ON DELETE CASCADE,
- FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
-) COMMENT = '게시글 댓글 좋아요 Table';
\ No newline at end of file
diff --git a/src/main/java/com/example/feeda/config/.gitkeep b/src/main/java/com/example/feeda/config/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/java/com/example/feeda/config/RedisConfig.java b/src/main/java/com/example/feeda/config/RedisConfig.java
deleted file mode 100644
index 65c3c4e..0000000
--- a/src/main/java/com/example/feeda/config/RedisConfig.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.example.feeda.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
-
-
-@Configuration
-@EnableRedisRepositories
-public class RedisConfig {
-
- @Value("${spring.data.redis.host}")
- private String host;
-
- @Value("${spring.data.redis.port}")
- private int port;
-
- @Value("${spring.data.redis.password:}")
- private String password;
-
- @Bean
- public RedisConnectionFactory redisConnectionFactory() {
- RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
- config.setHostName(host);
- config.setPort(port);
- config.setPassword(password);
-
- return new LettuceConnectionFactory(config);
- }
-}
diff --git a/src/main/java/com/example/feeda/config/SecurityConfig.java b/src/main/java/com/example/feeda/config/SecurityConfig.java
deleted file mode 100644
index 80ac914..0000000
--- a/src/main/java/com/example/feeda/config/SecurityConfig.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.example.feeda.config;
-
-import com.example.feeda.filter.JwtFilter;
-import com.example.feeda.security.handler.CustomAccessDeniedHandler;
-import com.example.feeda.security.handler.CustomAuthenticationEntryPoint;
-import com.example.feeda.security.jwt.JwtBlacklistService;
-import com.example.feeda.security.jwt.JwtUtil;
-import lombok.RequiredArgsConstructor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.Customizer;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
-
-@Configuration
-@EnableWebSecurity
-@RequiredArgsConstructor
-public class SecurityConfig {
- private final JwtBlacklistService jwtBlacklistService;
- private final JwtUtil jwtUtil;
- private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
- private final CustomAccessDeniedHandler customAccessDeniedHandler;
-
- @Bean
- public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
-
- return httpSecurity
- .csrf(AbstractHttpConfigurer::disable)
- .cors(Customizer.withDefaults())
- .httpBasic(AbstractHttpConfigurer::disable)
- .formLogin(AbstractHttpConfigurer::disable)
-
- // 세션 비활성화
- .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
-
- // 접근 제어
- .authorizeHttpRequests(auth -> auth
- // 회원가입, 로그인은 인증 제외
- .requestMatchers("/api/accounts", "/api/accounts/login").permitAll()
-
- .requestMatchers("/error").permitAll()
- .requestMatchers("/api/**").authenticated()
-
- .anyRequest().denyAll()
- )
-
- // 필터 등록
- .addFilterBefore(new JwtFilter(jwtBlacklistService, jwtUtil), UsernamePasswordAuthenticationFilter.class)
-
- .exceptionHandling(configurer ->
- configurer
- .authenticationEntryPoint(customAuthenticationEntryPoint)
- .accessDeniedHandler(customAccessDeniedHandler)
- )
-
- .build();
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/account/controller/AccountController.java b/src/main/java/com/example/feeda/domain/account/controller/AccountController.java
deleted file mode 100644
index 2773b65..0000000
--- a/src/main/java/com/example/feeda/domain/account/controller/AccountController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.example.feeda.domain.account.controller;
-
-import com.example.feeda.domain.account.sevice.AccountServiceImpl;
-import com.example.feeda.domain.account.dto.*;
-import com.example.feeda.security.jwt.JwtBlacklistService;
-import com.example.feeda.security.jwt.JwtPayload;
-import com.example.feeda.security.jwt.JwtUtil;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api")
-@RequiredArgsConstructor
-public class AccountController {
- private final AccountServiceImpl accountService;
- private final JwtBlacklistService jwtBlacklistService;
- private final JwtUtil jwtUtil;
-
- @PostMapping("/accounts")
- public ResponseEntity signup(@RequestBody @Valid SignUpRequestDTO requestDTO) {
- return new ResponseEntity<>(accountService.signup(requestDTO), HttpStatus.CREATED);
- }
-
- @DeleteMapping("/accounts/me")
- public ResponseEntity deleteAccount(
- @RequestHeader("Authorization") String bearerToken,
- @AuthenticationPrincipal JwtPayload jwtPayload,
- @RequestBody @Valid DeleteAccountRequestDTO requestDTO
- ) {
- accountService.deleteAccount(jwtPayload.getAccountId(), requestDTO.getPassword());
-
- // 토큰 무효화
- invalidateToken(bearerToken);
-
- return new ResponseEntity<>(HttpStatus.NO_CONTENT);
- }
-
- @PatchMapping("/accounts/password")
- public ResponseEntity updatePassword(
- @AuthenticationPrincipal JwtPayload jwtPayload,
- @RequestBody @Valid UpdatePasswordRequestDTO requestDTO
- ) {
- return new ResponseEntity<>(accountService.updatePassword(jwtPayload.getAccountId(), requestDTO), HttpStatus.OK);
- }
-
- @PostMapping("/accounts/login")
- public ResponseEntity login(
- @RequestBody @Valid LogInRequestDTO requestDTO
- ) {
- UserResponseDTO responseDTO = accountService.login(requestDTO);
-
- JwtPayload payload = new JwtPayload(
- responseDTO.getAccountId(),
- responseDTO.getProfileId(),
- responseDTO.getEmail(),
- responseDTO.getNickName()
- );
-
- String jwt = jwtUtil.createToken(payload);
-
- HttpHeaders headers = new HttpHeaders();
- headers.add("Authorization", "Bearer " + jwt);
-
- return new ResponseEntity<>(responseDTO, headers, HttpStatus.OK);
- }
-
- @PostMapping("/accounts/logout")
- public ResponseEntity logout(@RequestHeader("Authorization") String bearerToken) {
- // 토큰 무효화
- invalidateToken(bearerToken);
-
- return new ResponseEntity<>(HttpStatus.NO_CONTENT);
- }
-
-
- private void invalidateToken(String bearerToken) {
- String token = jwtUtil.extractToken(bearerToken);
- jwtBlacklistService.addBlacklist(token);
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/account/dto/UserResponseDTO.java b/src/main/java/com/example/feeda/domain/account/dto/UserResponseDTO.java
deleted file mode 100644
index 70f23a6..0000000
--- a/src/main/java/com/example/feeda/domain/account/dto/UserResponseDTO.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.example.feeda.domain.account.dto;
-
-import com.example.feeda.domain.account.entity.Account;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.time.LocalDateTime;
-
-@Getter
-@AllArgsConstructor
-public class UserResponseDTO {
- private final Long accountId;
- private final Long profileId;
- private final String email;
- private String nickName;
- private final LocalDateTime createdAt;
- private final LocalDateTime updatedAt;
-
- public UserResponseDTO(Account account) {
- this.accountId = account.getId();
- this.profileId = account.getProfile().getId();
- this.email = account.getEmail();
- this.nickName = account.getProfile().getNickname();
- this.createdAt = account.getCreatedAt();
- this.updatedAt = account.getUpdatedAt();
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/account/entity/Account.java b/src/main/java/com/example/feeda/domain/account/entity/Account.java
deleted file mode 100644
index 725e2eb..0000000
--- a/src/main/java/com/example/feeda/domain/account/entity/Account.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.example.feeda.domain.account.entity;
-
-import com.example.feeda.domain.profile.entity.Profile;
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.annotation.LastModifiedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.LocalDateTime;
-
-@Entity
-@Table(name = "accounts")
-@Getter
-@AllArgsConstructor
-@EntityListeners(AuditingEntityListener.class)
-public class Account {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @Column(nullable = false, unique = true)
- private String email;
-
- @Setter
- private String password;
-
- @CreatedDate
- @Column(updatable = false, name = "created_at")
- private LocalDateTime createdAt;
-
- @LastModifiedDate
- @Column(name = "updated_at")
- private LocalDateTime updatedAt;
-
- @Setter
- @OneToOne(mappedBy = "account", cascade = CascadeType.ALL, optional = false)
- private Profile profile;
-
- public Account() {
- // @Entity: no-arg 생성자가 포함되어야 함
- }
-
- public Account(String email, String password) {
- this.email = email;
- this.password = password;
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/account/repository/AccountRepository.java b/src/main/java/com/example/feeda/domain/account/repository/AccountRepository.java
deleted file mode 100644
index 8e3cfb2..0000000
--- a/src/main/java/com/example/feeda/domain/account/repository/AccountRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.example.feeda.domain.account.repository;
-
-import com.example.feeda.domain.account.entity.Account;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface AccountRepository extends JpaRepository {
- Optional findByEmail(String email);
-}
diff --git a/src/main/java/com/example/feeda/domain/account/sevice/AccountService.java b/src/main/java/com/example/feeda/domain/account/sevice/AccountService.java
deleted file mode 100644
index 9c18c4a..0000000
--- a/src/main/java/com/example/feeda/domain/account/sevice/AccountService.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.example.feeda.domain.account.sevice;
-
-import com.example.feeda.domain.account.dto.LogInRequestDTO;
-import com.example.feeda.domain.account.dto.SignUpRequestDTO;
-import com.example.feeda.domain.account.dto.UpdatePasswordRequestDTO;
-import com.example.feeda.domain.account.dto.UserResponseDTO;
-
-public interface AccountService {
- UserResponseDTO signup(SignUpRequestDTO requestDTO);
-
- void deleteAccount(Long id, String password);
-
- UserResponseDTO updatePassword(Long id, UpdatePasswordRequestDTO requestDTO);
-
- UserResponseDTO login(LogInRequestDTO requestDTO);
-}
diff --git a/src/main/java/com/example/feeda/domain/account/sevice/AccountServiceImpl.java b/src/main/java/com/example/feeda/domain/account/sevice/AccountServiceImpl.java
deleted file mode 100644
index fb2c7aa..0000000
--- a/src/main/java/com/example/feeda/domain/account/sevice/AccountServiceImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.example.feeda.domain.account.sevice;
-
-import com.example.feeda.domain.account.dto.LogInRequestDTO;
-import com.example.feeda.domain.account.dto.UpdatePasswordRequestDTO;
-import com.example.feeda.domain.account.dto.UserResponseDTO;
-import com.example.feeda.domain.account.dto.SignUpRequestDTO;
-import com.example.feeda.domain.account.entity.Account;
-import com.example.feeda.domain.account.repository.AccountRepository;
-import com.example.feeda.domain.profile.entity.Profile;
-import com.example.feeda.domain.profile.repository.ProfileRepository;
-import com.example.feeda.exception.CustomResponseException;
-import com.example.feeda.exception.enums.ResponseError;
-import com.example.feeda.security.PasswordEncoder;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-
-@Service
-@RequiredArgsConstructor
-public class AccountServiceImpl implements AccountService {
- private final AccountRepository accountRepository;
- private final PasswordEncoder passwordEncoder;
- private final ProfileRepository profileRepository;
-
- @Override
- @Transactional
- public UserResponseDTO signup(SignUpRequestDTO requestDTO) {
- if(accountRepository.findByEmail(requestDTO.getEmail()).isPresent()) {
- throw new CustomResponseException(ResponseError.EMAIL_ALREADY_EXISTS);
- }
-
- if(profileRepository.findByNickname(requestDTO.getNickName()).isPresent()) {
- throw new CustomResponseException(ResponseError.NICKNAME_ALREADY_EXISTS);
- }
-
- Account account = new Account(requestDTO.getEmail(), requestDTO.getPassword());
- account.setPassword(passwordEncoder.encode(account.getPassword()));
-
- Profile profile = new Profile(requestDTO.getNickName(), requestDTO.getBirth(), requestDTO.getBio());
-
- // 양방향 연결
- account.setProfile(profile);
- profile.setAccount(account);
-
- Account saveProfile = accountRepository.save(account);
-
- return new UserResponseDTO(saveProfile);
- }
-
- @Override
- @Transactional
- public void deleteAccount(Long id, String password) {
- Account account = getAccountById(id);
-
- if(!passwordEncoder.matches(password, account.getPassword())) {
- throw new CustomResponseException(ResponseError.INVALID_PASSWORD);
- }
-
- accountRepository.delete(account);
- }
-
- @Override
- @Transactional
- public UserResponseDTO updatePassword(Long id, UpdatePasswordRequestDTO requestDTO) {
- Account account = getAccountById(id);
-
- if(!passwordEncoder.matches(requestDTO.getOldPassword(), account.getPassword())) {
- throw new CustomResponseException(ResponseError.INVALID_PASSWORD);
- }
-
- account.setPassword(passwordEncoder.encode(requestDTO.getNewPassword()));
-
- // DB 에 변경 사항 강제 반영
- accountRepository.flush();
-
- return new UserResponseDTO(account);
- }
-
- @Override
- public UserResponseDTO login(LogInRequestDTO requestDTO) {
- return new UserResponseDTO(accountRepository.findByEmail(requestDTO.getEmail())
- .filter(findAccount -> passwordEncoder.matches(requestDTO.getPassword(), findAccount.getPassword()))
- .orElseThrow(() -> new CustomResponseException(ResponseError.INVALID_EMAIL_OR_PASSWORD))
- );
- }
-
-
- /* 유틸(?): 서비스 내에서만 사용 */
-
- public Account getAccountById(Long id) {
- return accountRepository.findById(id).orElseThrow(() ->
- new CustomResponseException(ResponseError.ACCOUNT_NOT_FOUND)
- );
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/controller/CommentController.java b/src/main/java/com/example/feeda/domain/comment/controller/CommentController.java
deleted file mode 100644
index b00ac8f..0000000
--- a/src/main/java/com/example/feeda/domain/comment/controller/CommentController.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.example.feeda.domain.comment.controller;
-
-import com.example.feeda.domain.comment.dto.CommentResponse;
-import com.example.feeda.domain.comment.dto.CreateCommentRequest;
-import com.example.feeda.domain.comment.dto.UpdateCommentRequest;
-import com.example.feeda.domain.comment.service.CommentService;
-import com.example.feeda.domain.comment.dto.LikeCommentResponseDTO;
-import com.example.feeda.domain.comment.service.CommentLikeService;
-import com.example.feeda.security.jwt.JwtPayload;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api")
-@RequiredArgsConstructor
-@Validated
-public class CommentController {
-
- private final CommentLikeService commentLikeService;
- private final CommentService commentService;
-
- // 댓글 작성
- @PostMapping("/comments/post/{postId}")
- public ResponseEntity createComment(
- @PathVariable Long postId,
- @AuthenticationPrincipal JwtPayload jwtPayload,
- @RequestBody @Valid CreateCommentRequest request
- ) {
- Long profileId = jwtPayload.getProfileId();
- CommentResponse response = commentService.createComment(postId, profileId, request);
- return ResponseEntity.ok(response);
- }
-
- // 댓글 전체 조회 (게시글 기준, 정렬/필터 가능)
- @GetMapping("/comments/post/{postId}")
- public ResponseEntity> getCommentsByPostId(
- @PathVariable Long postId,
- @RequestParam(defaultValue = "latest") String sort // latest 또는 oldest
- ) {
- List comments = commentService.getCommentsByPostId(postId, sort);
- return ResponseEntity.ok(comments);
- }
-
- // 댓글 단건 조회
- @GetMapping("/comments/{commentId}")
- public ResponseEntity getCommentById(@PathVariable Long commentId) {
- CommentResponse response = commentService.getCommentById(commentId);
- return ResponseEntity.ok(response);
- }
-
-
- // 댓글 수정
- @PutMapping("/comments/{commentId}")
- public ResponseEntity updateComment(
- @PathVariable Long commentId,
- @AuthenticationPrincipal JwtPayload jwtPayload,
- @Valid @RequestBody UpdateCommentRequest request
- ) {
- Long profileId = jwtPayload.getProfileId();
- CommentResponse response = commentService.updateComment(commentId, profileId, request);
- return ResponseEntity.ok(response);
- }
-
- // 댓글 삭제
- @DeleteMapping("/comments/{commentId}")
- public ResponseEntity deleteComment(
- @PathVariable Long commentId,
- @AuthenticationPrincipal JwtPayload jwtPayload
- ) {
- Long profileId = jwtPayload.getProfileId();
- commentService.deleteComment(commentId, profileId);
- return ResponseEntity.noContent().build();
- }
-
- // 댓글 좋아요
- @PostMapping("/comments/{id}/likes")
- public ResponseEntity likeComment(
- @PathVariable Long id,
- @AuthenticationPrincipal JwtPayload jwtPayload
- ) {
- Long profileId = jwtPayload.getProfileId();
- return new ResponseEntity<>(
- commentLikeService.likeComment(id, profileId),
- HttpStatus.OK
- );
- }
-
- // 댓글 좋아요 취소
- @DeleteMapping("/comments/{id}/likes")
- public ResponseEntity unlikeComment(
- @PathVariable Long id,
- @AuthenticationPrincipal JwtPayload jwtPayload
- ) {
- commentLikeService.unlikeComment(id, jwtPayload.getProfileId());
- return new ResponseEntity<>(HttpStatus.NO_CONTENT);
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/dto/CommentResponse.java b/src/main/java/com/example/feeda/domain/comment/dto/CommentResponse.java
deleted file mode 100644
index ae28b6c..0000000
--- a/src/main/java/com/example/feeda/domain/comment/dto/CommentResponse.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.example.feeda.domain.comment.dto;
-
-import com.example.feeda.domain.comment.entity.Comment;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.time.LocalDateTime;
-
-@Getter
-@AllArgsConstructor(staticName = "of")
-public class CommentResponse {
- private final Long id;
- private final String content;
- private final String profileName;
- private final LocalDateTime createdAt;
-
- public static CommentResponse from(Comment comment) {
- return CommentResponse.of(
- comment.getId(),
- comment.getContent(),
- comment.getProfile().getNickname(),
- comment.getCreatedAt()
- );
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/dto/CreateCommentRequest.java b/src/main/java/com/example/feeda/domain/comment/dto/CreateCommentRequest.java
deleted file mode 100644
index f41596e..0000000
--- a/src/main/java/com/example/feeda/domain/comment/dto/CreateCommentRequest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.example.feeda.domain.comment.dto;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor()
-public class CreateCommentRequest {
- @NotBlank(message = "내용을 입력해주세요.")
- private String content;
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/dto/LikeCommentResponseDTO.java b/src/main/java/com/example/feeda/domain/comment/dto/LikeCommentResponseDTO.java
deleted file mode 100644
index 48a1535..0000000
--- a/src/main/java/com/example/feeda/domain/comment/dto/LikeCommentResponseDTO.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.example.feeda.domain.comment.dto;
-
-import com.example.feeda.domain.comment.entity.CommentLike;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.time.LocalDateTime;
-
-@Getter
-@AllArgsConstructor
-public class LikeCommentResponseDTO {
- private final Long id;
- private final Long commentId;
- private final Long profileId;
- private final LocalDateTime createdAt;
-
- public LikeCommentResponseDTO(CommentLike commentLike) {
- this.id = commentLike.getId();
- this.commentId = commentLike.getComment().getId();
- this.profileId = commentLike.getProfile().getId();
- this.createdAt = commentLike.getCreatedAt();
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/dto/UpdateCommentRequest.java b/src/main/java/com/example/feeda/domain/comment/dto/UpdateCommentRequest.java
deleted file mode 100644
index 0379e0c..0000000
--- a/src/main/java/com/example/feeda/domain/comment/dto/UpdateCommentRequest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.example.feeda.domain.comment.dto;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class UpdateCommentRequest {
- @NotBlank(message = "내용을 입력해주세요.")
- private String content;
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/entity/Comment.java b/src/main/java/com/example/feeda/domain/comment/entity/Comment.java
deleted file mode 100644
index 4f2d2e2..0000000
--- a/src/main/java/com/example/feeda/domain/comment/entity/Comment.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.example.feeda.domain.comment.entity;
-
-import com.example.feeda.domain.post.entity.Post;
-import com.example.feeda.domain.profile.entity.Profile;
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.annotation.LastModifiedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.LocalDateTime;
-
-@Entity
-@Table(name = "post_comments")
-@Getter
-@AllArgsConstructor
-@EntityListeners(AuditingEntityListener.class)
-@NoArgsConstructor
-public class Comment {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @ManyToOne
- @JoinColumn(name = "post_id", nullable = false)
- private Post post;
-
- @ManyToOne
- @JoinColumn(name = "profile_id", nullable = false)
- private Profile profile;
-
- @Column(nullable = false)
- private String content;
-
- @CreatedDate
- @Column(updatable = false, name = "created_at")
- private LocalDateTime createdAt;
-
- @LastModifiedDate
- @Column(name = "updated_at")
- private LocalDateTime updatedAt;
-
- public Comment(Post post, Profile profile, String content) {
- this.post = post;
- this.profile = profile;
- this.content = content;
- }
-
- public void updateContent(String content) {
- this.content = content;
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/entity/CommentLike.java b/src/main/java/com/example/feeda/domain/comment/entity/CommentLike.java
deleted file mode 100644
index 6cfb13a..0000000
--- a/src/main/java/com/example/feeda/domain/comment/entity/CommentLike.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.example.feeda.domain.comment.entity;
-
-import com.example.feeda.domain.profile.entity.Profile;
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.LocalDateTime;
-
-@Entity
-@Table(name = "post_comment_likes")
-@Getter
-@AllArgsConstructor
-@EntityListeners(AuditingEntityListener.class)
-@NoArgsConstructor
-public class CommentLike {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- @ManyToOne
- @JoinColumn(name = "post_comment_id", nullable = false)
- private Comment comment;
-
- @ManyToOne
- @JoinColumn(name = "profile_id", nullable = false)
- private Profile profile;
-
- @CreatedDate
- @Column(updatable = false, name = "created_at")
- private LocalDateTime createdAt;
-
- public CommentLike(Comment comment, Profile profile) {
- this.comment = comment;
- this.profile = profile;
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/repository/CommentLikeRepository.java b/src/main/java/com/example/feeda/domain/comment/repository/CommentLikeRepository.java
deleted file mode 100644
index e8a85c5..0000000
--- a/src/main/java/com/example/feeda/domain/comment/repository/CommentLikeRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.example.feeda.domain.comment.repository;
-
-import com.example.feeda.domain.comment.entity.CommentLike;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Optional;
-
-public interface CommentLikeRepository extends JpaRepository {
- Optional findByComment_IdAndProfile_Id(Long commentId, Long profileId);
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/repository/CommentRepository.java b/src/main/java/com/example/feeda/domain/comment/repository/CommentRepository.java
deleted file mode 100644
index 61835b4..0000000
--- a/src/main/java/com/example/feeda/domain/comment/repository/CommentRepository.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.example.feeda.domain.comment.repository;
-
-import com.example.feeda.domain.comment.entity.Comment;
-import com.example.feeda.domain.post.entity.Post;
-import java.util.List;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface CommentRepository extends JpaRepository {
-
- List findByPostIdOrderByCreatedAtDesc(Long postId); // 최신순
-
- List findByPostIdOrderByCreatedAtAsc(Long postId);
-
- Long countByPost(Post findPost);
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/service/CommentLikeService.java b/src/main/java/com/example/feeda/domain/comment/service/CommentLikeService.java
deleted file mode 100644
index 0746e92..0000000
--- a/src/main/java/com/example/feeda/domain/comment/service/CommentLikeService.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.example.feeda.domain.comment.service;
-
-import com.example.feeda.domain.comment.dto.LikeCommentResponseDTO;
-import com.example.feeda.domain.comment.entity.Comment;
-import com.example.feeda.domain.comment.entity.CommentLike;
-import com.example.feeda.domain.comment.repository.CommentLikeRepository;
-import com.example.feeda.domain.comment.repository.CommentRepository;
-import com.example.feeda.domain.profile.entity.Profile;
-import com.example.feeda.domain.profile.repository.ProfileRepository;
-import com.example.feeda.exception.CustomResponseException;
-import com.example.feeda.exception.enums.ResponseError;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-
-import java.util.Optional;
-
-@Service
-@RequiredArgsConstructor
-public class CommentLikeService {
- private final CommentRepository commentRepository;
- private final CommentLikeRepository commentLikeRepository;
- private final ProfileRepository profileRepository;
-
-
- public LikeCommentResponseDTO likeComment(Long commentId, Long profileId) {
- Optional findCommentLike = commentLikeRepository.findByComment_IdAndProfile_Id(commentId, profileId);
- if(findCommentLike.isPresent()) {
- throw new CustomResponseException(ResponseError.ALREADY_LIKED_COMMENT);
- }
-
- Comment findComment = commentRepository.findById(commentId).orElseThrow(() ->
- new CustomResponseException(ResponseError.COMMENT_NOT_FOUND)
- );
-
- Profile findProfile = profileRepository.findById(profileId).orElseThrow(() ->
- new CustomResponseException(ResponseError.PROFILE_NOT_FOUND)
- );
-
- CommentLike commentLike = new CommentLike(findComment, findProfile);
- commentLikeRepository.save(commentLike);
-
- return new LikeCommentResponseDTO(commentLike);
- }
-
- public void unlikeComment(Long commentId, Long profileId) {
- Optional findCommentLikeOptional = commentLikeRepository.findByComment_IdAndProfile_Id(commentId, profileId);
- if(findCommentLikeOptional.isEmpty()) {
- throw new CustomResponseException(ResponseError.NOT_YET_LIKED_COMMENT);
- }
-
- CommentLike commentLike = findCommentLikeOptional.get();
-
- commentLikeRepository.delete(commentLike);
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/comment/service/CommentService.java b/src/main/java/com/example/feeda/domain/comment/service/CommentService.java
deleted file mode 100644
index 765d8b5..0000000
--- a/src/main/java/com/example/feeda/domain/comment/service/CommentService.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.example.feeda.domain.comment.service;
-
-import com.example.feeda.domain.comment.dto.CommentResponse;
-import com.example.feeda.domain.comment.dto.CreateCommentRequest;
-import com.example.feeda.domain.comment.dto.UpdateCommentRequest;
-import com.example.feeda.domain.comment.entity.Comment;
-import com.example.feeda.domain.comment.repository.CommentRepository;
-import com.example.feeda.domain.post.entity.Post;
-import com.example.feeda.domain.post.repository.PostRepository;
-import com.example.feeda.domain.profile.entity.Profile;
-import com.example.feeda.domain.profile.repository.ProfileRepository;
-import com.example.feeda.exception.CustomResponseException;
-import com.example.feeda.exception.enums.ResponseError;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-
-@Service
-@RequiredArgsConstructor
-public class CommentService {
-
- private final CommentRepository commentRepository;
- private final PostRepository postRepository;
- private final ProfileRepository profileRepository;
-
- @Transactional
- public CommentResponse createComment(Long postId, Long profileId, CreateCommentRequest request) {
- Post post = postRepository.findById(postId)
- .orElseThrow(() -> new CustomResponseException(ResponseError.POST_NOT_FOUND));
- Profile profile = profileRepository.findById(profileId)
- .orElseThrow(() -> new CustomResponseException(ResponseError.PROFILE_NOT_FOUND));
-
- Comment comment = new Comment(post, profile, request.getContent());
- commentRepository.save(comment);
- return CommentResponse.from(comment);
- }
-
- public List getCommentsByPostId(Long postId, String sort) {
- List comments;
-
- if (sort.equalsIgnoreCase("oldest")) {
- comments = commentRepository.findByPostIdOrderByCreatedAtAsc(postId);
- } else {
- comments = commentRepository.findByPostIdOrderByCreatedAtDesc(postId);
- }
-
- return comments.stream()
- .map(CommentResponse::from)
- .toList();
- }
-
- public CommentResponse getCommentById(Long commentId) {
- Comment comment = commentRepository.findById(commentId)
- .orElseThrow(() -> new CustomResponseException(ResponseError.COMMENT_NOT_FOUND));
- return CommentResponse.from(comment);
- }
-
- @Transactional
- public CommentResponse updateComment(Long commentId, Long requesterProfileId, UpdateCommentRequest request) {
- Comment comment = commentRepository.findById(commentId)
- .orElseThrow(() -> new CustomResponseException(ResponseError.COMMENT_NOT_FOUND));
-
- if (!comment.getProfile().getId().equals(requesterProfileId)) {
- throw new CustomResponseException(ResponseError.NO_PERMISSION_TO_EDIT);
- }
-
- comment.updateContent(request.getContent());
- return CommentResponse.from(comment);
- }
-
- @Transactional
- public void deleteComment(Long commentId, Long requesterProfileId) {
- Comment comment = commentRepository.findById(commentId)
- .orElseThrow(() -> new CustomResponseException(ResponseError.COMMENT_NOT_FOUND));
-
- Long authorId = comment.getProfile().getId();
- Long postOwnerId = comment.getPost().getProfile().getId();
-
- if (!authorId.equals(requesterProfileId) && !postOwnerId.equals(requesterProfileId)) {
- throw new CustomResponseException(ResponseError.NO_PERMISSION_TO_DELETE);
- }
-
- commentRepository.delete(comment);
- }
-}
diff --git a/src/main/java/com/example/feeda/domain/follow/controller/FollowsController.java b/src/main/java/com/example/feeda/domain/follow/controller/FollowsController.java
deleted file mode 100644
index f3a04c8..0000000
--- a/src/main/java/com/example/feeda/domain/follow/controller/FollowsController.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.example.feeda.domain.follow.controller;
-
-import com.example.feeda.domain.follow.dto.FollowsResponseDto;
-import com.example.feeda.domain.follow.service.FollowsService;
-import com.example.feeda.domain.profile.dto.ProfileListResponseDto;
-import com.example.feeda.security.jwt.JwtPayload;
-import jakarta.validation.constraints.Min;
-import lombok.RequiredArgsConstructor;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-@Validated
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/api/follows")
-public class FollowsController {
-
- private final FollowsService followsService;
-
- @PostMapping("/{profileId}")
- public FollowsResponseDto follow(@PathVariable Long profileId,
- @AuthenticationPrincipal JwtPayload jwtPayload) {
-
- return followsService.follow(jwtPayload, profileId);
- }
-
- @DeleteMapping("/{followingId}")
- public ResponseEntity