호스트가 모임 녹취록을 로컬에서 정리한 뒤, ReadMates 호스트 세션 편집기에서 한 번에 가져올 수 있는 JSON 형식입니다. 같은 편집기의 직접 작성·in-app 근거 기반 AI 생성·외부 JSON이라는 동등한 초안 입력 경계도 함께 설명합니다. 호스트 화면에서 이 JSON을 올리는 주 버튼 이름은 정리본 올리기입니다.
이 흐름은 production 앱에서 LLM을 호출하지 않습니다. 모델 선택, API key, 원본 녹취록, 중간 산출물은 로컬 작업 공간에만 두고, 앱에는 최종 검토한 JSON만 업로드합니다.
- 호스트 세션 편집기에서 현재 회차 정보를 확인합니다.
- 회차 번호
- 책 제목
- 모임 날짜
- 앱에 표시되는 참석자 이름
- 기록 공개 범위
- 녹취록을 로컬 파일로 준비합니다. 원본 녹취록과 중간 산출물은 Git 밖에 둡니다.
- 아래 생성 프롬프트 템플릿에 회차 정보와 참석자 목록을 채워 LLM에 전달합니다.
- 모델 출력은 설명 없이 JSON 하나만 받아
.json파일로 저장합니다. - 로컬 검수 체크와 호스트 편집기의 preview를 통과한 뒤 공유 초안으로 가져오고, 내용을 검토한 다음 별도의 반영 절차를 진행합니다.
반복 작업을 줄이려면 매 회차마다 새 규칙을 만들지 말고, 이 문서의 템플릿에서 {...} placeholder만 바꿉니다. 문체 수정이 필요하면 JSON 전체를 다시 만들기보다 publication.summary, highlights, oneLineReviews, feedbackDocument.markdown의 문장만 부분 재생성합니다.
호스트 세션 편집기의 기록 작업대에는 초안 만들기 아래에 직접 작성, AI로 생성, 외부 JSON이라는 동등한 세 입력이 있습니다. 어느 입력으로 시작해도 같은 작업 중 초안으로 수렴하며, AI와 JSON은 직접 작성 화면으로 돌아와 이어서 검토하고 고칠 수 있습니다. 외부 JSON은 AI의 fallback이 아니라 같은 초안으로 들어오는 별도 입력입니다. 단독 .md 또는 .txt 피드백 문서 업로드는 더 이상 제공하지 않습니다.
| 모드 | 입력 | LLM 호출 위치 | 운영 게이트 | 공유 초안으로의 결과 |
|---|---|---|---|---|
| 직접 작성 | 호스트가 작업대에서 직접 작성·수정한 내용 | 호출 없음 | 해당 없음 | 자동 저장되는 공통 작업 중 초안 |
| 외부 JSON 업로드 | 호스트가 로컬에서 정리한 readmates-session-import:v1 JSON |
앱 외부 | 항상 사용 가능 | preview 뒤 공통 작업 중 초안으로 가져오기 |
| In-app AI 생성 | UTF-8/BOM TXT(≤ 1 MiB, ≤ 3시간) + 서버가 제공한 모델 ID | 서버 측 Spring AI adapter (Claude/OpenAI/Gemini) | kill switch + provider allowlist + provider key + provider retention 확인 | 검토 완료 commit 뒤 공통 작업 중 초안으로 가져오기 |
AI와 JSON commit은 같은 validation과 SaveValidatedSessionRecordDraftUseCase.saveValidated(...) 경계를 사용해 검토 완료 snapshot을 공통 session_record_drafts에 저장합니다. 직접 작성도 이 초안을 계속 편집합니다. 초안을 만드는 일은 live 기록을 바꾸지 않으며, 별도 반영 검토와 확인이 draft revision/hash 및 live revision을 검증한 뒤 immutable revision과 live 콘텐츠를 갱신합니다. 현재 동작은 architecture.md의 In-app AI 세션 생성 컴포넌트, 운영 rollout과 장애 대응은 AI session generation runbook을 기준으로 합니다. docs/superpowers/**의 spec과 plan은 설계 이력이며 현재 동작의 source of truth가 아닙니다.
In-app AI가 활성화된 환경은 legacy 분기 없이 grounded whole-transcript 경로로 다음 순서에 따라 세션 기록을 완성합니다. 호출·비용·복구·trace 세부 계약은 Spring AI 2 provider architecture를 기준으로 합니다.
- TXT를 UTF-8 또는 UTF-8 BOM으로 준비합니다. 각 발언은
화자명 MM:SSheader와 본문을 사용하고 timestamp는 뒤로 가지 않아야 합니다. - 모든 고유 화자명을 현재 클럽의
ACTIVE멤버 표시 이름과 정확히 맞춥니다. 비교는 Unicode NFC + trim 후 case-sensitive exact match이며 alias, fuzzy match, generic label 자동 보정은 없습니다. - 호스트 편집기에서
AI로 생성을 열고 서버가 반환한 모델 목록에서 선택해 TXT를 업로드합니다. 최대 크기는 1 MiB, 최대 길이는 3시간입니다. - 생성이 끝나면 요약, 하이라이트, 한줄평, 피드백 문서의 각 항목에서 근거를 확인합니다. 기본 excerpt는 서버가 원본 turn에서 만든 최대 240 Unicode code point이며, 현재 revision이 참조한 turn 하나만 확장할 수 있습니다.
- 네 섹션을 모두
AI 근거 검토 완료로 표시합니다. 직접 문장을 고친 섹션은 기존 근거/review가 무효화되므로직접 수정 내용 확인으로 다시 확인합니다. - 재생성하면 revision과 네 섹션 review가 초기화됩니다. 최신 revision을 다시 검토한 뒤
초안으로 저장을 누릅니다.
비회원, 비활성/다른 클럽 회원, generic label, 정규화 후 중복 이름은 job을 만들기 전에 422로 거절됩니다. 이 preflight 실패에는 Redis/Kafka/provider/cost side effect가 없습니다. Model capability를 확인할 수 없으면 503, 실제 request budget이 모델 한도를 넘으면 422로 provider 호출 전에 fail closed하며, 임의 chunking은 하지 않습니다.
브라우저 draft는 revision을 포함한 복구용 편집값만 최대 6시간 보관합니다. Transcript, parsed turns, evidence/excerpt는 localStorage에 저장하지 않습니다. 서버의 transcript/turns/result/evidence payload도 Redis에 최대 6시간만 있고 AI commit/cancel에서 즉시 정리를 시도합니다. Commit cleanup 실패는 cleanupPending으로 재시도하며 TTL이 최종 backstop입니다. Commit한 검토 완료 snapshot은 공통 MySQL staged draft에 저장되지만 transcript, parsed turns, evidence/excerpt, provider response는 함께 저장되지 않습니다. 만료된 job은 운영 채널로 원문을 전달하지 말고 호스트가 원본 TXT를 다시 업로드합니다.
파일은 UTF-8 JSON 하나입니다.
{
"format": "readmates-session-import:v1",
"session": {
"number": 7,
"bookTitle": "Example Book",
"meetingDate": "2026-05-14"
},
"publication": {
"summary": "Public-safe session summary."
},
"highlights": [
{ "authorName": "Host", "text": "Public-safe highlight." }
],
"oneLineReviews": [
{ "authorName": "Host", "text": "Concise one-line review." }
],
"feedbackDocument": {
"fileName": "session-7-feedback.md",
"markdown": "<!-- readmates-feedback:v1 -->\n\n# 독서모임 7차 피드백\n\n..."
}
}recordVisibility는 파일에 넣지 않습니다. 호스트 편집기의 현재 공개 범위 선택값이 preview/commit 요청에 붙습니다. HOST_ONLY 범위는 저장할 수 없으므로, 가져온 기록을 저장하려면 편집기에서 MEMBER 또는 PUBLIC을 먼저 선택합니다.
아래 프롬프트를 그대로 복사하고 {...}만 바꿉니다. 실제 참석자 이름, 원본 파일명, 운영 URL, 로컬 경로는 문서나 commit에 남기지 않습니다.
첨부한 독서모임 녹취록을 ReadMates session import JSON으로 변환해줘.
반드시 JSON 하나만 출력해.
설명, 마크다운 코드블록, 주석, 후속 안내 문장은 출력하지 마.
고정값:
- format: "readmates-session-import:v1"
- session.number: {회차번호}
- session.bookTitle: "{앱에 표시된 책 제목}"
- session.meetingDate: "{YYYY-MM-DD}"
- feedbackDocument.fileName: "session-{회차번호}-feedback.md"
- feedbackDocument.markdown 제목: "# 독서모임 {회차번호}차 피드백"
참석자:
- authorName은 아래 앱 표시 이름 중에서만 사용한다.
- 참석자 목록: {앱에 표시된 참석자 이름 목록}
- 참석하지 않은 사람, 비활성 참석자, 별칭이 다른 이름은 쓰지 않는다.
출력 범위:
- publication.summary: 2~4문장. 모임의 핵심 흐름만 자연스럽게 요약한다.
- highlights: 3~6개. 실제 발언에 근거한 장면만 고른다.
- oneLineReviews: 1개 이상. 같은 authorName을 중복하지 않는다.
- feedbackDocument.markdown: 아래 피드백 문서 구조를 정확히 지킨다.
문체:
- AI가 정리한 티가 나는 추상어를 줄인다.
- "결론은", "참석자들은", "방식으로 이어졌다" 같은 보고서 문장을 과하게 반복하지 않는다.
- 실제 대화에서 나온 말투와 장면을 우선한다.
- 없는 한줄평을 새로 꾸미지 말고, 녹취록에 있는 짧은 감상이나 정리 발언을 한줄평으로 다듬는다.
- 근거 없는 심리 추정, 성격 평가, 과장된 칭찬을 쓰지 않는다.
금지:
- 녹취록에 없는 사실, 배경, 평가를 만들지 않는다.
- 이메일, 연락처, 로컬 경로, 운영 정보, 민감한 개인 사정은 넣지 않는다.
- JSON 밖에 어떤 텍스트도 출력하지 않는다.
JSON 스키마:
{
"format": "readmates-session-import:v1",
"session": {
"number": {회차번호},
"bookTitle": "{앱에 표시된 책 제목}",
"meetingDate": "{YYYY-MM-DD}"
},
"publication": {
"summary": "..."
},
"highlights": [
{ "authorName": "...", "text": "..." }
],
"oneLineReviews": [
{ "authorName": "...", "text": "..." }
],
"feedbackDocument": {
"fileName": "session-{회차번호}-feedback.md",
"markdown": "<!-- readmates-feedback:v1 -->\n\n# 독서모임 {회차번호}차 피드백\n\n..."
}
}
- 녹취록 텍스트
- 회차 번호
- 책 제목, 저자
- 모임 날짜
- 앱에 표시되는 참석자 이름
- 실명 모드 또는 alias 모드
format은 반드시readmates-session-import:v1입니다.session.number,session.bookTitle,session.meetingDate는 현재 편집 중인 세션과 일치해야 합니다.publication.summary와highlights는 공개 가능 문장만 사용합니다.authorName은 참석자 표시 이름과 정확히 일치해야 합니다.- 로컬 demo/seed 데이터는 실제 참석자 실명 대신 alias 표시 이름을 사용할 수 있습니다. import 전에 호스트 편집기 참석자 목록에 보이는 이름을 그대로 넣습니다.
highlights는 1개 이상 6개 이하입니다.oneLineReviews는 1개 이상이고, 같은 작성자를 중복하지 않습니다.feedbackDocument.fileName은/또는\를 포함하지 않는.md또는.txt파일명입니다.feedbackDocument.markdown은 기존readmates-feedback:v1피드백 문서 템플릿을 통과해야 합니다.- 서버 preview는 같은 검증을 다시 수행하고, 저장 가능한 경우에만 commit을 허용합니다.
feedbackDocument.markdown은 문자열 안에 들어가는 Markdown입니다. 서버 parser는 heading 이름과 순서를 기준으로 읽기 때문에 아래 구조를 유지해야 합니다.
<!-- readmates-feedback:v1 -->
# 독서모임 {회차번호}차 피드백
{책제목} · {YYYY.MM.DD}
## 메타
- 일시: {YYYY.MM.DD} ({요일}) · {HH:mm}
- 소요시간: {녹취록 기준 소요시간}
- 책: {책제목} · {저자}
- 참여자: {참석자 목록}
## 관찰자 노트
{모임 전체 흐름 1~3문단}
## 참여자별 피드백
### 01. {참석자명}
역할: {대화에서 맡은 자연스러운 역할}
#### 참여 스타일
{참여 방식 1~2문단}
#### 실질 기여
- {실제 대화에 남긴 기여}
#### 문제점과 자기모순
##### 1. {부드러운 개선 지점 제목}
- 핵심: {무엇이 아쉬웠는지}
- 근거: {녹취록에서 확인되는 근거}
- 해석: {다음 대화에서 어떻게 다루면 좋을지}
#### 실천 과제
1. {다음 모임에서 바로 해볼 행동}
#### 드러난 한 문장
> {녹취록에 실제로 가깝게 남은 한 문장}
맥락: {그 말이 나온 대화 맥락}
주석: {이 문장이 보여주는 의미}필수 heading은 ## 메타, ## 관찰자 노트, ## 참여자별 피드백, #### 참여 스타일, #### 실질 기여, #### 문제점과 자기모순, #### 실천 과제, #### 드러난 한 문장입니다. ### 01. 이름처럼 참여자 번호와 이름도 유지합니다.
summary는 앱에 공개될 수 있는 짧은 회차 소개입니다. 분석 보고서처럼 쓰지 말고, 실제 모임을 떠올릴 수 있는 말로 씁니다.highlights는 "누가 어떤 관점을 냈는지"가 보여야 합니다. 모든 문장을 같은 형식으로 시작하지 않습니다.oneLineReviews는 참석자가 남긴 짧은 감상에 가깝게 씁니다. 별도 한줄평이 없었다면 녹취록의 마무리 감상, 책에 대한 반응, 다시 읽고 싶은 지점 등을 짧게 다듬습니다.- 참여자별 피드백은 평가서가 아니라 다음 대화를 돕는 메모입니다. "탁월한", "깊이 있는", "통찰을 제공했다"처럼 근거 없이 좋은 말만 쌓지 않습니다.
- 문제점 제목은 공격적으로 쓰지 않습니다. 예를 들어
전달 난도가 높았다보다바로 따라가기 어려운 지점도 생겼다처럼 독자가 받아들이기 쉬운 표현을 씁니다. - 추상어를 쓸 때는 한 단계 구체화합니다.
라벨이 어색하면해석의 틀,이름 붙이기,선입견,기대중 문맥에 맞는 말을 고릅니다. - 문장 끝이 모두
~했다,~이었다로 반복되면 일부를~로 이어졌다,~에 가까웠다,~라는 말이 남았다처럼 자연스럽게 바꿉니다.
업로드 전에 다음을 확인합니다.
- 녹취록에 없는 사실, 평가, 배경 정보를 만들지 않았습니다.
- 공개 요약과 하이라이트에 이메일, 연락처, 로컬 경로, 운영 정보, 민감한 개인 사정이 없습니다.
- 실명 모드가 아닌 demo/public fixture에는 alias만 사용했습니다.
- JSON 파일에는 API key, 모델 provider token, 원본 녹취록 경로가 없습니다.
- 피드백 문서 제목은
# 독서모임 N차 피드백형식입니다.
파일을 저장한 뒤 최소한 아래를 확인합니다.
jq -e '.format == "readmates-session-import:v1"' session-import.json
jq -e '.session.number and .session.bookTitle and .session.meetingDate' session-import.json
jq -e '(.highlights | length >= 1 and length <= 6) and (.oneLineReviews | length >= 1)' session-import.json
jq -e '.feedbackDocument.markdown | contains("<!-- readmates-feedback:v1 -->") and contains("## 참여자별 피드백")' session-import.json이 검수는 형식 확인일 뿐입니다. 최종 판단은 호스트 편집기 preview의 issue 목록과 사람이 읽었을 때의 문체 검토로 합니다.
- 호스트 세션 편집기에서
기록 작업대를 열고, 현재 적용본과 작업 중인 초안을 구분해 확인합니다. 초안 만들기에서외부 JSON을 선택하고 파일을 고릅니다.- preview에서 회차, 책, 날짜, 작성자 매칭, 피드백 문서 상태를 확인합니다.
- 저장 가능 상태일 때
초안으로 가져오기를 누릅니다. - 공통 초안에 가져온 내용을 직접 작성 화면에서 필요한 만큼 고친 뒤,
반영 검토에서 다음 버전·공개 범위·알림을 분리해 확인합니다.
가져오기는 해당 회차의 공유 초안을 바꾸지만 현재 적용본은 바꾸지 않습니다. 서버는 가져오기 직전에 같은 검증을 다시 실행하고, 실패하면 아무 레코드도 일부 저장하지 않습니다. 현재 적용본의 요약, 하이라이트, 한줄평, 피드백 문서는 별도의 반영 확인이 성공할 때만 교체됩니다.
호스트 편집기는 내부적으로 두 API를 사용합니다.
POST /api/host/sessions/{sessionId}/session-import/previewPOST /api/host/sessions/{sessionId}/session-import/commit
두 API 모두 현재 club의 active host 권한이 필요합니다.
Sanitized 예시는 fixtures/session-import-example.json을 참고합니다. 이 파일은 실제 멤버 데이터가 아니라 public-safe alias와 예시 문장만 포함합니다.