Skip to content

Project Architecture

kimhoeyun edited this page Aug 31, 2026 · 4 revisions

Project Architecture

현재 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
Loading

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_jobsscrape_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이지만 StreamLambdaHandlerSPRING_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에 기록합니다.

Clone this wiki locally