Skip to content

Commit fb029c4

Browse files
authored
Merge pull request #93 from prgrms-web-devcourse-final-project/develop
chore[deploy] : 배포
2 parents aeca5c5 + 52a60eb commit fb029c4

37 files changed

+152323
-67
lines changed

.github/workflows/CI-CD_Pipeline.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ jobs:
7575
7676
# JPA 설정 (application-test.yml에서 참조)
7777
TEST_JPA_HIBERNATE_DDL_AUTO=create-drop
78+
79+
email_address=${{ secrets.EMAIL_ADDRESS }}
80+
send_email_password=${{ secrets.EMAIL_PASSWORD }}
81+
send_email_address=${{ secrets.SEND_EMAIL_ADDRESS }}
7882
7983
# Redis 설정 (application-test.yml에서 참조, GitHub Actions 서비스 사용)
8084
TEST_REDIS_HOST=localhost
@@ -204,7 +208,7 @@ jobs:
204208
PROD_DATASOURCE_URL=jdbc:mysql://mysql_1:3306/${{ secrets.DB_NAME }}
205209
PROD_DATASOURCE_USERNAME=${{ secrets.DB_USER }}
206210
PROD_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }}
207-
211+
208212
PROD_REDIS_HOST=redis_1
209213
PROD_REDIS_PORT=6379
210214
PROD_REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}
@@ -232,15 +236,15 @@ jobs:
232236
PROD_DATASOURCE_DRIVER=com.mysql.cj.jdbc.Driver
233237
PROD_DATASOURCE_USERNAME=root
234238
PROD_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }}
235-
239+
236240
PROD_REDIS_HOST=redis_1
237241
PROD_REDIS_PORT=6379
238242
PROD_REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}
239243
EOF
240244
241245
# EC2에서 GHCR 로그인
242246
echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
243-
247+
244248
# 최신 이미지 pull & 컨테이너 실행
245249
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/${{ env.DOCKER_IMAGE_NAME }}:latest
246250
docker stop app1 2>/dev/null || true

