본문으로 건너뛰기

데이터 · 확장 후 — 저장소 다섯의 소유권

갱신일 2026-08-12 · 기준: 확장 개요 · AA · 현재 판 데이터 이 문서가 갖는 것: 누가 원본을 갖고, 무엇을 지워도 되고, 지운 뒤 무엇으로 되살리는가. 여기 없는 것: 테이블·칼럼·FK(erd.md) · 그래프 온톨로지(ontology.md) · 파이프라인 단계(AA §3) · 노트 삭제 화면(IA §9).

⚠︎ 이건 계획이지 현황이 아니다. 지금 서 있는 것은 현재 판 데이터 아키텍처가 갖는다.

1. 원본은 셋뿐이다

Postgres heymoa · S3 오디오(7일) · voice print. 나머지는 전부 파생이거나 휘발이다. 아래 모든 규칙이 이 한 줄에서 나온다.

저장소무엇이 들어 있나원본/파생주인재생성
Postgres heymoa유저·워크스페이스·프로젝트·노트 · 전사 세그먼트(+화자) · 결정·액션 아이템·근거 · 채팅·승인 · 에이전트 카드 · 연동 토큰 · 감사 이벤트원본server불가. 백업 복원뿐
Postgres heymoa_aianalysis_results(멱등성 캐시) · LangGraph checkpoint*파생ai재분석
벡터전사 청크 임베딩 1536 · 확정 Decision 임베딩(C3 씨앗 · 실시간 §4) · HNSW파생ai재색인
Neo4jMeeting·Person·Decision·ActionItem·ExternalItem과 관계파생server가 쓴다 · ai는 읽기 전용전량 재투영
S3 오디오회의 녹음 Int16 PCM · 멀티파트 잔여원본 · 7일server transcription불가. 지나간 소리는 못 만든다
브로커 · 큐STOMP 팬아웃 구독 · 파이프라인 잡 메시지휘발server해당 없음

voice print는 여섯 번째 줄이 아니라 첫 줄 안의 별도 구역이다. heymoa 와 같은 인스턴스, biometric 스키마, 다른 키, 다른 조회 경로 — §3.

브로커·큐는 저장소가 아닌데 표에 있다. 인스턴스 밖에 상태가 사는 순간부터 백업·장애·용량을 저장소처럼 봐야 하고, SA가 소유권을 이 문서로 넘겼다(SA §2). 재생성 칸이 「해당 없음」인 이유는 되살릴 것이 없어서다 — 팬아웃으로 흐른 전사는 이미 heymoa 에 들어갔고, 잃어버린 잡은 pipeline_steps 를 훑는 워치독이 다시 낸다.

벡터는 1만 구간까지 heymoa_ai 안의 pgvector 다. 10만에서 전용 스토어로 나간다(README §7의 18번). 그 이사가 가능한 이유가 파생이기 때문이다 — 옮기는 게 아니라 새 스토어에 다시 만들고 옛 것을 버린다.

재생성 경로와 소요

무엇입력외부 API소요
analysis_resultstranscript_segmentsLLM 1회/노트노트 단위. 전량은 안 한다
벡터transcript_segments임베딩 API노트 단위는 분. 전량 55,000건 원가는 미확인
Neo4jnotes·note_participants·decisions·action_items·evidence·decision_relations없음SQL 읽기 + Cypher 쓰기. 전량 소요 미확인 — §10 리허설이 잰다
voice print사용자가 다시 녹음없음자동 재생성 경로가 없다. 사람이 다시 해야 한다

Neo4j 재생성에 LLM이 없다는 것이 "파생"의 진짜 조건이다. 모델 호출이 끼면 결과가 결정적이지 않고, 결정적이지 않으면 재생성이 아니라 재추론이다. 그래서 LLM이 낸 후보는 Postgres에 먼저 쓰고(온톨로지 §6) 그래프는 투영으로만 만든다. 사람이 확인한 SUPERSEDES 판정과 그 부정 기록도 Postgres에 있어야 한다 — 그래프에만 두면 재투영에서 사라지고 확인 작업을 사용자가 다시 한다. 칼럼은 erd.md.

버린 대안

대안왜 버렸나
Neo4j를 결정·액션 아이템의 정본으로백업 대상이 둘이 되고, 어긋났을 때 판정할 방법이 없다. 그래프 DB를 쓰는 시스템은 대개 여기서 무너진다
전사 본문을 벡터 스토어에만임베딩 모델을 바꾸는 순간 전사가 사라진다
S3 오디오를 영구 보관보관 자체가 사고의 크기다(D15). 화자 분리 재실행 여유만 준다

