Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b890d79
Merge pull request #1 from codingbaraGo/task1
codingbaraGo Dec 29, 2025
7bab2a8
feat(ci): CI 테스트, LLM 코드리뷰 깃허브 액션 워크플로우 추가
codingbaraGo Dec 30, 2025
5a7f2bf
feat(ci): PR 템플릿 설정
codingbaraGo Dec 30, 2025
2bf814c
fix(ci): spotless check 제거
codingbaraGo Dec 30, 2025
03e8811
fix(ci): JDK 버전 수정
codingbaraGo Dec 31, 2025
851b763
feat(github): 이슈 템플릿 추가(NewFeature)
codingbaraGo Dec 31, 2025
717973a
[Merge] main <- develop
codingbaraGo Jan 1, 2026
76c26d0
fix(ci): CI 테스트 워크플로의 빌드 설정 변경
codingbaraGo Jan 1, 2026
1653c7a
chore: LLM 코드리뷰 액션 트리거 추가(reopened)
codingbaraGo Jan 1, 2026
1ded3a7
[Merge] main <- feat/web/handler/static/#6
codingbaraGo Jan 1, 2026
1888b19
enhance(github): issue template, pr template 수정 및 추가
codingbaraGo Jan 5, 2026
e19754c
Merge pull request #26 from codingbaraGo/develop
codingbaraGo Jan 5, 2026
11d8f81
Merge pull request #27 from codingbaraGo/refactor/architecture/#24
codingbaraGo Jan 5, 2026
f7230bc
Merge pull request #29 from codingbaraGo/enhance/web/adapter/#19
codingbaraGo Jan 6, 2026
5ab0e23
Merge pull request #32 from codingbaraGo/refactor/web/renderer/#31
codingbaraGo Jan 7, 2026
3718d97
Merge pull request #35 from codingbaraGo/feat/http/requestbody/#34
codingbaraGo Jan 8, 2026
d20b2fd
Merge pull request #39 from codingbaraGo/feat/app/login-post/#37
codingbaraGo Jan 8, 2026
2643c30
Merge pull request #42 from codingbaraGo/feat/http/cookie/#41
codingbaraGo Jan 9, 2026
f166bcc
Merge pull request #45 from codingbaraGo/refactor/config/di/#44
codingbaraGo Jan 11, 2026
d9f7a5d
Merge pull request #47 from codingbaraGo/feat/web/filter/#20
codingbaraGo Jan 11, 2026
a966b52
Merge pull request #49 from codingbaraGo/feat/authentication/#22
codingbaraGo Jan 12, 2026
207f901
Merge pull request #52 from codingbaraGo/feat/web/dynamic-view#23
codingbaraGo Jan 13, 2026
5c0ad4c
Merge pull request #54 from codingbaraGo/feat/authentication/logout/#51
codingbaraGo Jan 13, 2026
43760d0
Merge pull request #57 from codingbaraGo/enhance/view/#56
codingbaraGo Jan 13, 2026
b19d7d2
Merge pull request #60 from codingbaraGo/feat/app/image/#59
codingbaraGo Jan 14, 2026
ba864e8
Merge pull request #63 from codingbaraGo/feat/database/repo-template#62
codingbaraGo Jan 15, 2026
5ac100b
feat(app): User 레포지토리 추가
codingbaraGo Jan 15, 2026
2ceb479
feat(app): 회원가입 핸들러에 유효성 검사 로직 추가
codingbaraGo Jan 15, 2026
fdcea4f
enhance(database): SQL 자동생성시 컬럼 네임에 Snake case 적용
codingbaraGo Jan 15, 2026
1e1e8f9
Merge branch 'main' into feat/app/page-register/#65
codingbaraGo Jan 15, 2026
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
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/Enhancement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: '🔥Enhancement Issue'
about: '기존 기능을 개선합니다.'
title: '[domain] - issue title'
labels: 'enhancement'
assignees: ''

---

### 📝 기존 기능
<!--기존 기능의 한계점 혹은 개선이 필요한 이유 설명-->
-

### 🔨 개선 이유 및 개선 사항
<!-- 개선사항 설명-->
-

### ✏️ 작업할 내용
<!--실질적 작업 내용 설명-->
- [ ]
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/NewFeature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: '✨New Feature'
about: '새로운 기능을 추가합니다.'
title: '[domain] - issue title'
labels: 'feature'
assignees: ''

---

### 🎯 새로운 기능
<!--새로운 기능 설명-->
-

