Skip to content
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문) 만약에 신규 모델이 배포 되고 나서 처음 요청 받아서 임베딩을 뽑아놓고 벡터 색인을 했는데, 문제가 발견되서 기존 모델로 롤백이 결정되면 어떻게 되나요?

Copy link
Copy Markdown
Collaborator Author

@baekyutae baekyutae Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0415

기존에는 문제가 되는 데이터들의 재색인을 롤백 완료의 기준으로 잡았는데, 마지막으로 저장된 스냅샷을 불러오는걸 롤백 완료의 기준으로 수정했습니다. 또한 롤백 진행동안 신규 데이터 작업큐를 대기시키지 않고 모델과 인덱스만 복원되면 바로 서비스가 사용 가능하게 수정하였습니다.

서비스 타겟을: notebook lm과 같이 지속적으로 영상을 쌓아두고 지식데이터베이스로 활용하는 사람으로 잡았습니다

서비스 핵심 가치는 검색 가용성 유지를 1순위로 두어 만약의 상황에 롤백을 하게되더라도 최대한 검색 기능을 유지 하는 것을 목표로 롤백 로직을 설계했습니다.

0415 롤백 로직

  1. 신규 모델로 임베딩된 데이터가 포함된 영상은 롤백 복구가 끝날 때까지 검색 범위에서 일시 제외합니다.

  2. 롤백은 모델 배포 직전에 저장한 마지막 정상 서빙 조합 스냅샷을 기준으로 수행합니다.

  3. 이 스냅샷은 당시의 active/previous 모델 버전과 인덱스 식별자를 가리키는 복원 포인터이며, 실제 모델 아티팩트와 인덱스 스냅샷은 저장소에서 복원합니다.

  4. 롤백 복원은 대상 모델 readiness와 스냅샷 인덱스 복원이 완료된 뒤 ModelRelease를 이전 정상 조합으로 되돌리는 방식으로 진행합니다.

  5. 롤백 후 문제 모델 버전으로 임베딩된 데이터는 복원된 서빙 조합에 맞게 백그라운드에서 다시 임베딩·재색인합니다.

  6. 롤백 진행 중에도 신규 업로드 요청과 일반 ingest 처리는 계속할 수 있으며, Search Service는 남아 있는 검색 가능 영상으로 검색을 계속 제공하고 일부 영상이 복구 중임을 사용자에게 고지합니다.

  7. 재임베딩과 재색인이 끝난 영상부터 검색 범위에 순차적으로 다시 포함시키며, 문제 모델로 생성된 기존 인덱스 데이터는 복구 완료 후 비동기로 정리할 수 있도록 설계했습니다.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에는 모든 영상이 색인이 완료되어야 질의가 가능했는데, 복구 시에는 일부 영상만 제거하거나, 일부 영상만으로 서비스를 제공하는 등 정책이 통일성이 부족한 것 같다는 생각이 듭니다.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음... 이부분은 저도 고민이 되는 지점이였는데, 지금 내린 결정으론 모든 영상 색인 완료후 질의 가능이란 정책을 조금 수정하더라도, 복구시에 재색인 데이터를 제외한 검색서비스를 제공하고 그 영향 범위를 고지하는게, 아예 재색인이 완료될 때 까지 기다리는 것보다 검색 서비스 가용성 측면에서 좋다고 생각해서 위와 같이 설계 했습니다.