2. 흐름 — 화살표마다 push 냐 pull 이냐

규칙 한 줄: 확정된 것은 push, 계속 변하는 것과 큰 바이너리는 pull.

화살표방식
오디오 청크 → server → Soniox → S3push스트림이다. uploadId 는 DB 에(CA §8)
server → speech잡만 push오디오를 페이로드에 싣지 않는다. 45분 11MB를 큐에 넣으면 재시도마다 다시 흐른다
speech → S3pull큰 바이너리는 받는 쪽이 당긴다. 재시도가 공짜가 된다
server → voice printpull · 내부 1회매칭 서비스만 읽는다(§3)
server → ai 분석push회의가 끝난 확정 전사. 한 번에 넘긴다
ai → server 채팅 컨텍스트pull진행 중 회의라 매 턴 최신이 필요하다
server → Neo4jpush · 비동기몇 분 늦어도 아무도 모른다(온톨로지 §6)
ai → Neo4jpull · 읽기 전용턴당 1회 상한(온톨로지 §7)

S1에서 10:45에 회의가 끝나면 위 화살표가 순서대로 한 번씩 돈다. 화자 분리가 실패해도 server → ai 는 돈다 — 화자 없는 요약이 요약 없는 것보다 낫다.

3. voice print — 원본이지만 옆에 두지 않는다

목소리는 생체정보다. 나머지 원본과 같은 스키마에 두면 조회·백업·로그·삭제가 전부 같이 딸려 다닌다. 그게 위험의 전부다.

같이 두면 벌어지는 일
조회노트 상세 API가 참석자를 조인하다가 임베딩까지 실어 나른다. 한 번 새면 되돌릴 수 없다
백업일반 스냅숏에 생체정보가 들어간다. 스냅숏에는 삭제 요청이 안 닿는다
로그슬로우 쿼리 로그에 임베딩 값이 찍힌다
삭제S7의 "즉시 삭제"가 CASCADE 사슬 어딘가에 걸려 소프트 삭제로 타협된다

나중에 분리할 수 없다. 위 넷은 전부 "이미 흘러간 곳"의 문제라서, 분리하는 시점에는 이미 늦었다.

규칙무엇으로 강제하나
별도 스키마 biometric일반 커넥션 풀의 role에 USAGE 를 주지 않는다. 조인이 문법적으로 불가능해진다. 스키마·칼럼은 ERD §3가 갖는다
별도 KMS 키키를 지우면 데이터가 죽는다 — 조직 단위 삭제의 최후 수단
단일 조회 경로매칭 서비스 하나만 읽는다. 일반 조회 API·관리자 화면·데이터 내보내기에 노출 경로 없음
organization 스코프조직을 넘어 대조하지 않는다. 넘는 순간 다른 제품이 된다
임베딩 바이트는 즉시 물리 삭제S7에서 embedding·key_id 를 NULL로 만든다. 남는 것은 동의·철회 이력 껍데기 행뿐 — 재등록 때 "전에 지웠다"를 알아야 하고 그 이력이 감사 대상이다(ERD §3)
원본 음성 미보관임베딩만 남긴다. 등록용 녹음은 추출 직후 버리고, speech가 낸 회의별 화자 임베딩도 매칭 직후 폐기 — 저장하면 그것도 생체정보다

pyannote를 자체 GPU로 돌리는 결정(D9)이 여기서 회수된다. 화자 분리를 관리형 API로 했으면 목소리가 매 회의 국외로 나가고, 위 규칙 전부가 성립하지 않는다 — §11.

S1에서 최유진은 voice print를 등록하지 않았다. 매칭은 시도조차 하지 않는다. 최유진은 화자 4 로 남고, 김민수가 화자 4 → 최유진 으로 교정한다. 그 교정은 transcript_segments 의 화자 칼럼을 채우고, voice print를 만들지 않는다. S2의 외부 게스트 이정훈(외부) 도 같다 — 계정 없는 이름표는 그 노트 안에서만 사는 문자열이다.

4. S6 — 노트를 지우면 다섯에서 무슨 일이

김민수가 노트 하나를 지운다. 다섯 저장소를 한 트랜잭션에 묶을 방법은 없다.