### ✏️ 작업할 내용
<!--실질적 작업 내용 설명-->
- [ ]
18 changes: 18 additions & 0 deletions .github/ISSUE_TEMPLATE/Refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
name: '♻️Refactoring issue'
about: '리펙토링 이슈를 추가합니다.'
title: '[domain] - issue title'
labels: 'refactor'
assignees: ''

---

### ♿️ 리펙토링 배경
<!--리펙토링을 하게 된 이유 작성-->
-
<!--리펙토링 대상 코드/도메인 설명-->
-

### 🚚️ 작업할 내용
<!--작업 내용 설명-->
- [ ]
15 changes: 15 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
### 💻 작업 내용
<!-- 진행한 작업 내용에 대해 작성해주세요. -->
-

### ✨ 리뷰 포인트
<!-- (ex) query 가 너무 복잡한 것 같은데 이 위주로 봐주세요. -->

### 📝 메모
<!-- PR 관련 전달사항이 있다면 이곳에 작성해주세요. -->

### 🎯 관련 이슈
<!-- pr이 merge 되면 이슈가 자동으로 close 되도록 합니다. 만약 자동 close 를 하지 않고 이슈만 링크한다면 closed 키워드를 삭제해주세요.-->
closed #이슈번호

<!-- @claude -->
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: CI pipeline

on:
pull_request:
branches:
- develop
- main
workflow_dispatch:
jobs:
#################################################
# 단위 테스트
#################################################
unit-test:
runs-on: ubuntu-24.04
permissions:
contents: read
statuses: write

steps:
# 1) 소스 체크아웃
- name: Checkout branch HEAD
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
persist-credentials: true

# 1-2) race condition 대비용 pull
- name: Ensure latest commit
run: |
git pull --ff-only origin "${{ github.head_ref }}"

# 2) JDK 설치 + Gradle 캐싱
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
cache: 'gradle'

# 3) Gradle Wrapper 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew

# 4) 단위 테스트
- name: Run unit tests
run: ./gradlew --no-daemon test

# 테스트 리포트 업로드
- name: Upload Test Report (HTML)
uses: actions/upload-artifact@v4
with:
name: junit-report
path: build/reports/tests/test/**/*.html
- name: Upload Test Report (XML)
uses: actions/upload-artifact@v4
with:
name: junit-xml-report
path: build/test-results/test/**/*.xml

# 5) 빌드(JAR 파일 생성)
- name: Build jar
run: ./gradlew --no-daemon build -x test --stacktrace

# 빌드 실패 시 로그 업로드
- name: Upload Build Logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: build-logs
path: build/reports/
24 changes: 24 additions & 0 deletions .github/workflows/code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Claude Auto PR Review
on:
pull_request:
types: [opened, reopened]

permissions:
contents: read
pull-requests: write
checks: write
id-token: write

jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Simple LLM Code Review
uses: codingbaraGo/simple-llm-code-review@latest
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
language: korean
11 changes: 11 additions & 0 deletions src/main/java/app/db/UserRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.db;

import app.model.User;
import database.ConnectionManager;
import database.CrudRepository;

public class UserRepository extends CrudRepository<User> {
public UserRepository(ConnectionManager connectionManager) {
super(connectionManager, User.class);
}
}
54 changes: 47 additions & 7 deletions src/main/java/app/handler/RegisterWithPost.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package app.handler;

import app.db.Database;
import app.db.UserRepository;
import app.model.User;
import config.VariableConfig;
import exception.ErrorCode;
import exception.ServiceException;
import http.HttpMethod;
Expand All @@ -14,19 +15,58 @@
import web.response.RedirectResponse;

public class RegisterWithPost extends SingleArgHandler<QueryParameters> {
private static final String EMAIL = "email";
private static final String NICKNAME = "nickname";
private static final String PASSWORD = "password";

private static final Logger log = LoggerFactory.getLogger(RegisterWithPost.class);

public RegisterWithPost() {
private final UserRepository userRepository;

public RegisterWithPost(UserRepository userRepository) {
super(HttpMethod.POST, "/user/create");
this.userRepository = userRepository;
}

@Override
public HandlerResponse handle(QueryParameters params) {
String email = params.getQueryValue("email").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "email required"));
String nickname = params.getQueryValue("nickname").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "nickname required"));
String password = params.getQueryValue("password").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "password required"));
Database.addUser(new User(password, nickname, email, UserRole.MEMBER.toString()));
log.info("Registered - password:{}, nickname:{}, email:{}", password, nickname, email);
String email = getRequired(params, EMAIL);
String nickname = getRequired(params, NICKNAME);
String password = getRequired(params, PASSWORD);

validate(email, nickname, password);

User saved = userRepository.save(
new User(password, nickname, email, UserRole.MEMBER.toString()));

