Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
1bd068f
Merge branch 'main' into develop
Smallt0wn Aug 8, 2025
53c6132
[FEAT] SecurityConfig에 Grafana path 설정
ydking0911 Aug 8, 2025
e2e10c0
[FIX] /grafana/ 적용에 대한 Nginx 수정
ydking0911 Aug 8, 2025
a956ae7
[HOTFIX] .env 삭제
ydking0911 Aug 8, 2025
758539c
Merge pull request #69 from Alzheimer-dinger/feature/OPS-44
ydking0911 Aug 8, 2025
3c23d8d
[FIX] CICD develop branch로 변경
ydking0911 Aug 8, 2025
9d53e09
[HOTFIX] CICD 변경
ydking0911 Aug 8, 2025
08ad586
[HOTFIX] CICD 복구
ydking0911 Aug 8, 2025
ef76e52
[HOTFIX] Nginx upstream 분리
ydking0911 Aug 8, 2025
d832be8
[FIX] Grafana Domain 지정
ydking0911 Aug 8, 2025
91c4a12
Merge pull request #70 from Alzheimer-dinger/feature/OPS-44
ydking0911 Aug 8, 2025
6cf4c0b
[HOTFIX] Nginx 헤더 Map으로 변경 및 추가
ydking0911 Aug 8, 2025
b3a4c65
[HOTFIX] 디버그 추가 후 테스트
ydking0911 Aug 8, 2025
8473ebb
[HOTFIX] 프록시 패스 경로 수정
ydking0911 Aug 8, 2025
20103b7
[FEAT] Nginx prometheus 설정
ydking0911 Aug 8, 2025
158c5b7
Merge pull request #71 from Alzheimer-dinger/feature/OPS-44
ydking0911 Aug 8, 2025
a08ae44
Merge branch 'develop' into feature/OPS-43
Smallt0wn Aug 8, 2025
a8629c6
[FIX] Nginx cors 처리 부분 수정
Smallt0wn Aug 8, 2025
82dba8b
Merge pull request #72 from Alzheimer-dinger/feature/OPS-43
Smallt0wn Aug 8, 2025
c760777
[HOTFIX] Nginx cors 설정 수정
Smallt0wn Aug 8, 2025
ccc3285
[HOTFIX] Nginx cors 경로 수정
Smallt0wn Aug 8, 2025
0226c32
[HOTFIX] Nginx cors path 검토 및 수정
Smallt0wn Aug 8, 2025
29532fb
[HOTFIX] Nginx 설정 변경 및 처리 위치 변경
Smallt0wn Aug 8, 2025
69753cd
[HOTFIX] cors 중복 처리 수정
Smallt0wn Aug 8, 2025
7bba090
[FEAT] AOP를 통해 metric 수집
ydking0911 Aug 10, 2025
2a09e89
Merge pull request #73 from Alzheimer-dinger/feature/OPS-44
ydking0911 Aug 10, 2025
d2d5b16
[HOTFIX] MetrixAspect에 로그 및 어노테이션 추가
ydking0911 Aug 10, 2025
fcfc13e
[HOTFIX] CORS application.yml에 도메인 추가
ydking0911 Aug 10, 2025
da70dac
[FEAT] 프로필 수정 로직 구현
ydking0911 Aug 10, 2025
d26c0e5
[FIX] UseCase 수정
ydking0911 Aug 10, 2025
32e7e15
[FIX] remove unusage import
ydking0911 Aug 10, 2025
4293630
[FEAT] 테스트 코드 추가
ydking0911 Aug 10, 2025
964af48
Merge pull request #75 from Alzheimer-dinger/feature/OPS-45
ydking0911 Aug 10, 2025
d490f4c
[REFACTOR] 분리된 분석 도메인 적용 및 리포트 로직 정리
Smallt0wn Aug 12, 2025
e36d948
Merge pull request #78 from Alzheimer-dinger/feature/OPS-46
Smallt0wn Aug 12, 2025
a0be9d5
Merge branch 'develop' into feature/OPS-47
Smallt0wn Aug 12, 2025
1496d06
[FIX] 프로필 업로드 시 받는 fileKey 생성 수정
ydking0911 Aug 13, 2025
6b0416e
Merge pull request #79 from Alzheimer-dinger/feature/OPS-45
ydking0911 Aug 13, 2025
6a0ea1d
[HOTFIX] 이미지 업로드 로직 복구
ydking0911 Aug 13, 2025
5b840b0
[HOTFIX] 업로드된 이미지 적용 버그 수정
ydking0911 Aug 13, 2025
69d62bb
[FEAT] 이전 업로드 이미지 삭제 로직 구현
ydking0911 Aug 13, 2025
644eb04
Merge pull request #81 from Alzheimer-dinger/feature/OPS-47
ydking0911 Aug 13, 2025
3ed3368
hotfix: response 수정
KoungQ Aug 13, 2025
6f6c233
hotfix: 로직 수정
KoungQ Aug 13, 2025
9ee2713
hotfix: 응답 수정
KoungQ Aug 13, 2025
0703ee1
hotfix: 리턴값 수정
KoungQ Aug 13, 2025
02db329
[FEAT] Transcript 관련 기능 구현
Smallt0wn Aug 13, 2025
fed8186
[FIX] Analysis/Transcript 전반 수정 및 안정화
Smallt0wn Aug 13, 2025
27b5331
Merge remote-tracking branch 'origin/feature/OPS-47' into feature/OPS-47
Smallt0wn Aug 13, 2025
cddc643
Merge pull request #83 from Alzheimer-dinger/feature/OPS-47
Smallt0wn Aug 13, 2025
9219cf1
fix: 버그 수정
KoungQ Aug 13, 2025
52b1255
fix: 로직 수정
KoungQ Aug 13, 2025
114d53c
refactor: validation 추가
KoungQ Aug 13, 2025
26b4e00
refactor: validation 추가
KoungQ Aug 13, 2025
305a2eb
Merge branch 'main' into develop
ydking0911 Aug 14, 2025
59c3dbb
ci(nginx): AI Call 백엔드 업스트림 추가 및 경로 분기 처리
hyunbridge Aug 14, 2025
76abc2a
Merge pull request #84 from Alzheimer-dinger/ci/ws
Smallt0wn Aug 14, 2025
66f05cd
[HOTFIX] Analysis report entity 타입 수정
Smallt0wn Aug 15, 2025
eaac50a
[REFACTOR] 분석 API 일/월 응답 분리 및 월간 엔드포인트 추가
Smallt0wn Aug 15, 2025
6d3af6b
Merge pull request #86 from Alzheimer-dinger/feature/OPS-49
Smallt0wn Aug 15, 2025
998222b
[HOTFIX] 분석 도메인 네이밍 변경 및 테스트코드 수정
Smallt0wn Aug 15, 2025
2c9639e
[FEAT] 통합 보고서 평균 통화 시간 Transcript 기반 계산 및 반환 로직 구현
Smallt0wn Aug 15, 2025
aa41a2b
Merge pull request #88 from Alzheimer-dinger/feature/OPS-50
Smallt0wn Aug 15, 2025
2a39bc1
hotfix: log
KoungQ Aug 15, 2025
ed630be
Merge branch 'develop' of https://github.com/Alzheimer-dinger/BE into…
KoungQ Aug 15, 2025
f64a314
hotfix: exception
KoungQ Aug 15, 2025
0a645a4
hotfix: 주석 해제
KoungQ Aug 15, 2025
39198ca
fix: 로직 수정
KoungQ Aug 16, 2025
f136fd0
[FEAT] ReadME.md 파일 생성
ydking0911 Aug 16, 2025
f10cd10
fix: exception
KoungQ Aug 16, 2025
e449760
fix: error
KoungQ Aug 16, 2025
e65f752
fix: entity
KoungQ Aug 16, 2025
5db09c1
fix: type
KoungQ Aug 16, 2025
279c2b1
fix: type
KoungQ Aug 16, 2025
1a8df1c
[FIX] user domain 예시 추가
ydking0911 Aug 16, 2025
a51a7d8
fix: query
KoungQ Aug 16, 2025
f487f64
refactor: notification messaging
KoungQ Aug 16, 2025
ed9ee31
fix: validation
KoungQ Aug 16, 2025
174cce1
refactor: notification messaging
KoungQ Aug 16, 2025
00dcea4
Merge pull request #90 from Alzheimer-dinger/feature/OPS-51
ydking0911 Aug 16, 2025
626709d
refactor: relation logic
KoungQ Aug 16, 2025
22ec94b
Merge branch 'develop' of https://github.com/Alzheimer-dinger/BE into…
KoungQ Aug 16, 2025
c705a1e
refactor: relation logic
KoungQ Aug 16, 2025
891bf87
refactor: resend logic
KoungQ Aug 16, 2025
dc146e4
fix: resend logic
KoungQ Aug 16, 2025
cb946d8
fix: relation logic
KoungQ Aug 16, 2025
cf2a840
fix
KoungQ Aug 16, 2025
4416622
refactor: response
KoungQ Aug 16, 2025
8ce56d9
refactor: profile image
KoungQ Aug 17, 2025
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
Binary file added .DS_Store
Binary file not shown.
4 changes: 3 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/src/main/resources/secret/
/src/main/resources/secret/
/src/main/resources/firebase/
/.env
12 changes: 6 additions & 6 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI/CD Pipeline