원본 삭제와 outbox 기록이 같은 트랜잭션이어야 한다. 이 한 줄이 설계 전부다 — 원본을 먼저 지우고 outbox를 나중에 쓰면 그 사이 크래시한 노트가 영원한 고아가 된다. 지금 판의 구멍이 정확히 그것이다(현재 판 ERD §11 ③).

대상값은 넷이다S3·NEO4J·VECTOR·AI_CACHE(ERD §9). heymoa_aiheymoa 와 다른 database라 notes CASCADE가 애초에 닿지 않는다. VECTOR 가 전사 청크 임베딩을, AI_CACHEanalysis_results 와 그 노트의 LangGraph 체크포인트를 진다. 둘을 한 대상값으로 묶지 않는 이유는 재시도 단위가 다르기 때문이다 — 임베딩 삭제는 인덱스를 건드리고 캐시 삭제는 안 건드린다. 한쪽이 실패했을 때 다른 쪽까지 다시 도는 것을 막는다.

버린 대안
2PC / 분산 트랜잭션S3와 Neo4j가 참여하지 못한다. 참여하는 둘만 묶어도 반쪽이다
파생을 먼저 지우고 원본을 나중에원본 삭제가 실패하면 사용자가 요약 없는 반쪽 노트를 본다. 더 나쁘다
삭제 API를 저장소마다 동기 호출셋 중 하나가 느리면 삭제 버튼이 30초 돈다. Neo4j가 죽어 있으면 삭제 자체가 막힌다
아무것도 안 지우고 "파생이라 괜찮다"지금 하고 있는 것. 검색과 브리핑에 지운 회의가 계속 나온다

실패하면 무엇이 남나

어디서 죽나남는 것사용자에게 보이나청소
트랜잭션 1아무것도 안 지워진다노트 그대로다시 누른다
S3오디오 (최대 7일)아니오lifecycle이 알아서 지운다 — 자동 청소가 있는 유일한 저장소
heymoa_ai임베딩 · 캐시 행 · checkpoint예 — 검색에 지운 회의가 뜬다outbox 재시도 → 주간 스윕
Neo4jDecision·ActionItem 노드예 — 브리핑·MCP가 지운 회의를 근거로 든다outbox 재시도 → 스윕 → 전량 재투영

제일 나쁜 둘이 벡터와 그래프다. 그래서 방어선을 하나 더 둔다 — 조회 결과는 언제나 noteId 를 달고 나오므로, server가 Postgres에서 살아 있는 노트만 통과시킨다. 고아가 남아 있어도 화면에는 안 나온다. 시나리오 S3에서 박준호가 heymoa.search_decisions 를 부를 때도 같은 필터를 지난다.

고아 청소는 주간 스윕이다. 벡터·Neo4j의 noteId 집합에서 notes.id 를 뺀 나머지를 지운다. 이 스윕이 0이 아니면 outbox가 새고 있다는 신호다 — 청소가 아니라 계측이 목적이다. 주기가 야간이 아니라 주간인 이유가 그것이다.

남는 것: voice print. 노트 소유가 아니라 사용자 소유다. 삭제 확인 화면이 이 구분을 말해야 한다(IA §9).

5. S7 — voice print를 지우면

최유진이 계정 설정에서 voice print를 지운다.

무엇어떻게 되나
biometric 스키마의 임베딩 바이트즉시 물리 삭제 (embedding·key_id NULL)§3
동의·철회 이력 껍데기 행남는다재등록 때 "전에 지웠다"를 알아야 한다. 감사 대상이다(§7)
매칭 옵트인 플래그false앞으로 대조하지 않는다
과거 노트의 화자 라벨남는다아래
Neo4j ATTENDED · ASSIGNED_TO남는다참석과 담당은 회의 시점의 사실이다
S3 오디오관계없다 (이미 7일에 사라진다)voice print 삭제는 녹음 삭제가 아니다
회의별 화자 임베딩애초에 없다§3

왜 과거 라벨을 안 지우나 — 셋.

  1. 라벨은 회의 기록의 일부다. 그 회의록은 최유진 혼자의 것이 아니라 참석자 4명의 기록이다.
  2. 상당수는 사람이 만든 것이다. S1의 화자 4 → 최유진 은 voice print가 아니라 김민수가 붙였다. 목소리를 지운다고 김민수가 한 판단이 취소되지 않는다.
  3. 지우기 시작하면 이력이 부서진다. ASSIGNED_TO 가 끊기고, 액션 아이템의 담당자가 사라지고, 브리핑이 "누가 맡았는지 모르는 일"을 쌓는다. 지운 것은 목소리인데 조직의 기록이 손상된다.