log.info("Registered id:{}, email:{}, nickname:{}, password:{}",
saved.getId(), email, nickname, password);
return RedirectResponse.to("/login");
}

private void validate(String email, String nickname, String password) {
validateDuplicate(email, nickname);
validateLength(email, VariableConfig.EMAIL_MIN, VariableConfig.EMAIL_MAX, ErrorCode.EMAIL_LENGTH_INVALID);
validateLength(nickname, VariableConfig.NICKNAME_MIN, VariableConfig.NICKNAME_MAX, ErrorCode.NICKNAME_LENGTH_INVALID);
validateLength(password, VariableConfig.PASSWORD_MIN, VariableConfig.PASSWORD_MAX, ErrorCode.PASSWORD_LENGTH_INVALID);
}

private String getRequired(QueryParameters params, String key) {
return params.getQueryValue(key)
.orElseThrow(() -> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, key + " required"));
}

private void validateLength(String value, int min, int max, ErrorCode code) {
int len = value.length();
if (len < min || len > max)
throw new ServiceException(code);
}

private void validateDuplicate(String email, String nickname) {
if (!userRepository.findByColumn(EMAIL, email).isEmpty())
throw new ServiceException(ErrorCode.EMAIL_ALREADY_EXISTS);

if (!userRepository.findByColumn(NICKNAME, nickname).isEmpty())
throw new ServiceException(ErrorCode.NICKNAME_ALREADY_EXISTS);
}
}
3 changes: 3 additions & 0 deletions src/main/java/app/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public User(String password, String nickname, String email, String userRole) {
this.userRole = userRole;
}

public User() {
}

public Long getId() {
return id;
}
Expand Down
23 changes: 13 additions & 10 deletions src/main/java/config/AppConfig.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package config;

import app.db.UserRepository;
import app.handler.*;
import database.ConnectionManager;
import database.H2DbManager;
Expand Down Expand Up @@ -120,8 +121,7 @@ public RegisterWithGet registerWithGet() {
public RegisterWithPost registerWithPost() {
return getOrCreate(
"registerWithPost",
RegisterWithPost::new
);
() -> new RegisterWithPost(userRepository()));
}

public LoginWithPost loginWithPost() {
Expand Down Expand Up @@ -233,8 +233,9 @@ public QueryParamsResolver queryParamsResolver() {
}

public MultipartFormResolver multipartFormResolver(){
return getOrCreate("multipartFormResolver", () ->
new MultipartFormResolver(multipartFormParser()));
return getOrCreate("multipartFormResolver",
() -> new MultipartFormResolver(multipartFormParser()));

}

public MultipartFormParser multipartFormParser(){
Expand All @@ -250,10 +251,7 @@ public ExceptionHandlerMapping exceptionHandlerMapping() {
List.of(
serviceExceptionHandler(),
errorExceptionHandler(),
unhandledErrorHandler()
)
)
);
unhandledErrorHandler())));
}

public ServiceExceptionHandler serviceExceptionHandler() {
Expand Down Expand Up @@ -325,8 +323,13 @@ public H2DbManager h2DbManager(){
}

public DdlGenerator ddlGenerator(){
return getOrCreate(DdlGenerator.class.getSimpleName(), () ->
new DdlGenerator(connectionManager()));
return getOrCreate(DdlGenerator.class.getSimpleName(),
() -> new DdlGenerator(connectionManager()));
}

public UserRepository userRepository(){
return getOrCreate(UserRepository.class.getSimpleName(),
()-> new UserRepository(connectionManager()));
}
}

7 changes: 6 additions & 1 deletion src/main/java/config/DdlGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private String buildDdlForEntity(Class<?> entityClass, String tableName) {
continue;
}

String columnName = field.getName();
String columnName = toColumnName(field.getName());
Class<?> fieldType = field.getType();

if (!firstColumn) {
Expand Down Expand Up @@ -108,4 +108,9 @@ private String toTableName(Class<?> clazz) {
}
return name;
}

private String toColumnName(String str){
String snake = str.replaceAll("(?<!^)([A-Z])", "_$1");
return snake.toLowerCase();
}
}
7 changes: 7 additions & 0 deletions src/main/java/config/VariableConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,11 @@ public class VariableConfig {

public static final long IDLE_MS = 30*60*100;
public static final long ABSOLUTE_MS = 180*60*100;

public static final int EMAIL_MAX = 50;
public static final int EMAIL_MIN = 4;
public static final int NICKNAME_MAX = 12;
public static final int NICKNAME_MIN = 4;
public static final int PASSWORD_MAX = 16;
public static final int PASSWORD_MIN = 4;
}
Loading