Skip to content

Club-PARD/00_BE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

75 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›οΈ Mora (λͺ¨μ•„) - μž…λ²• 청원 정보 제곡 μ„œλΉ„μŠ€

"λ³΅μž‘ν•œ 청원, 3μ€„λ‘œ 끝내닀." λŒ€ν•œλ―Όκ΅­ ꡭ회 κ΅­λ―Όλ™μ˜μ²­μ›κ³Ό 청원24의 데이터λ₯Ό ν•œκ³³μ— λͺ¨μ•„, AI둜 μ•ŒκΈ° μ‰½κ²Œ λΆ„μ„ν•˜κ³  처리 κ²°κ³Όλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ μ•Œλ €μ£ΌλŠ” ν”Œλž«νΌμž…λ‹ˆλ‹€.


πŸ“– ν”„λ‘œμ νŠΈ μ†Œκ°œ

MoraλŠ” 흩어져 μžˆλŠ” 청원 μ‚¬μ΄νŠΈ(ꡭ회, ν–‰μ •λΆ€)의 데이터λ₯Ό 톡합 μˆ˜μ§‘ν•˜μ—¬ μ œκ³΅ν•©λ‹ˆλ‹€. λ‹¨μˆœν•œ λͺ©λ‘ μ œκ³΅μ„ λ„˜μ–΄, **OpenAI(GPT-4o-mini)**λ₯Ό ν™œμš©ν•΄ 2030 μ„ΈλŒ€κ°€ 읽기 μ‰¬μš΄ **'μΉ΄λ“œλ‰΄μŠ€ ν˜•νƒœ'**둜 λ‚΄μš©μ„ μš”μ•½/λΆ„μ„ν•˜λ©°, μ‚¬μš©μžκ°€ 관심 μžˆλŠ” μ²­μ›μ˜ 처리 κ²°κ³Ό(심사, λ‹΅λ³€ λ“±)κ°€ μ—…λ°μ΄νŠΈλ˜λ©΄ μ΄λ©”μΌλ‘œ μ•Œλ¦Όμ„ μ œκ³΅ν•˜μ—¬ 지속적인 μ •μΉ˜ μ°Έμ—¬λ₯Ό μœ λ„ν•©λ‹ˆλ‹€.


✨ μ£Όμš” κΈ°λŠ₯ (Key Features)

1. πŸ” ν•˜μ΄λΈŒλ¦¬λ“œ 데이터 μˆ˜μ§‘ (Hybrid Data Collection)

  • ꡭ회 청원 (Type 1): Open API와 μ—‘μ…€ νŒŒμ‹±(Apache POI)을 κ²°ν•©ν•˜μ—¬ κ³Όκ±° 데이터뢀터 μ‹€μ‹œκ°„ ν˜„ν™©κΉŒμ§€ λΉˆν‹ˆμ—†μ΄ μˆ˜μ§‘ν•©λ‹ˆλ‹€.
  • 청원 24 (Type 0): APIκ°€ μ—†λŠ” μ •λΆ€ 청원 μ‚¬μ΄νŠΈμ˜ νŠΉμ„±μ„ κ³ λ €ν•˜μ—¬, Selenium 기반의 동적 크둀링으둜 데이터λ₯Ό ν™•λ³΄ν•©λ‹ˆλ‹€. (ν˜„μž¬ 크둀링 μ‚¬μš© κ°€λŠ₯ μ—¬λΆ€λ₯Ό μ •ν™•νžˆ νŒŒμ•…ν•˜μ§€ λͺ»ν•˜μ—¬ κΈ°λŠ₯만 있고 μžμ •λ§ˆλ‹€ 싀행은 λ˜μ§€ μ•Šκ³  μžˆμŠ΅λ‹ˆλ‹€.)

2. πŸ€– AI 기반 μΉ΄λ“œλ‰΄μŠ€ μžλ™ 생성

  • λ³΅μž‘ν•˜κ³  κΈ΄ 청원 원문을 GPT-4o-miniμ—κ²Œ μ „λ‹¬ν•˜μ—¬ λ‹€μŒκ³Ό 같은 κ΅¬μ‘°ν™”λœ λ°μ΄ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.
    • SubTitle: 20λŒ€ νƒ€κ²Ÿμ˜ ν›…ν‚Ή(Hooking) μ†Œμ œλͺ©
    • Summary: 핡심 λ‚΄μš© 3쀄 μš”μ•½
    • Tags: 긍정적 효과 / 뢀정적 μš°λ €μ‚¬ν•­ 뢄석
    • Needs: 청원 κ°œμš”