backend/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ dependencies {
3535
implementation 'org.springframework.boot:spring-boot-starter-validation'
3636
implementation 'org.springframework.boot:spring-boot-starter-web'
3737
implementation 'org.springframework.boot:spring-boot-starter-actuator'
38+
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '3.0.5'
3839

3940
// API Documentation (문서화)
4041
implementation 'org.apache.commons:commons-lang3:3.18.0'

backend/docker-compose.yml

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ services:
66
container_name: mysql
77
restart: unless-stopped
88
environment:
9-
MYSQL_DATABASE: ${DB_NAME}
10-
MYSQL_USER: ${DB_USER}
11-
MYSQL_PASSWORD: ${DB_PASS}
9+
MYSQL_DATABASE: balaw
10+
MYSQL_PASSWORD: ${DEV_DATASOURCE_PASSWORD}
1211
# 새 변수: 루트 계정 비번 (필수)
13-
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
12+
MYSQL_ROOT_PASSWORD: ${DEV_DB_ROOT_PASSWORD}
1413
TZ: Asia/Seoul
1514
ports:
1615
# 호스트 포트는 원하는 값으로, 컨테이너는 3306 고정
17-
- "${DB_PORT:-3306}:3306"
16+
- "${DEV_DATASOURCE_PORT:-3306}:3306"
1817
volumes:
1918
- mysql-data:/var/lib/mysql
2019
command: >
@@ -23,10 +22,27 @@ services:
2322
--default-time-zone=Asia/Seoul
2423
--skip-log-bin
2524
healthcheck:
26-
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-p${DB_ROOT_PASS}"]
25+
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-p${DEV_DATASOURCE_PASSWORD}"]
26+
interval: 10s
27+
timeout: 5s
28+
retries: 10
29+
30+
redis:
31+
image: redis:7.4
32+
container_name: redis
33+
restart: unless-stopped
34+
ports:
35+
- "${DEV_REDIS_PORT:-6379}:6379"
36+
volumes:
37+
- redis-data:/data
38+
command: >
39+
redis-server --appendonly yes
40+
healthcheck:
41+
test: ["CMD", "redis-cli", "ping"]
2742
interval: 10s
2843
timeout: 5s
2944
retries: 10
3045

3146
volumes:
32-
mysql-data:
47+
mysql-data:
48+
redis-data:

backend/sql/drop.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
drop table ho;
2+
drop table hang;
3+
drop table jo;
4+
drop table jang;
5+
drop table law;
6+
drop table precedent;
7+
8+
ALTER TABLE ho AUTO_INCREMENT = 1;
9+
ALTER TABLE hang AUTO_INCREMENT = 1;
10+
ALTER TABLE jo AUTO_INCREMENT = 1;
11+
ALTER TABLE jang AUTO_INCREMENT = 1;
12+
ALTER TABLE law AUTO_INCREMENT = 1;
13+
ALTER TABLE precedent AUTO_INCREMENT = 1;

backend/sql/lawData.sql

Lines changed: 150586 additions & 0 deletions
Large diffs are not rendered by default.

backend/src/main/java/com/ai/lawyer/domain/law/controller/LawController.java

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,22 @@
55
import com.ai.lawyer.domain.law.entity.Law;
66
import com.ai.lawyer.domain.law.service.LawService;
77
import com.ai.lawyer.global.dto.PageResponseDto;
8+
import io.swagger.v3.oas.annotations.Operation;
89
import lombok.RequiredArgsConstructor;
910
import org.springframework.data.domain.Page;
1011
import org.springframework.http.ResponseEntity;
1112
import org.springframework.web.bind.annotation.*;
1213

1314
@RestController
1415
@RequiredArgsConstructor
15-
@RequestMapping("/law")
16+
@RequestMapping("/api/law")
1617
public class LawController {
1718

1819
private final LawService lawService;
1920

20-
// 법령 리스트 출력
21-
@GetMapping(value = "/list")
22-
public ResponseEntity<?> list(
23-
@RequestParam String query,
24-
@RequestParam int page
25-
) throws Exception {
26-
String lawList = lawService.getLawList(query, page);
27-
return ResponseEntity.ok().body(lawList);
28-
}
29-
3021

3122
@GetMapping(value = "/list/save")
23+
@Operation(summary = "키워드 관련 법령 데이터 저장(벡엔드 전용 API)", description = "벡엔드 데이터 저장용 API입니다")
3224
public ResponseEntity<?> getStatisticsCard(
3325
@RequestParam String query,
3426
@RequestParam int page
@@ -44,15 +36,8 @@ public ResponseEntity<?> getStatisticsCard(
4436
return ResponseEntity.ok().body("Success");
4537
}
4638

47-
@GetMapping("/{id}")
48-
public ResponseEntity<Law> getFullLaw(@PathVariable Long id) {
49-
Law law = lawService.getLawWithAllChildren(id);
50-
51-
return ResponseEntity.ok(law);
52-
}
53-
54-
5539
@PostMapping("/search")
40+
@Operation(summary = "볍령 목록 검색 기능", description = "조건에 맞는 법령 목록을 가져옵니다")
5641
public ResponseEntity<PageResponseDto> searchLaws(@RequestBody LawSearchRequestDto searchRequest) {
5742
Page<LawsDto> laws = lawService.searchLaws(searchRequest);
5843
PageResponseDto response = PageResponseDto.builder()
@@ -64,4 +49,13 @@ public ResponseEntity<PageResponseDto> searchLaws(@RequestBody LawSearchRequestD
6449
.build();
6550
return ResponseEntity.ok(response);
6651
}
52+
53+
@GetMapping("/{id}")
54+
@Operation(summary = "볍령 상세 조회 기능", description = "법령 상세 데이터를 조회합니다 \n" +
55+
"예시: /api/law/1")
56+
public ResponseEntity<Law> getFullLaw(@PathVariable Long id) {
57+
Law law = lawService.getLawWithAllChildren(id);
58+
59+
return ResponseEntity.ok(law);
60+
}
6761
}

backend/src/main/java/com/ai/lawyer/domain/law/dto/LawSearchRequestDto.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.ai.lawyer.domain.law.dto;
22

3+
import io.swagger.v3.oas.annotations.media.Schema;
34
import lombok.Builder;
45
import lombok.Data;
56

@@ -8,13 +9,31 @@
89
@Data
910
@Builder
1011
public class LawSearchRequestDto {
12+
13+
@Schema(description = "법령명", example = "노동")
1114
private String lawName; // 법령명
15+
16+
@Schema(description = "법령분야", example = "법률")
1217
private String lawField; // 법령분야
18+
19+
@Schema(description = "소관부처", example = "고용노동부")
1320
private String ministry; // 소관부처
21+
22+
@Schema(description = "공포일자 시작", example = "2000-03-25")
1423
private LocalDate promulgationDateStart; // 공포일자 시작
24+
25+
@Schema(description = "공포일자 종료", example = "2025-03-25")
1526
private LocalDate promulgationDateEnd; // 공포일자 종료
27+
28+
@Schema(description = "시행일자 시작", example = "2000-03-25")
1629
private LocalDate enforcementDateStart; // 시행일자 시작
30+
31+
@Schema(description = "시행일자 종료", example = "2025-03-25")
1732
private LocalDate enforcementDateEnd; // 시행일자 종료
33+
34+
@Schema(description = "페이지 번호 (0부터 시작)", example = "0")
1835
private int pageNumber; // 페이지 번호
36+
37+
@Schema(description = "페이지 크기", example = "10")
1938
private int pageSize; // 페이지 크기
2039
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.ai.lawyer.domain.lawWord.controller;
2+
3+
import com.ai.lawyer.domain.lawWord.service.LawWordService;
4+
import com.ai.lawyer.domain.precedent.entity.Precedent;
5+
import io.swagger.v3.oas.annotations.Operation;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.PathVariable;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequiredArgsConstructor
15+
@RequestMapping("/api/law-word")
16+
public class LawWordController {
17+
18+
private final LawWordService lawWordService;
19+
20+
@GetMapping("/{word}")
21+
@Operation(summary = "법령 용어 검색", description = "법령 용어에 대한 정의를 반환합니다. \n" +
22+
"예시: /api/law-word/선박")
23+
public ResponseEntity<?> getPrecedent(@PathVariable String word) {
24+
return ResponseEntity.ok(lawWordService.findDefinition(word));
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.ai.lawyer.domain.lawWord.entity;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnore;
4+
import jakarta.persistence.*;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
10+
@Entity
11+
@Data
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class LawWord {
16+
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY)
19+
@JsonIgnore
20+
private Long id;
21+
22+
private String word; // 법률 용어
23+
24+
@Lob
25+
@Column(columnDefinition = "LONGTEXT")
26+
private String definition; // 정의
27+
28+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.ai.lawyer.domain.lawWord.repository;
2+
3+
import com.ai.lawyer.domain.lawWord.entity.LawWord;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.Optional;
8+
9+
@Repository
10+
public interface LawWordRepository extends JpaRepository<LawWord, Long> {
11+
Optional<LawWord> findByWord(String word);
12+
}

0 commit comments

Comments
 (0)