-
Notifications
You must be signed in to change notification settings - Fork 1
Project Architecture
kimhoeyun edited this page Aug 31, 2026
·
4 revisions
현재 Lambda 런타임, 패키지 책임, 데이터와 외부 시스템의 경계를 설명합니다.
flowchart LR
Client["Web / Android Client"]
APIGW["AWS API Gateway"]
Lambda["AWS Lambda\nSpring Boot"]
DB[("PostgreSQL")]
Cache["Caffeine Cache"]
Outbox[("scrape_job_outbox")]
SQS["AWS SQS"]
Worker["Scraping Worker"]
Portal["Suwon Portal"]
S3[("S3 Result Store")]
Obs["CloudWatch / Sentry / Grafana Cloud"]
Client --> APIGW --> Lambda
Lambda --> DB
Lambda --> Cache
Lambda --> Outbox --> SQS --> Worker --> Portal
Worker --> S3
Worker -->|"HMAC callback"| APIGW
Lambda --> S3
Lambda --> Obs
API Gateway가 요청을 Lambda로 전달합니다. Lambda 안에서 Spring Boot가 실행되고 PostgreSQL에 사용자, 학사, 졸업 요건, 포털 작업 상태를 저장합니다.
포털 작업은 요청 스레드에서 직접 스크래핑하지 않습니다. 작업과 Outbox를 같은 트랜잭션에 저장한 뒤 SQS에 발행합니다. Worker가 결과를 S3에 저장하고 HMAC 서명 콜백을 보내면 백엔드가 결과를 읽어 학사 데이터를 갱신합니다.
| 패키지 | 책임 |
|---|---|
domain |
엔티티, 도메인 서비스, 컨트롤러, DTO, 저장소 인터페이스 |
application |
여러 도메인과 인프라를 묶는 유스케이스와 트랜잭션 흐름 |
infrastructure |
포털·OIDC·SQS·S3·캐시 등 외부 시스템 구현 |
global |
Security, 공통 응답, 예외, 로깅, Lambda 설정 |
주요 도메인입니다.
| 도메인 | 역할 |
|---|---|
user, auth
|
OIDC 로그인, 사용자, JWT와 Refresh Token |
student, academic
|
학생 프로필, 학기, 수강·성적 데이터 |
course, professor, department
|
과목과 학과 기준 정보 |
graduation |
학점·영역·복수전공·어학 요건과 졸업 진행도 |
portal, scrapejob
|
포털 연동 요청, Outbox, 상태 조회, 결과 콜백 |
lectureevaluations |
강의평가 대상과 제출 상태 |
admin |
dev 전용 테스트 데이터 API |
- 사용자와 인증은
users,social_accounts,refresh_token에 저장합니다. - 학적 데이터는
students,student_academic_records,semester_academic_records,student_courses를 중심으로 구성됩니다. - 포털 지정과목 원본은
student_designated_courses에 저장하고 마지막 반영 시각은students.designated_courses_snapshot_version에 기록합니다. 지정과목 테이블은student_id외래 키(ON DELETE CASCADE)와(student_id, source_order)unique 제약을 가지며 수강·과목 테이블과 연결하지 않습니다. - 졸업 요건은
graduation_requirements,department_area_requirements,dual_major_requirements, 어학 요건 테이블을 사용합니다. - 포털 작업은
scrape_jobs와scrape_job_outbox에 저장합니다. - 강의평가는
course_evaluations,course_evaluation_tags에 저장합니다.
DDL의 기준은 JPA 엔티티가 아니라 src/main/resources/db/migration의 Flyway SQL입니다.
| 프로필 | DB 스키마 | 관측 | 용도 |
|---|---|---|---|
local |
Hibernate update
|
Sentry·Tracing 비활성 | 개발자 로컬 실행 |
dev |
Hibernate validate
|
dev Sentry, OTLP 설정 가능 | 통합 검증 |
develop-shadow |
dev 포함, async scraping |
dev 설정 계승 | Shadow Worker 연동과 Lambda 기본값 |
prod |
Hibernate validate
|
prod Sentry, OTLP 설정 가능 | 운영 |
애플리케이션 내부 Flyway 실행은 모든 프로필에서 꺼져 있습니다. dev·prod 배포는 별도 GitHub Actions 마이그레이션을 먼저 실행합니다.
일반 Spring Boot 실행의 기본 프로필은 local이지만 StreamLambdaHandler는 SPRING_PROFILES_ACTIVE가 없으면 develop-shadow를 선택합니다. 배포 Workflow는 Lambda 환경 변수를 바꾸지 않으므로 운영 프로필은 외부 인프라 설정에서 확인해야 합니다.
- 로그는 local에서 Console, dev에서 Console·File·Sentry, prod에서 File·Sentry로 기록됩니다. prod Logback에는 Console appender가 없습니다.
- Sentry event에는 가능한 경우
userId,jobId,outboxId,operationType,workerRequestId가 태그로 붙습니다. - Actuator는
health,info,metrics,prometheus를 노출합니다. - Trace context와 span ID 생성은 유지하지만 현재
OtlpAutoConfiguration이 제외돼 OTLP Trace exporter는 자동 구성되지 않습니다. - OTLP Metric export는 별도 설정으로 켤 수 있으며 기본값은 비활성입니다.
- Lambda platform 로그는 CloudWatch에서 확인합니다. 애플리케이션 file 로그가 CloudWatch나 Grafana로 전달되는지는 Lambda Extension과 외부 인프라 설정을 따로 확인해야 합니다.
- 컨트롤러는 인증 주체와 요청 DTO를 받고 서비스에 위임합니다.
- 비즈니스 트랜잭션은
application또는 도메인 서비스에서 관리합니다. - AWS SDK, 외부 OIDC, 포털 클라이언트는
infrastructure에 둡니다. - 공통 예외는
ErrorCode와 공통 응답 형식을 사용합니다. - 공개 API 변경은 Swagger 문서 인터페이스와 테스트까지 함께 변경합니다.
현재 구조의 선택 이유와 운영 제약은 Architecture Decision Records에 기록합니다.