Comment thread
baekyutae marked this conversation as resolved.
Comment thread
baekyutae marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
132 changes: 132 additions & 0 deletions docs/Diagram/sequence_diagram/SD_Mermaid.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,136 @@ SS->>LLM: LLM 답변 생성 직접 요청 (Direct SDK)<br/>generate_answer(query
LLM-->>SS: answer (+ cited_chunk_ids)

SS-->>C: 최종 응답 반환<br/>{answer, timestamps, topk_chunk_ids, cited_chunk_ids}
```

# 4. Feedback Loop

```mermaid
sequenceDiagram
participant Client
participant CoreAPI as Core API Server
participant MetaDB as Metadata DB
participant FIP as Feedback Ingestion Pipeline
participant ObjStore as Object Storage
participant MLWorker as ML Lifecycle Worker
participant ModelFiles as Model Artifact Files
participant MEE as Managed Embedding Endpoint
participant VS as Vector Store

%% === 피드백 수집 (2.6) ===
rect rgb(230, 245, 255)
Note over Client, ObjStore: 피드백 수집
Client ->> CoreAPI: 검색 응답 단위 피드백 (req_id, rating)
CoreAPI ->> CoreAPI: 사용자 권한 검증
CoreAPI ->> MetaDB: req_id 검색 응답 스냅샷 조회
MetaDB -->> CoreAPI: 스냅샷
CoreAPI ->> CoreAPI: 피드백 유효성 검증<br/>(동일 사용자, 허용 시간, 무효화 여부)
CoreAPI ->> FIP: 검증된 피드백 이벤트 전달<br/>(질의, 응답, 활성 모델/인덱스 정보 포함)
FIP ->> ObjStore: 원본 이벤트 로그 적재
end

%% === 데이터셋 전처리 (2.7) ===
rect rgb(245, 255, 230)
Note over MLWorker, ObjStore: 피드백 데이터셋 생성 - 정기 배치 <br/>운영자 수동 트리거도 가능
MLWorker ->> ObjStore: 신규 피드백 원본 로그 읽기
ObjStore -->> MLWorker: 원본 로그
MLWorker ->> MLWorker: 서빙 맥락(모델 버전, 인덱스)이 기록된 이벤트만<br/>학습 데이터셋으로 변환
MLWorker ->> ObjStore: 학습용 피드백 데이터셋 저장

alt 실행 중인 MLPipelineRun 없음
MLWorker ->> MLWorker: 학습 파이프라인 자동 트리거
else 실행 중인 MLPipelineRun 존재
MLWorker ->> MLWorker: 최신 데이터셋 기준 다음 실행 대기 등록
Note over MLWorker: 이전 대기 실행은 SUPERSEDED 처리
end
end

%% === 모델 재학습 및 재색인 ===
rect rgb(255, 245, 230)
Note over MLWorker, VS: 모델 재학습 및 재색인

%% 학습
MLWorker ->> ObjStore: 학습용 데이터셋 읽기
ObjStore -->> MLWorker: 학습 데이터셋
MLWorker ->> MLWorker: 후보 임베딩 모델 학습
MLWorker ->> ModelFiles: 후보 모델 저장
MLWorker ->> MetaDB: MLPipelineRun 생성

%% 평가
MLWorker ->> ObjStore: 평가용 데이터셋 읽기
ObjStore -->> MLWorker: 평가 데이터셋 (immutable versioned artifact)
MLWorker ->> MLWorker: 후보 모델 vs 기준 모델 비교 평가
MLWorker ->> MetaDB: 평가 결과 집계 저장
MLWorker ->> ObjStore: 평가 질의별 상세 아티팩트 저장

alt 평가 PASS
MLWorker ->> MEE: 후보 모델 로드
MEE -->> MLWorker: readiness 확인
MLWorker ->> MEE: 재색인용 임베딩 요청 (후보 모델)
MEE -->> MLWorker: 임베딩 벡터
MLWorker ->> VS: 후보 인덱스 구축
Note over MLWorker, VS: 전환 기준 시각까지 데이터 반영 +<br/>후보 모델 readiness 모두 확인
Note over MLWorker, VS: 재색인 중 신규 유입 데이터는<br/>기존 서빙 유지하며 후보 인덱스에도 반영
MLWorker ->> MEE: 서빙 모델 전환
MLWorker ->> MetaDB: ModelRelease 갱신 (서빙 전환)
Note over MLWorker: 이전 모델/인덱스 정보 롤백용 보존
else 평가 FAIL 또는 시스템 ERROR
MLWorker ->> MetaDB: MLPipelineRun 실패 단계 및 유형 기록
Note over MLWorker, MetaDB: 기존 서빙 유지,<br/>Admin Dashboard에서 실패 상태 확인 가능
end
end

```

# 5. Admin_Video_Ops
```mermaid
sequenceDiagram
participant Admin as Admin Dashboard
participant CoreAPI as Core API Server
participant MetaDB as Metadata DB
participant Broker as Message Broker
participant PipelineWorker as Media & AI Pipeline Worker
participant ObjStore as Object Storage

Note over Admin, CoreAPI: 모든 Admin 요청은 JWT claim role 기반 운영자 권한 검증,<br/>소유권(user_id) 제한 없이 모든 리소스 접근

%% === 파이프라인 상태 조회 ===
rect rgb(230, 245, 255)
Note over Admin, MetaDB: 파이프라인 상태 조회
Admin ->> CoreAPI: 임의 video_id 처리 현황 조회
CoreAPI ->> MetaDB: Video 상태 및 실패 상세 조회
MetaDB -->> CoreAPI: 처리 현황, failed_stage, error_message
CoreAPI -->> Admin: 처리 현황 및 실패 상세 응답
end

%% === 재처리 ===
rect rgb(245, 255, 230)
Note over Admin, PipelineWorker: 비디오 재처리
Admin ->> CoreAPI: 임의 video_id 재처리 요청
CoreAPI ->> MetaDB: 현재 Video.status 확인
MetaDB -->> CoreAPI: 현재 상태
Note over CoreAPI: 재처리 가능 상태인지 검증 후 진행
CoreAPI ->> MetaDB: Video.status를 PENDING으로 초기화
CoreAPI ->> Broker: PREPROCESS_REQUEST 발행
CoreAPI -->> Admin: 202 Accepted
Broker ->> PipelineWorker: PREPROCESS_REQUEST 전달
PipelineWorker ->> MetaDB: Video 정보 로드, failed_stage 확인
MetaDB -->> PipelineWorker: failed_stage, 보존 산출물 정보
PipelineWorker ->> PipelineWorker: 완료된 작업 Skip, 안전한 재개 지점부터 Resume
end

%% === 삭제 ===
rect rgb(255, 245, 230)
Note over Admin, ObjStore: 비디오 삭제
Admin ->> CoreAPI: 임의 video_id 삭제 요청
CoreAPI ->> MetaDB: Video.status를 DELETING으로 전이
Note over MetaDB: 이 시점부터 검색 범위에서 즉시 제외
CoreAPI ->> Broker: DELETE_REQUEST 발행
CoreAPI -->> Admin: 202 Accepted
Broker ->> PipelineWorker: DELETE_REQUEST 전달
PipelineWorker ->> MetaDB: VectorIndexEntry, Chunk,<br/>TranscriptSegment, Asset 삭제 (단일 트랜잭션)
PipelineWorker ->> MetaDB: Video 레코드 hard-delete
PipelineWorker ->> ObjStore: 원본 영상, 오디오, 키프레임 삭제 (비동기)
Note over PipelineWorker: 수집 피드백 이벤트 및 학습 데이터셋은 보존
end
```
190 changes: 190 additions & 0 deletions docs/git-naming-convention.md
Comment thread
baekyutae marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Git Naming Convention

`Biblio` 프로젝트에서 사용하는 브랜치, 커밋, PR 네이밍 규칙을 정의한다.

## 목적

- 작업 단위를 GitHub Issue 기준으로 일관되게 추적한다.
- 브랜치, 커밋, PR 제목만 보고 변경 목적을 빠르게 파악한다.
- Git 로그와 PR 목록을 사람이 읽기 쉽게 유지한다.

## 기본 원칙

- 작업 식별자는 `GitHub Issue 번호`를 사용한다.
- 브랜치와 PR 제목에는 Issue 번호를 반드시 포함한다.
- 커밋 메시지는 `Conventional Commits` 형식을 사용한다.
- 커밋 메시지의 Issue 번호 포함은 선택 사항으로 한다.
- 기본 머지 방식은 `Squash Merge`를 권장한다.

## Type 규칙

다음 타입만 사용한다.

| Type | 의미 | 사용 예시 |
| --- | --- | --- |
| `feat` | 사용자 관점의 새로운 기능 추가 | API 추가, 검색 기능 추가 |
| `fix` | 기존 동작의 버그 수정 | 예외 처리 보완, 상태 전이 수정 |
| `refactor` | 동작 변경 없는 내부 구조 개선 | 함수 분리, 책임 재구성 |
| `docs` | 문서만 수정 | README, ADR, Spec, Runbook 수정 |
| `test` | 테스트 코드만 추가 또는 수정 | unit/integration test 보강 |
| `chore` | 설정, 의존성, CI, 스크립트 등 잡무성 변경 | lint 설정, dependency update |
| `hotfix` | 운영 이슈 대응을 위한 긴급 수정 | 장애 대응 패치 |

## 브랜치 네이밍

형식:

```text
<type>/<issue-number>-<short-slug>
```

규칙:

- `type`은 위 표의 값 중 하나를 사용한다.
- `issue-number`는 GitHub Issue 번호만 넣는다.
- `short-slug`는 영어 소문자와 하이픈(`-`)만 사용한다.
- `short-slug`는 구현 상세보다 작업 목적을 드러내도록 작성한다.

예시:

```text
feat/123-video-upload
fix/241-search-timeout
refactor/198-preprocess-orchestrator
docs/310-git-naming-convention
test/322-upload-complete-idempotency
chore/415-pre-commit-hooks
hotfix/501-duplicate-callback-guard
```

## 커밋 메시지 네이밍

형식:

```text
<type>(<scope>): <summary>
```

권장 형식:

```text
<type>(<scope>): <summary> (#<issue-number>)
```

규칙:

- `type`은 위 표의 값 중 하나를 사용한다.
- `scope`는 변경이 일어난 서비스 또는 모듈을 나타낸다.
- `summary`는 명령형 현재 시제로 간결하게 작성한다.
- 첫 글자는 소문자로 시작한다.
- 마침표는 붙이지 않는다.
- 하나의 커밋에는 하나의 의도만 담는다.

추천 scope 예시:

- `core-api`
- `search-service`
- `pipeline-worker`
- `managed-embedding-endpoint`
- `repo`
- `docs`

예시:

```text
feat(core-api): add upload completion endpoint (#123)
fix(search-service): handle empty retrieval result (#241)
refactor(pipeline-worker): split preprocess orchestrator
docs(repo): add git naming convention
test(core-api): add upload completion idempotency cases
chore(repo): add commitlint config
hotfix(core-api): reject duplicate callback request (#501)
```

## PR 제목 네이밍

형식:

```text
<type>(<scope>): <summary> [#<issue-number>]
```

규칙:

- 브랜치와 동일한 작업 목적을 유지한다.
- PR 제목만 읽어도 변경 목적이 드러나야 한다.
- PR 제목에는 반드시 GitHub Issue 번호를 포함한다.

예시:

```text
feat(core-api): add video upload initiation API [#123]
fix(search-service): prevent timeout on empty query [#241]
refactor(pipeline-worker): split preprocess workflow [#198]
docs(repo): define git naming convention [#310]
```

## PR 본문 규칙

PR 본문에는 아래 중 하나를 반드시 포함한다.

- `Closes #123`
- `Fixes #123`
- `Refs #123`

권장 예시:

```markdown
## Summary
- add upload completion endpoint
- validate object existence before status transition

## Issue
Closes #123
```

## 예외 규칙

- 아주 작은 저장소 관리 작업은 `no-ticket` 브랜치를 허용할 수 있다.
- `no-ticket`은 문서 오탈자 수정, 로컬 개발 편의 스크립트 정리 등 추적 가치가 낮은 작업에만 사용한다.
- `no-ticket` 사용이 잦아지면 Issue를 먼저 생성하는 것을 기본 원칙으로 되돌린다.

예시:

```text
docs/no-ticket-readme-typo
chore/no-ticket-local-dev-alias
```

## 운영 권장사항

- 하나의 PR은 가능한 한 하나의 Issue만 다룬다.
- 큰 작업은 먼저 Issue로 쪼개고, 브랜치도 그 단위에 맞춰 나눈다.
- `chore`는 남용하지 않는다. 기능이면 `feat`, 버그면 `fix`, 구조 개선이면 `refactor`를 우선 사용한다.
- 운영 장애 대응이 아니면 `hotfix` 대신 일반 `fix`를 사용한다.

## 빠른 예시

Issue:

```text
#123 Add video upload initiation API
```

브랜치:

```text
feat/123-video-upload-initiation
```

커밋:

```text
feat(core-api): add upload initiation endpoint (#123)
```

PR:

```text
feat(core-api): add video upload initiation API [#123]
```
Loading
Loading