flowchart TB
Browser[React Browser Client] --> Edge[Cloudflare Tunnel / Ingress]
Edge --> Backend[Spring Boot Backend]
Browser --> Kakao[Kakao Maps]
Backend --> Redis[(Redis)]
Backend --> Core[(PostgreSQL core)]
Backend --> Kafka[Kafka]
Backend --> AI[FastAPI AI Service]
Kafka --> AI
AI --> Derived[(PostgreSQL ai + pgvector)]
AI --> Models[Embedding / LLM / Vision]
| 경계 | 소유 데이터와 책임 |
|---|---|
| Frontend | 화면·라우팅·서버 상태 캐시·탭 간 Refresh 조정. Credential을 저장하지 않습니다. |
| Backend | 사용자 인증, Core 도메인, 권한·공개 범위, AI 요청과 최종 응답 조립을 소유합니다. |
| AI | ai 스키마의 파생 데이터와 모델 호출을 소유하며 core 스키마를 읽지 않습니다. |
| Infra | 이미지 공급망, Kubernetes 선언 상태, Secret, NetworkPolicy, 관측·백업을 소유합니다. |
- 브라우저는 FastAPI AI 서버나 PostgreSQL에 직접 접근하지 않습니다.
- Backend는 인증된 사용자의 Core 원문과 소유권을 확인하고 AI에는 처리에 필요한 식별자와 제한된 입력만 전달합니다.
- AI 애플리케이션 DB Role은
ai스키마만 읽고 씁니다.core스키마는 search path와 권한에서 제외합니다. - 외부에 공개되는 Collection 응답은 Context 원문과 내부 Member·Record·Context ID를 포함하지 않습니다.
sequenceDiagram
actor User
participant Browser
participant Back as Spring Security
participant Provider as Google / Kakao / Naver
participant Redis
User->>Browser: 소셜 로그인 선택
Browser->>Back: OAuth 인가 시작
Back->>Provider: 인가 요청
Provider-->>Back: Authorization Code
Back->>Provider: 사용자 정보 확인
Back->>Redis: 회전형 Refresh 세션 저장
Back-->>Browser: HttpOnly Access·Refresh + CSRF Cookie
Browser->>Back: API 요청 + CSRF Header
Back-->>Browser: 인증된 응답
Access·Refresh Token은 JavaScript가 읽을 수 없는 HttpOnly Cookie로 전달합니다. 상태 변경 요청은 별도 CSRF Cookie와 Header가 일치해야 합니다. Access 만료 시 Frontend가 Refresh를 한 번 호출하고, 여러 탭의 동시 회전은 Promise 공유와 Web Locks로 직렬화합니다. 이전 Refresh Token 재사용은 회원 단위 세션 폐기로 이어집니다.
sequenceDiagram
actor User
participant Front
participant Back
participant DB as PostgreSQL
participant Queue as Kafka
participant AI
participant Model
User->>Front: 장소와 Context 저장
Front->>Back: Record / Context 요청
Back->>DB: core Context + PENDING 상태 저장
Back->>Queue: Context 처리 이벤트 발행
Back-->>Front: 저장 결과 반환
Queue->>AI: 처리 이벤트 전달
AI->>DB: 상태 사전 검사·작업 선점
AI->>Model: Embedding·Keyword 판정
Model-->>AI: 파생 결과
AI->>DB: 상태 잠금·CANCELLED 재검사
AI->>DB: 파생 데이터 저장, COMPLETED 전이
모델 호출은 DB 트랜잭션 밖에서 수행합니다. 결과 저장 직전에 상태를 다시 확인하므로 처리 중 삭제·교체된 Context의 늦은 결과가 검색에 섞이지 않습니다.
| 상황 | 처리 |
|---|---|
| 최초 Embedding·Keyword 처리 | PENDING → PROCESSING → COMPLETED |
| Embedding 완료 후 Keyword 실패 | Embedding 결과를 재사용하고 Keyword 단계부터 재개 |
| 일시적인 외부 API·DB 오류 | PROCESSING을 유지하고 만료 후 Scheduler가 회수 |
| 재시도 한도에 도달한 영구 오류 | 해당 단계를 FAILED로 전이 |
| 처리 중 Context 삭제·수정 | CANCELLED 전이 후 늦은 결과를 저장하지 않음 |
| 삭제된 Embedding | is_deleted = true로 검색 대상에서 즉시 제외 |
sequenceDiagram
actor User
participant Front
participant Back
participant AI
participant DB as PostgreSQL
User->>Front: 자연어 질의
Front->>Back: 개인 기록 검색
Back->>AI: 사용자 범위 + 질의
AI->>DB: exact cosine + 상태·profile 필터
AI->>AI: 재작성·Keyword·문자열 신호 결합
AI-->>Back: recordId 후보와 신뢰도
Back->>DB: Core 원문·소유권 확인
Back-->>Front: Record 검색 결과
AI는 Core 원문을 직접 조회하지 않습니다. Backend가 인증된 사용자의 소유권과 공개 범위를 다시 확인한 뒤 화면 응답을 만듭니다.
flowchart LR
Query[사용자 질의] --> Rewrite[선택적 질의 재작성]
Rewrite --> Vector[pgvector exact cosine]
Query --> Lexical[본문 문자열 검색]
Vector --> Merge[Record 단위 후보 결합]
Lexical --> Merge
Merge --> Keyword[Keyword 재정렬]
Keyword --> Judge[선택적 LLM 관련도 판정]
Judge --> Back[Backend 소유권·원문 검증]
벡터 검색은 user_id, is_deleted, 분석 상태, Embedding Profile을 먼저 제한합니다. 여러 Context가 일치해도 Record마다 최고 유사도 Context 하나만 후보로 남깁니다. 재작성·Keyword·문자열·LLM 신호는 각각 독립적으로 끌 수 있으며 실패하면 기본 검색으로 복귀합니다.
sequenceDiagram
actor User
participant Front
participant Back
participant AI
participant Vision
participant Kakao
User->>Front: 대화 캡처 이미지 선택
Front->>Back: multipart 이미지 업로드
Back->>AI: 내부 장소 제안 요청
AI->>Vision: 장소명·지역·맥락 단서 추출
Vision-->>AI: 구조화된 단서
AI->>Kakao: 장소 후보 검색
Kakao-->>AI: 장소 후보
AI-->>Back: 후보별 상태·경고·Context 제안
Back-->>Front: 사용자가 확인할 후보
User->>Front: 장소와 Context 확정
이미지는 후보 생성에만 사용하고 영구 저장하지 않습니다. Vision 결과를 바로 Record로 만들지 않고 Kakao 장소 후보와 사용자의 최종 확인을 거쳐 잘못된 장소 저장을 방지합니다. 외부 API 일부가 실패하면 후보별 경고를 함께 반환해 사용자가 직접 검색으로 이어갈 수 있습니다.
flowchart LR
PR[Pull Request] --> CI[Test / Lint / Build]
CI --> Image[Immutable Image]
Image --> GHCR[GHCR]
GHCR --> Update[Infra Image Candidate]
Update --> Argo[Argo CD]
Argo --> K3s[k3s Cluster]
K3s --> Observe[Prometheus / Grafana / Loki]
K3s --> Backup[PostgreSQL Backup]
운영 상세는 ../infra/docs/architecture.md와 각 Runbook을 기준으로 합니다.
- 선언 상태: 환경별 ApplicationSet·Helm values가 배포 구성을 소유하고 Argo CD가 live 상태를 맞춥니다.
- 불변 이미지: Backend·Frontend·AI 이미지는 commit SHA로 식별하며 같은 태그를 덮어쓰지 않습니다.
- Secret: 평문은 Git에 저장하지 않고 Sealed Secret의 암호문만 선언 상태에 포함합니다.
- 네트워크: Cloudflare Tunnel과 Traefik만 공개 진입점을 제공하며 AI·DB·Redis는 내부 통신으로 제한합니다.
- 관측: Prometheus가 애플리케이션·클러스터 메트릭을 수집하고 Grafana·Loki가 대시보드와 로그 탐색을 제공합니다.
- 복구: PostgreSQL 백업은 생성·검증·외부 보관 경계를 분리하고 복원 절차를 Runbook으로 관리합니다.