개별 라벨을 지우고 싶으면 그 노트에서 교정한다. 삭제 화면이 이 경로를 말해야 한다(IA §8).

계정 삭제는 다른 문제다 — 유저를 가리키는 FK에 CASCADE도 SET NULL도 없어서 지금은 삭제가 실패한다(현재 판 ERD §11 ⑤). §13으로 내린다.

6. 보존 기간

데이터어디산다정하는 것
오디오 원본S37일 (D15) · 미완료 멀티파트는 1일lifecycle. 조직이 늘릴 수 있다
전사 세그먼트·화자 · 결정·액션·근거 · 에이전트 카드heymoa노트와 같이삭제만이 끝. 카드는 §8
회의별 화자 임베딩없음매칭 직후 폐기§3
voice printbiometric사용자가 지울 때까지§5
임베딩벡터노트와 같이 (outbox)§4
analysis_resultsheymoa_ai90일 (추정)멱등성 캐시일 뿐이다. 오래된 것을 들고 있을 이유가 없다
LangGraph checkpoint*heymoa_ai마지막 턴 +30일 (추정)지우면 멀티턴 맥락만 사라진다. 표시용 히스토리는 server에 있다
Neo4j 노드Neo4j노트와 같이파생이라 독립 수명이 없다
감사 이벤트heymoa노트를 지워도 남는다§7

7. 감사 로그

삭제 기록이 삭제와 함께 사라지면 감사가 아니다. §12가 이 문장을 설계 전제로 들고 있으니 실물이 어디에 사는지를 여기서 정한다. organization 계층(D16)과 함께 들어온다.

Loki에 안 둔다. 관측 로그는 Grafana Cloud Free의 50GB/월 상한에 걸리면 조용히 잘린다(CA §10). 상한에 잘리는 것을 감사라고 부를 수 없다. 감사 로그는 Postgres heymoa 의 테이블이고, 그래서 §1 표의 첫 줄 안에 있다. 테이블 정의는 ERD가 갖는다.

사건언제주체
VOICE_PRINT_CONSENTED목소리 등록 동의user
VOICE_PRINT_DELETEDS7 · 임베딩 바이트 물리 삭제(§5)user
SPEAKER_CONFIRMEDS1의 화자 4 → 최유진 교정user
NOTE_DELETEDS6 · outbox INSERT와 같은 트랜잭션(§4)user
TOKEN_ISSUEDS3의 90일 PAT 발급user
TOKEN_USEDMCP 호출. 집계 행이다token
POLICY_CHANGED조직이 기능을 끄고 켠다user
OPS_ACTION재처리·재투영 같은 운영 개입user

주체는 (user_id, token_id) 쌍이다. PAT이 두 번째 인증 주체가 되면서 "누가"가 사람 하나로 안 끝난다(SA §1). 쿠키 경로는 token_id 가 비고, S3의 MCP 호출은 둘 다 찬다.

규칙
append-onlyUPDATE·DELETE를 role로 막는다. 앱 코드가 지키는 게 아니라 권한이 지킨다
notes FK를 안 건다deletion_outbox 와 같은 판단(§4) — 지운 노트의 삭제 기록이 그 삭제에 딸려 가면 안 된다
TOKEN_USED 만 집계 행기계 속도에 행이 폭발한다. 원시 호출 로그는 Loki로 가고, 결제·감사 근거는 버킷 집계다
화면은 조직 하나/o/{orgId}/audit(IA §3). 워크스페이스 화면에 안 붙인다 — 감사를 보는 사람과 회의를 보는 사람이 다르다

보존 기간은 정하지 않았다 — §13.

8. AI 산출과 사람 발화는 다른 테이블에 둔다

S1의 10:23:14에 C3 카드가 뜬다. 카드도 시각을 갖고 타임라인에 섞여 보이니 transcript_segmentskind 칼럼 하나 붙이면 정렬·페이징이 공짜다. 그렇게 하면 안 된다. 소유권 규칙은 하나뿐이다 — transcript_segments 에는 사람 목소리에서 나온 것만 들어간다. 카드는 agent_cards 별도 테이블, 카드에서 나온 항목은 origin = AI, 요약 payload 에도 카드는 세그먼트와 섞지 않고 별도 필드로 AI 출력 표시를 달아 넘긴다(실시간 §6). 칼럼과 "왜 한 테이블이 아닌가"의 논거 셋은 ERD §5가 갖는다.