3. πŸ”” 슀마트 μƒνƒœ 좔적 및 μ•Œλ¦Ό (Smart Batch System)

  • μžμ • 배치(Midnight Batch): 맀일 λ°€ μ‹€ν–‰λ˜μ–΄ λͺ¨λ“  μ²­μ›μ˜ μƒνƒœ(ν˜„μž¬ κ΅­λ―Όλ™μ˜μ²­μ› ν•œμ •)λ₯Ό μžλ™μœΌλ‘œ μ΅œμ‹ ν™”ν•©λ‹ˆλ‹€.
    • 달성 감지: 기간이 λλ‚˜λ©΄ 마감 μƒνƒœλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€.
    • κ²°κ³Ό 좔적: ꡭ회 μ˜μ•ˆ μ‹œμŠ€ν…œμ˜ μœ„μ›νšŒ νšŒλΆ€, 본회의 처리 κ²°κ³Όλ₯Ό κ°μ§€ν•©λ‹ˆλ‹€.
    • 처리결과 감지: κ΅­λ―Όλ™μ˜μ²­μ› OpenApi λ‚΄ <청원 처리결과> ν…μŠ€νŠΈλ₯Ό μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.
  • 이메일 μ•Œλ¦Ό: 청원 처리결과 μƒνƒœ λ³€ν™”κ°€ κ°μ§€λ˜λ©΄ ν•΄λ‹Ή 청원을 μŠ€ν¬λž©ν•œ μœ μ €λ“€μ—κ²Œ 비동기 이메일을 λ°œμ†‘ν•©λ‹ˆλ‹€.
  • (ν˜„μž¬ κ΅­λ―Όλ™μ˜μ²­μ› ν•œμ •μœΌλ‘œ λͺ¨λ“  κΈ°λŠ₯이 μžμ •λ§ˆλ‹€ λŒμ•„κ°€λ©° 결과좔적, 처리결과 감지, 이메일 μ•Œλ¦Όμ€ 청원24도 μžλ™μœΌλ‘œ κΈ°λŠ₯ κ΅¬ν˜„μ€ λ˜μ–΄μžˆμœΌλ‚˜ μžμ •λ§ˆλ‹€ λŒμ•„κ°€κ³  μžˆμ§€λŠ” μ•ŠμŒ)

πŸ› οΈ 기술 μŠ€νƒ (Tech Stack)

Backend

Category Technology Description
Framework Spring Boot 3.4.1 핡심 μ„œλ²„ ν”„λ ˆμž„μ›Œν¬
Language Java 17 κΈ°λ³Έ 개발 μ–Έμ–΄
Database MySQL 8.0 메인 λ°μ΄ν„°λ² μ΄μŠ€ (RDBMS)
ORM Spring Data JPA 객체-관계 λ§€ν•‘ 및 쿼리 처리 (Hibernate 6.6.4)
Security Spring Security & OAuth2 인증/인가 및 ꡬ글 μ†Œμ…œ 둜그인 κ΅¬ν˜„
API Docs Swagger (SpringDoc) REST API λͺ…μ„Έμ„œ μžλ™ν™”

Data Processing & AI (Core Features)

Category Technology Description
Crawling Selenium 동적 μ›Ή νŽ˜μ΄μ§€(청원24, ꡭ회 상세) 데이터 μˆ˜μ§‘ 및 봇 탐지 우회
Data Parsing Apache POI λŒ€μš©λŸ‰ μ—‘μ…€ 데이터λ₯Ό νŒŒμ‹±ν•˜μ—¬ 초기 데이터 적재 νš¨μœ¨ν™”
Batch Spring @Async 크둀링, μƒνƒœ μ—…λ°μ΄νŠΈ, 메일 λ°œμ†‘ λ“± μž₯κΈ° μ‹€ν–‰ μž‘μ—… 비동기 처리
AI OpenAI API (GPT-4o-mini) 청원 원문 뢄석, ν›…ν‚Ή(Hooking) 문ꡬ 생성, 긍정/λΆ€μ • μš”μΈ μΆ”μΆœ

Notification & Infrastructure

Category Technology Description
Email JavaMailSender 청원 μƒνƒœ/κ²°κ³Ό λ³€κ²½ μ‹œ 비동기 μ•Œλ¦Ό 메일 λ°œμ†‘
Server AWS EC2 (Ubuntu) ν΄λΌμš°λ“œ 배포 ν™˜κ²½
Web Server Nginx λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ 및 νƒ€μž„μ•„μ›ƒ μ„€μ •

🎢 ERD μ†Œκ°œ