on:
push:
branches: [ main ] # develop
branches: [ develop ]
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -55,12 +55,12 @@ jobs:

# repo clone / pull
if [ ! -d /opt/your-app ]; then
git clone --branch main https://github.com/Alzheimer-dinger/BE.git /opt/your-app
# git clone --branch develop https://github.com/Alzheimer-dinger/BE.git /opt/your-app
# git clone --branch main https://github.com/Alzheimer-dinger/BE.git /opt/your-app
git clone --branch develop https://github.com/Alzheimer-dinger/BE.git /opt/your-app
else
cd /opt/your-app
git pull origin main
# git pull origin develop
# git pull origin main
git pull origin develop
fi

# 작업 디렉토리 이동
Expand Down Expand Up @@ -102,4 +102,4 @@ jobs:

# 4) Docker Compose로 배포
docker-compose pull springboot
docker-compose up -d --remove-orphans
docker-compose up -d --remove-orphans
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ build/
!**/src/test/**/build/
/logs/
/src/main/resources/secret/
/src/main/resources/firebase/
/.env

--data-binary
-H
/--data-binary
/-H

### STS ###
.apt_generated
Expand Down
848 changes: 848 additions & 0 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation("org.springframework.boot:spring-boot-starter-aop")

// Kafka
implementation 'org.springframework.kafka:spring-kafka'
Expand Down
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ services:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
command:
- --config.file=/etc/prometheus/prometheus.yml
- --web.external-url=https://api.alzheimerdinger.com/prometheus/
ports:
- "9090:9090"
networks:
Expand All @@ -116,6 +119,8 @@ services:
environment:
GF_SECURITY_ADMIN_USER: "${GRAFANA_ADMIN_USER}"
GF_SECURITY_ADMIN_PASSWORD: "${GRAFANA_ADMIN_PASSWORD}"
GF_SERVER_SERVE_FROM_SUB_PATH: "true"
GF_SERVER_ROOT_URL: "https://api.alzheimerdinger.com/grafana/"
ports:
- "3000:3000"
networks:
Expand Down
67 changes: 57 additions & 10 deletions nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
@@ -1,29 +1,76 @@
# 80 포트 - 헬스체크만 예외, 나머지는 HTTPS에 담당
server {
listen 80;
server_name alzheimerdinger.com www.alzheimerdinger.com api.alzheimerdinger.com;

add_header 'Access-Control-Allow-Origin' 'http://localhost:5173 http://localhost:8080' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Upgrade,Connection' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
# CORS headers are handled by Spring Boot only

# API & WebSocket 프록시
location / {
proxy_pass http://app;
# WebSocket 프록시
location /ws/ {
proxy_pass http://call;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;

# 타임아웃
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;

# 버퍼링 비활성화
proxy_buffering off;
proxy_cache_bypass $http_upgrade;
}

# API 프록시
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# Grafana
location = /grafana { return 301 /grafana/; } # spring으로 프록시 방지
location /grafana/ {
proxy_pass http://grafana;
proxy_http_version 1.1;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-Proto $xfp;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /grafana;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_redirect off;
}

# Prometheus
location = /prometheus { return 301 /prometheus/; } # spring으로 프록시 방지
location /prometheus/ {
proxy_pass http://prometheus;
proxy_http_version 1.1;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-Proto $xfp;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /prometheus;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_redirect off;
}
}
25 changes: 15 additions & 10 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,26 @@ http {
default upgrade;
'' close;
}

# LB가 준 값이 있으면 그대로, 없으면 https로 간주
map $http_x_forwarded_proto $xfp {
default $http_x_forwarded_proto;
"" https;
}

upstream app {
server springboot:8080;
}
upstream call {
server 172.17.0.1:8765;
}
upstream grafana {
server grafana:3000;
}
upstream prometheus {
server prometheus:9090;
}

# Load server configurations from conf.d
include /etc/nginx/conf.d/*.conf;

# HTTPS 설정(SSL 인증서가 있을 경우)
# server {
# listen 443 ssl;
# ssl_certificate /etc/nginx/certs/fullchain.pem;
# ssl_certificate_key /etc/nginx/certs/privkey.pem;
# include /etc/nginx/certs/options-ssl-nginx.conf;
# ssl_dhparam /etc/nginx/certs/ssl-dhparams.pem;
# …위와 동일한 location / 설정…
# }
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
package opensource.alzheimerdinger.core.domain.analysis.application.dto.response;

import java.time.LocalDate;
import java.util.List;

public record AnalysisDayResponse(
String userId,
LocalDate analysisDate,
boolean hasData,

Double happyScore,
Double sadScore,
Double angryScore,
Double surprisedScore,
Double boredScore,

List<EmotionSummary> monthlyEmotionData
Double boredScore
) {

public record EmotionSummary(
LocalDate date,
String emotionType
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package opensource.alzheimerdinger.core.domain.analysis.application.dto.response;

import java.time.LocalDate;
import java.util.List;

public record AnalysisMonthlyEmotionResponse(
String userId,
LocalDate month,
List<EmotionSummary> monthlyEmotionData
) {
public record EmotionSummary(
LocalDate date,
String emotionType
) {}
}


Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ public record AnalysisResponse(

Double averageRiskScore,

List<EmotionDataPoint> emotionTimeline,
List<EmotionDataScore> emotionTimeline,

Integer totalParticipate,
String averageCallTime // 임시값으로 지정되어 있는 상황 AI쪽 구현 후 수정 필요
) {
public record EmotionDataPoint(
public record EmotionDataScore(
LocalDate date,

Double happyScore,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import opensource.alzheimerdinger.core.domain.analysis.application.dto.response.AnalysisResponse;
import opensource.alzheimerdinger.core.domain.analysis.application.dto.response.AnalysisDayResponse;
import opensource.alzheimerdinger.core.domain.analysis.application.dto.response.AnalysisReportResponse;
import opensource.alzheimerdinger.core.domain.analysis.application.dto.response.AnalysisMonthlyEmotionResponse;
import opensource.alzheimerdinger.core.domain.analysis.domain.entity.AnalysisReport;
import opensource.alzheimerdinger.core.domain.analysis.domain.service.AnalysisService;
import opensource.alzheimerdinger.core.global.metric.UseCaseMetric;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
Expand All @@ -20,25 +22,34 @@ public class AnalysisUseCase {


//특정 기간 감정 분석 데이터 조회
@UseCaseMetric(domain = "analysis", value = "get-period", type = "query")
public AnalysisResponse getAnalysisPeriodData(String userId, LocalDate start, LocalDate end) {
return analysisService.getPeriodData(userId, start, end);
}


//일별 감정 분석 데이터 조회 (달력용 데이터 포함)
@UseCaseMetric(domain = "analysis", value = "get-day", type = "query")
public AnalysisDayResponse getAnalysisDayData(String userId, LocalDate date) {
return analysisService.getDayData(userId, date);
}

// 월간 달력용 데이터 조회
@UseCaseMetric(domain = "analysis", value = "get-month", type = "query")
public AnalysisMonthlyEmotionResponse getAnalysisMonthlyEmotionData(String userId, LocalDate date) {
return analysisService.getMonthlyEmotionData(userId, date);
}

//기존 분석 리포트 중 가장 최근 리포트 조회
@UseCaseMetric(domain = "analysis", value = "get-latest-report", type = "query")
public AnalysisReportResponse getLatestReport(String userId, LocalDate periodEnd) {
AnalysisReport latestReport = analysisService.findLatestReport(userId, periodEnd);

return new AnalysisReportResponse(
latestReport.getAnalysisReportId(),
userId,
latestReport.getCreatedAt().toLocalDate(),
latestReport.getReport()
latestReport.getContent()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,31 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import opensource.alzheimerdinger.core.domain.user.domain.entity.User;
import opensource.alzheimerdinger.core.global.common.BaseEntity;
import opensource.alzheimerdinger.core.domain.user.domain.entity.User;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "analysis_report")
@Table(name = "reports")
public class AnalysisReport extends BaseEntity {

@Id @Tsid
@Column(name = "id")
private String analysisReportId;

private String report;
// Self reference to base report (nullable)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "base_report_id")
private AnalysisReport baseReport;

@Column(name = "session_id", nullable = false)
private String sessionId;

@Column(name = "content", columnDefinition = "TEXT")
private String content;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package opensource.alzheimerdinger.core.domain.analysis.domain.entity;

import io.hypersistence.utils.hibernate.id.Tsid;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import opensource.alzheimerdinger.core.domain.user.domain.entity.User;
import opensource.alzheimerdinger.core.global.common.BaseEntity;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "dementia_analysis")
public class DementiaAnalysis extends BaseEntity {

@Id @Tsid
@Column(name = "id")
private String dementiaId;

@Column(name = "session_id", nullable = false)
private String sessionId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@Column(name = "risk_score", nullable = false)
private double riskScore;
}


Loading