여기 남기는 것은 그림 하나다. 분리를 안 했을 때 데이터가 어떻게 도는가.

두 홉이면 추측이 사실이 된다. 아무도 안 본 카드가 요약의 입력이 되고, 요약이 만든 결정이 그래프에 들어가고, 다음 회의의 충돌 감지가 그것을 근거로 든다. 그리고 근거를 눌러 들어가면 AI가 한 말이 나온다evidence → transcript_segments 사슬이 사람 발화로 착지하지 않으면 온톨로지 §4의 "근거 없는 노드는 만들지 않는다"가 무력화된다. 루프라서 한 번 섞이면 다음 회의가 오염을 키운다.

버린 대안 — 같은 테이블 + source 칼럼으로 필터. 필터를 빠뜨린 쿼리 하나가 오염을 만들고, 그 오염은 그래프까지 가서야 보인다. 읽는 쪽이 실수할 수 있는 구조를 두지 않는다.

9. cross-database 금지가 다섯으로 늘면

쌍이 열이다. 쌍마다 규칙을 만들면 무너진다. 규칙 수를 늘리지 않고 접는다.

규칙
어느 저장소도 남의 저장소를 조인하지 않는다Postgres는 database를 넘는 FK를 못 만들고, Neo4j·S3는 애초에 조인 대상이 아니다
저장소를 넘는 참조는 전부 맨 문자열 ID13자 TSID. DB가 무결성을 안 지킨다 — 지키는 것은 outbox(§4)와 스윕이다
조인은 애플리케이션에서 한다벡터가 noteId 10건을 주면 server가 Postgres에서 그 10건을 읽는다. 반대 방향은 안 된다 — 벡터는 권한 조건을 모른다
쓰기는 주인만§1의 주인 열. ai는 Neo4j 읽기 전용 계정, server는 벡터에 쓰지 않는다
mcp는 저장소에 직접 붙지 않는다server API만 본다. public edge가 데이터에 직접 닿으면 상한·감사·권한이 두 벌이 된다

진짜 문제는 조인이 아니라 스코프다. 워크스페이스 권한은 Postgres 에만 있다. 벡터와 Neo4j는 자기 안에 workspaceId복제해서 들고 순회를 자른다. 복제한 스코프가 원본과 어긋나면 그건 성능 문제가 아니라 권한 사고다.

상황어떻게
노트가 다른 프로젝트로 이동워크스페이스는 안 바뀐다. 해당 노트만 재투영
노트가 다른 워크스페이스로 이동기능을 만들지 않는다. 만드는 순간 파생 전부의 스코프를 다시 써야 하고, 그 사이 창에서 잘못된 조직이 조회한다
워크스페이스 삭제노트 삭제와 같은 outbox 경로를 노트 수만큼

10. 재생성 리허설

안 돌려본 복구 절차는 없는 절차다. 그리고 리허설의 목적은 복구가 아니라 수치를 얻는 것이다 — README §10의 미확인 7번(Neo4j 재생성 소요)을 채우는 게 이 절이다.

리허설주기무엇을 재나합격
Neo4j 전량 재투영분기 1회 · staging소요 시간 · 노드/관계 수가 Postgres 집계와 일치하는가 · 확인된 SUPERSEDES 가 살아 돌아오는가수치 일치
벡터 전량 재색인반기 1회 · 표본 1%소요 · 임베딩 API 원가 · HNSW 빌드 시간원가 추정치 갱신
초기 백필 예행1회 · staging기능이 켜지는 날 한 번만 도는 것 — 워크스페이스 단위로 오래된 것부터 투영할 때 전량 소요 · 도입 전 노트(오디오가 없어 화자 분리가 영영 불가)가 무엇을 만드는가소요가 예상 창 안 · 반쯤 투영된 워크스페이스가 안 생긴다
outbox 스윕주 1회 · prod고아 수0