image
  • Petition

  • id: Long (not null, unique)

  • title: String (not null, unique)

  • type: Integer (not null) β†’ 청원24, κ΅­λ―Όλ™μ˜μ²­μ› / 0,1

  • status: Integer (not null) β†’ 0,1 (μ§„ν–‰, μ’…λ£Œ)

  • subTitle: String (not null)

  • petitionNeeds: String (not null)

  • petitionSummary: String (not null)

  • result: String (not null)

  • category: String (not null) β†’ 무슨 뢄야인지

  • finalDate: LocalDateTime

  • voteStartDate: LocalDateTime (not null)

  • voteEndDate: LocalDateTime (not null)

  • positiveEx: String (not null)

  • negativeEx: String (not null)

  • good: Integer (not null) β†’ μ’‹μ•„μš”

  • bad: Integer (not null) β†’ μ‹«μ–΄μš”

  • allows: Integer (not null) β†’ λ™μ˜μž 수(맀일 μ—…λ°μ΄νŠΈ)

  • url: String (not null)

  • department: String (not null) β†’ μ†Œκ΄€μœ„

  • Laws

  • id: Long (not null, unique)

  • title: String (not null, unique)

  • summary: String(not null)

  • **LawsLink

  • id: Long (pk)

  • petId: UUID (not null)

  • lawId: Long (not null)

  • User

  • id: UUID (unique, not null)

  • name: String (unique, not null)

  • email: String (not null, unique)

  • age: Integer (not null)

  • status: Integer (not null) β†’ 4κ°€μ§€ μƒνƒœ

  • Scrap

  • id: Long (pk)

  • petId: Long (not null)

  • userId: UUID (not null)

  • Comment

  • id: Long (not null,unique)

  • petId: Long (not null)

  • userId: UUID (not null)

  • body: String (not null)

  • Likes

  • id: Long (pk)

  • petId: Long (not null)

  • userId: UUID (not null, unique)

  • like: Integer (not null) β†’ μ‹«μ–΄μš”, μ’‹μ•„μš” / -1,1

πŸ’‘ 기술적 도전 및 ν•΄κ²° (Technical Highlights)

1. 동적 DOM ꡬ쑰의 '청원24' 크둀링 μ •λ°€ν™”

  • 문제: '청원24' μ‚¬μ΄νŠΈλŠ” νŽ˜μ΄μ§€λ§ˆλ‹€ 제λͺ©κ³Ό λ‚ μ§œ μš”μ†Œμ˜ μœ„μΉ˜κ°€ λ―Έμ„Έν•˜κ²Œ λ‹€λ₯΄κ±°λ‚˜, λΆˆν•„μš”ν•œ 뱃지 ν…μŠ€νŠΈκ°€ μ„žμ—¬ μžˆμ–΄ μ •ν™•ν•œ νŒŒμ‹±μ΄ μ–΄λ €μ› μŠ΅λ‹ˆλ‹€.
  • ν•΄κ²°: νŠΉμ • 클래슀λͺ…에 μ˜μ‘΄ν•˜λŠ” λŒ€μ‹ , "μ²˜λ¦¬κΈ°κ΄€"μ΄λΌλŠ” κ³ μ • ν…μŠ€νŠΈλ₯Ό κΈ°μ€€μœΌλ‘œ XPath의 preceding(μ—­λ°©ν–₯ 탐색) 문법을 μ‚¬μš©ν•˜μ—¬ 제λͺ© μœ„μΉ˜λ₯Ό λ™μ μœΌλ‘œ μΆ”μ ν•˜λŠ” λ‘œμ§μ„ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€. μ΅œν›„μ˜ μˆ˜λ‹¨μœΌλ‘œ 전체 ν…μŠ€νŠΈ νŒŒμ‹± λ‘œμ§μ„ μΆ”κ°€ν•˜μ—¬ μ•ˆμ •μ„±μ„ ν™•λ³΄ν–ˆμŠ΅λ‹ˆλ‹€.

2. κΈ€λ‘œλ²Œ 배포 ν™˜κ²½μ˜ Timezone 동기화

  • 문제: 둜컬 개발 ν™˜κ²½(KST)κ³Ό 달리 AWS EC2(UTC) 배포 μ‹œ 청원 λ‚ μ§œκ°€ 9μ‹œκ°„ μ „μœΌλ‘œ κΈ°λ‘λ˜λŠ” 데이터 μ •ν•©μ„± λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
  • ν•΄κ²°:
    1. Ubuntu μ„œλ²„ νƒ€μž„μ‘΄ λ³€κ²½ (timedatectl set-timezone Asia/Seoul)
    2. JVM μ‹€ν–‰ μ˜΅μ…˜ μΆ”κ°€ (-Duser.timezone=Asia/Seoul)
    3. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹œμž‘ μ‹œμ (@PostConstruct)에 TimeZone.setDefault() μ„€μ • -> 3쀑 μ•ˆμ „μž₯치λ₯Ό 톡해 λ°μ΄ν„°μ˜ μ‹œκ°„ 정확성을 ν™•λ³΄ν–ˆμŠ΅λ‹ˆλ‹€.

