Feature/analysis integration - 수신 처리 인프라 통합 #26
Merged
Conversation
us-09 시리즈 작업물(feature/us-09-resume-analyzer →
feature/us-09-repo-web-analyzer → feature/us-09-chunking-embedding)을
스프린트 1 통합 브랜치로 가져옴.
- analyzer/{resume,repository,web_resume}_analyzer.py: 3종 분석 파이프라인
- analyzer/sources/{pdf,github_repo,web}.py: 소스 추출기 + 추상화
- chain/document_analysis_chain.py + prompts: LangChain 분석 체인
- rag/chunker.py + embedder.py: 청킹 + 임베딩 (Gemini/Mock)
- core/client.py: Core 내부 API 클라이언트 (github-token, embeddings upsert)
- messaging/consumers/{resume,repository,web}_consumer.py
- messaging/runner.py: 3개 consumer wiring
- storage/{s3,local_fs}: 객체 스토리지 추상화
- infra/rabbitmq/definitions.json: ai.analyze.web 큐 추가
- 123 tests passing
- docs/messaging.md: ai.analyze.web 큐/RK 추가, analyze.resume·repository envelope 필드를 AI 구현(filePath, analyzedDocumentId, repoFullName)에 맞춰 갱신. callback.analysis는 documentPath + targetType WEB 추가. 스모크 테스트 페이로드도 신 스키마로. - docs/messaging.md §10 신설: AI ↔ Core 내부 API(github-token, embeddings) - docs/api-conventions.md §2.6 + §10: /api/internal/* 컨벤션과 두 endpoint의 요청·응답·에러 코드 명시. X-Internal-API-Key 헤더 인증. - docs/environment.md §4 AI Server: LLM 게이트웨이, storage, Core internal, GitHub repo, web fetch, embedding, MD 키 템플릿 변수 카탈로그 갱신. - docs/environment.md §7: AI 큐 매핑에 repository/web 큐 추가. - infra/CLAUDE.md §5.1: ai.analyze.web 표 항목 추가.
스프린트 1 분석 파이프라인의 Core 측 통합.
- Flyway V4: analyzed_documents 라이프사이클 컬럼(analysis_status,
error_code, error_message, embedding_chunk_count), document_embeddings
테이블(pgvector ivfflat 인덱스 포함), processed_messages 테이블 추가.
- AnalysisStatus 열거형 + AnalyzedDocument 도메인 메서드(forResume/
forRepository, markAnalyzed/markFailed)
- Resume / GithubRepository 에 markAnalyzing/Analyzed/Failed 도메인 메서드
- ProcessedMessage 엔티티 (common/messaging/domain) — 비동기 멱등성
- DocumentEmbeddingRepository 인터페이스 + JdbcTemplate 기반 pgvector
upsert 구현 (vector literal 직렬화 포함)
발행 측:
- AnalyzeResumePayload, AnalyzeRepositoryPayload (camelCase 필드로 AI 측
pydantic camel_config 와 정합)
- AnalysisRequestService: AnalyzedDocument(PROCESSING) row 생성 후 도메인
이벤트로 트랜잭션 커밋 이후 발행 (transactional outbox 간이판)
- InternalAnalysisTriggerController: /api/internal/analyses/{resume|repository}/{id}
e2e 검증 트리거 endpoint
소비 측:
- AnalysisCallbackEnvelope (구체 타입 — generic 추론 회피)
- AnalysisCallbackPayload
- AnalysisCallbackHandler: @RabbitListener on core.callback.analysis,
도메인 갱신은 AnalysisCallbackService 에 위임
- 멱등 처리: envelope.messageId → processed_messages INSERT
- 성공 시 AnalyzedDocument.markAnalyzed + 소스 도메인 ANALYZED + SSE 푸시
- 실패 시 markFailed + SSE 푸시
내부 API:
- /api/internal/users/{userId}/github-token (github 슬라이스에 위치 —
user → github 순환 의존 회피)
- PUT /api/internal/documents/{documentId}/embeddings: 청크/임베딩
idempotent upsert. dim 불일치 검증, 존재하지 않는 document 시 404.
- InternalApiKeyAuthenticationFilter: X-Internal-API-Key 헤더 검증,
유효 시 INTERNAL 권한 부여. SecurityConfig 에서 /api/internal/** 은
hasAuthority("INTERNAL") 로 게이트.
- SecurityProperties.internalApiKey 추가, application*.yml 동기화.
테스트:
- StackupApplicationTests 에 신규 repository @MockitoBean 추가
- ArchUnit 룰 통과 (도메인 의존 방향, 순환 없음, presentation→JpaRepository
금지, @transactional application-only, entity는 ..domain..)
Core → RealTime 단방향 push 채널을 wiring.
- RabbitMqProperties: exchanges.names.realtime, routingKeys.realtimeSessionNotify
- RabbitMqConfig: stackup.realtime TopicExchange 빈 declare
(q.realtime.session.notify 큐 + binding 은 RealTime 서버 / definitions.json
이 자체 관리 — Core 는 exchange 만)
- RealtimeNotifyPublisher: publishSessionNotify(sessionId, userId, eventType, data)
헬퍼. envelope.payload = {eventType, data}, context.sessionId 강제.
docs/messaging.md §5.12 envelope 정합.
- application.yml: realtime 키 / RK 추가
- 테스트 fixture (RabbitMessagePublisherTest) 정합
분석 콜백 흐름에서는 사용하지 않음 (세션 전 단계라 sessionId 없음 — Core 자체
SseEventPublisher 가 /api/stream/documents/{id} 로 push). 본 publisher 는
US-13+ 세션/꼬리질문/피드백 단계에서 활용.
스프린트 1 분석 파이프라인 e2e 를 위해 stackup-ai 컨테이너에 다음을 주입. - CORE_INTERNAL_BASE_URL: 호스트에서 동작하는 Core(38010) 도달용 (extra_hosts: host.docker.internal → host-gateway 매핑 추가) - CORE_INTERNAL_API_KEY: X-Internal-API-Key 헤더 값 - EMBEDDING_PROVIDER (default mock): LLM 키 없이도 청킹+임베딩 흐름 검증 가능 - EMBEDDING_MODEL / EMBEDDING_DIM / GEMINI_API_KEY
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
record 는 implicit final 이라 @transactional 메서드에 대한 Spring AOP CGLIB 프록시 생성이 실패하고, 운영 컨테이너에서 부팅 중 BeanCreationException 으로 죽음 (Caused by: Cannot subclass final class GithubUserService). 테스트 프로파일에서는 DataSource/Hibernate autoconfig 제외로 TransactionManager 가 없어 AOP advisor 가 활성화되지 않아 contextLoads 가 통과한 탓에 그동안 감지 못함. 일반 class + 생성자 주입으로 변환. 동작 변경 없음.
…Listener 제약 호환
…ext 필드 forward 보장
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 사항
코어 - AI 서버간 이력서 및 리포지토리 분석 요청 작업을 처리합니다.
프론트엔드 외 나머지 부분을 통합합니다.