벡터 전량은 임베딩 모델을 바꿀 때만 실제로 돈다. 55,000건 재색인은 API 원가가 들어서 리허설로 쓸 수 없다 — 표본으로 단가를 재고 곱한다. 그리고 도는 동안 검색이 살아 있어야 한다. 새 인덱스를 옆에 만들고 스위치한다. 현재 판의 노트 단위 재적재(note_id DELETE 후 INSERT + advisory lock)는 한 건짜리라 괜찮지만 전량에는 못 쓴다.

초기 백필 예행은 딱 한 번 쓰고 버리는 리허설이다. 그래도 하는 이유는 그날이 전량 투영을 처음이자 마지막으로 prod에서 도는 날이고, 실패하면 되돌릴 대상이 사용자 화면이기 때문이다.

11. 국외 이전 — 무엇이 나가나

어디로나가는 것안 나가는 것
Soniox오디오 그 자체 (server 릴레이). 전사 원문을 돌려받는다사용자 신원 · 노트 제목 · 워크스페이스
OpenAI · 요약전사 원문 전량 + 화자 라벨(실명)오디오 · voice print
OpenAI · 임베딩전사 청크 원문
OpenAI · 실시간 게이트30~60초 창 + 기존 결정 문구(실시간 §5)
pyannote아무것도 안 나간다 — 자체 GPU · 서울
Linear · GitHub사용자가 승인한 항목의 제목·본문

세 줄로 접으면: 오디오는 Soniox로, 텍스트는 OpenAI로, 목소리의 지문은 아무 데도 안 간다.

마지막 줄이 §3의 대가다. GPU를 직접 굴리는 비용(CA §6)이 인프라 최대 항목인데, 관리형 화자 분리 API로 바꾸면 매 회의 모든 참석자의 음성이 국외로 나가고 voice print 규칙 전체가 무의미해진다. 값을 치르고 사는 것이 그것이다. 다만 요약에는 실명이 나간다김민수화자 A 로 바꿔 보내고 결과에서 되돌릴 수 있지만 누가 누구에게 무엇을 부탁했는지가 흐려진다. 재본 적이 없다(§13).

12. 설계 전제

  • 원본은 셋이다. 넷째를 만들자는 제안은 백업·복구 책임을 하나 더 만들자는 제안이다.
  • 재생성 명령이 있을 때만 파생이다. 없으면 "파생"은 규칙이 아니라 주장이다. 그 명령에 LLM이 필요하면 그것도 파생이 아니다 — 결정적이지 않은 복구는 복구가 아니다.
  • 저장소를 넘는 삭제는 outbox로 한다. 2PC를 쓰지 않고, 최종 일관성을 인정하고, 그 사이를 조회 필터로 가린다.
  • 고아는 생긴다고 전제한다. 안 생기게 하는 대신 보여주지 않고 주기적으로 센다 — 스윕은 청소가 아니라 계측이다.
  • 생체정보는 별도 스키마·별도 키·단일 조회 경로. 나중에 분리할 수 없다.
  • AI가 만든 것과 사람이 말한 것은 다른 테이블에 둔다. 필터로 가르지 않는다.
  • 저장소가 늘어도 규칙 수는 늘지 않는다. 쌍마다 예외를 만들면 열 쌍에서 무너진다.
  • 삭제 기록은 삭제되지 않는다. 감사 로그만 사슬 밖이다(§7).
  • 휘발하는 것은 원본이 아니다. 브로커·큐가 비어도 되살릴 것이 없어야 한다.

13. 미확인

무엇지금 아는 것확인해야 할 것
Neo4j 전량 재투영 소요없다§10 리허설. 이 수치가 "파생" 규칙의 실현 가능성을 정한다
벡터 전량 재색인 원가없다표본 1% 로 단가를 재고 55,000건에 곱한다
Soniox·OpenAI의 리전·재하도급·보존 기간계약 전이다DPA. §11 표의 "어디로"가 실제로 어디인지 · 실명 익명화가 요약 품질을 얼마나 깎는가
감사 로그 보존 기간사건 8종과 저장 위치는 정했다(§7)organization 계층(D16)과 함께. 법정 기간을 모른다
analysis_results·checkpoint 만료 기간90일·30일은 추정실제 재분석 요청이 며칠 뒤에 오는지
계정 삭제 흐름없다. FK가 막아서 지금은 실패한다voice print 삭제(§5)와 다른 문제다. 어디까지 지우고 무엇을 익명화하나
조직 단위 데이터 내보내기없다. 화면도 없다포맷 · 다섯 저장소 중 무엇까지 포함하나 · 감사 이벤트를 넣나