3. λŒ€λŸ‰ μž‘μ—…μ˜ 비동기 처리 μ΅œμ ν™”

  • 문제: 수천 건의 청원 μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜κ³  이메일을 λ°œμ†‘ν•˜λŠ” κ³Όμ •μ—μ„œ 단일 μŠ€λ ˆλ“œ 처리 μ‹œ νƒ€μž„μ•„μ›ƒμ΄ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
  • ν•΄κ²°: @Async μ–΄λ…Έν…Œμ΄μ…˜μ„ ν™œμš©ν•˜μ—¬ 크둀링, μƒνƒœ 체크, 이메일 λ°œμ†‘μ„ λ³„λ„μ˜ μŠ€λ ˆλ“œ ν’€μ—μ„œ λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•˜λ„λ‘ μ•„ν‚€ν…μ²˜λ₯Ό κ°œμ„ ν–ˆμŠ΅λ‹ˆλ‹€. Selenium μΈμŠ€ν„΄μŠ€ λ˜ν•œ μž¬μ‚¬μš© λ‘œμ§μ„ μ μš©ν•˜μ—¬ λ¦¬μ†ŒμŠ€ 점유λ₯Ό μ€„μ˜€μŠ΅λ‹ˆλ‹€.

πŸš€ μ‹œμž‘ν•˜κΈ° (Getting Started)

1. μ „μ œ 쑰건

  • Java 17
  • Gradle 8.x 이상
  • MySQL 8.0

2. ν”„λ‘œμ νŠΈ 클둠 및 μ„€μ •

git clone [https://github.com/Club-PARD/00_BE.git](https://github.com/Club-PARD/00_BE.git)
cd mora

3. application.yml μ„€μ •

src/main/resources/ κ²½λ‘œμ— application.yml νŒŒμΌμ„ μƒμ„±ν•˜κ³  μ•„λž˜μ™€ 같이 λ°μ΄ν„°λ² μ΄μŠ€, JWT, OAuth2 ν΄λΌμ΄μ–ΈνŠΈ 정보 등을 μ„€μ •ν•©λ‹ˆλ‹€.

spring:
  application:
    name: youngyoung.server.mora

  logging:
    level:
      root: info

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://{DB}:3306/YY_mora?serverTimezone=UTC&characterEncoding=UTF-8&serverTimezone=Asia/Seoul
    username: {name}
    password: {PW}

  mail:
    host: smtp.gmail.com
    port: 587
    username: "{EMAIL}"
    password: "{PW}"
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          connectiontimeout: 5000
          timeout: 5000
          writetimeout: 5000

  jpa:
    show-sql: true
    database-platform: org.hibernate.dialect.MySQLDialect
    database: mysql
    hibernate:
      ddl-auto: update
    generate-ddl: false
    properties:
      hibernate:
        format_sql: true
        enable_lazy_load_no_trans: true

  security:
    oauth2:
      client:
        registration:
          google:
            client-id: {ID}
            client-secret: {SECRET}
            redirect-uri: {BASE}/login/oauth2/code/google
            scope:
              - profile
              - email

openai:
  api:
    key: {KEY}
  model: gpt-4o-mini

open-api:
  assembly:
    key: {KEY}

logging:
  level:
    org.springframework.security: DEBUG
    org.springframework.web.client.RestTemplate: DEBUG
    org.springframework.security.oauth2.client: DEBUG

4. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜λ©΄ https://00-fe.vercel.appμ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“ API μ—”λ“œν¬μΈνŠΈ

Swagger UIλ₯Ό 톡해 λͺ¨λ“  API μ—”λ“œν¬μΈνŠΈμ™€ λͺ…μ„Έλ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • Swagger UI: https://moragora.site/swagger-ui/index.html#/

μ£Όμš” μ—”λ“œν¬μΈνŠΈ:

  • Petition (/petition):
    • GET /{id}: 청원 상세 정보 쑰회
    • GET /cardNews: 청원 λͺ©λ‘(μΉ΄λ“œ λ‰΄μŠ€) 쑰회
    • POST /likes: 청원 곡감/비곡감 처리
    • POST /comment: λŒ“κΈ€ μž‘μ„±
    • GET /comment/{id}: λŒ“κΈ€ 쑰회
    • POST /scrap/{id}: 청원 슀크랩
  • User (/user):
    • POST /signUp: νšŒμ›κ°€μž…
    • GET /me: λ‚΄ 정보 쑰회
    • GET /scrap: μŠ€ν¬λž©ν•œ 청원 쑰회
    • DELETE /delete: νšŒμ› νƒˆν‡΄

About

pard 6th team 00 backend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages