Commit Graph

5 Commits

Author SHA1 Message Date
Claude f9fba46889
관계 메모 실제 반영(2.7-E) 구현: draftRequest에 RelationshipNote 전달 + 프롬프트 주입
Contact.RelationshipNote는 CRUD는 이미 있었지만 draftRequest에 필드 자체가 없어
ai-service 프롬프트에 전혀 전달되지 않는 저장 전용 스텁이었다. 이번 변경으로 실제
초안 생성에 반영되게 만든다.

- core-backend/aiservice.go: draftRequest에 RelationshipNote string 필드 추가
  (relationship_tier 옆, omitempty, 빈 문자열 = 무영향)
- core-backend/persona.go: resolveRelationshipNote() 추가. 티어/자율성과 달리
  메모는 순전히 개인별이라 전역 기본 메모 개념이 없음 -- 그룹 대화나 매칭되는
  Contact가 없으면 빈 문자열로 귀결. resolveRelationshipTier/resolveAutonomyLevel/
  resolveRelationshipNote 셋이 복붙하던 "1:1 상대 Contact 찾기" 루프를
  findCounterpartContact() 공용 헬퍼로 추출해 중복 제거
- core-backend/main.go: POST /conversations/:id/draft 핸들러가 resolveRelationshipNote
  결과를 draftRequest에 실어 보내도록 연결
- ai-service/app/generation.py: system_prompt_for_tier()가 relationship_note를
  받아 "[관계 메모] {note} -- ..." 문단을 관계 티어 지침과 별도로 추가(빈 값이면
  기존과 동일). draft_reply()도 파라미터 통과만 함 -- 에스컬레이션/정체성 게이팅은
  전혀 영향 없음
- ai-service/app/main.py: DraftRequest에 relationship_note 필드 추가, /draft가
  draft_reply로 그대로 전달
- 테스트: core-backend Go 64개(신규 3개: 메모 전달/빈 값/그룹 스킵) 전부 통과,
  ai-service pytest 52개(신규 5개) 전부 통과, mobile flutter analyze/test 변경 없이
  그대로 6개 통과(이 기능은 새 UI가 필요 없음 -- 필드는 이미 있었음)
- docs/roadmap.md §2.7-E, docs/deploy-checklist.md N4-C5a/b/c 완료 처리 + NOW/
  바로 다음 5개 요약 갱신

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YSB5PqF38raTxP5ABgr9m
2026-08-03 05:37:33 +00:00
Claude 5733ec4399
관계별 페르소나(2.7-B) 구현: 관계 티어 필드 + 온보딩/연락처 UI + 톤 프롬프트 분기
PRD.md §2.1-②·§3.1 P0 갭 우선순위 #2. close/formal 2종 관계 티어를 추가하고,
초안 생성 시 상대별 톤을 다르게 낸다.

- core-backend: TwinSettings.RelationshipTier(전역 기본값, 안전 우선 formal
  기본), Contact.RelationshipTier(1:1 연락처별 오버라이드, nullable).
  persona.go의 resolveRelationshipTier()가 연락처 오버라이드 → 전역 기본값 →
  formal 순으로 해석하고, 그룹 대화는 상대가 여럿이라 항상 전역 기본값만 사용.
  POST /conversations/:id/draft는 기존에 인증을 요구하지 않던 동작을 깨지
  않도록 currentUser(..., false)로 선택적 인증 처리 후 티어를 주입.
- 안전 관련 부수 수정: 그룹 대화에서는 전역 자율성 레벨(L1/L2)과 무관하게
  와카뷰 자동 발송을 무조건 차단(단톡 따라잡기는 L0 고정이 맞음).
- ai-service: RELATIONSHIP_TIER_INSTRUCTIONS + system_prompt_for_tier()로
  Gemini system_instruction에 관계 톤 지침을 주입. 에스컬레이션/정체성 게이팅
  로직은 티어와 무관하게 그대로 유지.
- mobile: 온보딩(말투 샘플 다음 단계)과 자율성 설정 화면에 전역 기본값
  SegmentedButton, 연락처 추가/수정 다이얼로그에 _RelationshipTierPicker로
  상대별 오버라이드 추가.
- 테스트: core-backend persona_test.go 6개(해석 순서·그룹 예외·비인증
  기본값 포함), ai-service 6개(system_prompt_for_tier + draft_reply 경로)
  전부 추가, 기존 스위트 모두 통과(go test, pytest 47/47, flutter analyze/test).
  실제 Flutter 빌드 + Playwright로 온보딩→연락처 오버라이드→목록 표시까지
  전체 라운드트립 시각 검증 완료.
- docs: roadmap.md §2.7-B, deploy-checklist.md N4-C2a~d 완료 처리. 다음
  우선순위는 Track C3(스팸/도배 감지 최소 버전).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YSB5PqF38raTxP5ABgr9m
2026-08-03 04:59:34 +00:00
Claude 64323b824e
feat: implement 단톡 따라잡기 (group catch-up summary) — roadmap.md §2.7-A
Closes the biggest content gap found against PRD.md §3.1 P0: group chat
catch-up was one of only two v1 MVP scenarios and had zero implementation.

Backend (core-backend):
- ConversationParticipant.LastReadMessageID read marker.
- POST /conversations/:id/read advances the caller's marker (never backward).
- GET /conversations/:id/summary builds context from messages since that
  marker and calls ai-service's new POST /summarize; returns unread_count
  and needs_reply.
- GET /conversations now reports unread_count per room.
- Safety: group conversations now unconditionally block twin-authored
  sends (POST /conversations/:id/messages), regardless of the sender's
  global autonomy level. PRD.md §2.3-③ requires this scenario stay L0-fixed
  with no auto-send; autonomy level is a per-user global setting today, so
  this closes the only path a global L2 whitelist match could otherwise
  auto-send into a group.

AI service (ai-service): new summarize.py module (same Gemini-call shape as
generation.py's draft_reply, no escalation/identity gating since nothing
generated here is ever sent) + POST /summarize.

Mobile: "새 대화" dialog now supports adding/removing multiple peer fields
(2+ peers -> is_group:true automatically); unread badge on conversation
rows; ChatScreen takes isGroup and renders its L1 panel as L0-locked for
groups; new "안 본 동안 요약" AppBar action opens a dialog with the summary
and, when a reply looks needed, a button that feeds straight into the
existing draft-request flow.

Verified with a real Flutter build against a live core-backend + ai-service
instance (Playwright driving 3 demo accounts through group creation, unread
badges, and the summary dialog) — this caught a real ordering bug: marking
the read marker on chat *open* meant the summary was always empty by the
time you could tap it, since opening the room already advanced the marker
past everything you'd come to catch up on. Fixed by marking read on screen
*exit* (dispose) instead, so the marker reflects what was unread that whole
visit and updates once you leave.

go test / pytest / flutter analyze+test all pass.
2026-08-03 03:16:54 +00:00
Claude 9041dc9b64
에스컬레이션 하드게이트 우회 구멍 차단 + 서버 측 삭제 플로우 추가
발견한 문제: POST /conversations/:id/messages가 sender_mode=twin을
검증 없이 그대로 저장·브로드캐스트하고 있었음 -- 에스컬레이션 게이트는
초안 생성(/draft) 경로에만 있었고 실제 발송 경로엔 없어서, 클라이언트가
/draft를 거치지 않고 바로 twin 메시지를 보내면 안전선을 완전히
우회할 수 있었다.

- ai-service: /draft와 별개인 POST /escalate/check 하드게이트 엔드포인트 추가
- core-backend: AIServiceClient.checkEscalation 추가, 메시지 저장 직전에
  twin 발송이면 무조건 호출하도록 해서 발송이 실제로 일어나는 단
  하나의 지점에서 막음. AI 서비스 응답 불가 시 fail-safe로 발송 차단.
  에스컬레이션되면 저장/브로드캐스트 없이 escalation_logs에만 기록.
  사람이 직접 보내는 메시지는 게이트 대상 아님
- core-backend: DELETE /users/:id 추가 -- 유저가 걸린 모든 행(트윈 설정·
  화이트리스트·연락처·대화참여·메시지·에스컬레이션로그·유저 본인)을
  트랜잭션으로 삭제 (tech-design.md §5 "사용자가 언제든 초기화 가능")
- 온디바이스 암호화·데이터 흐름 대시보드는 Flutter 클라이언트 책임이라
  이 환경에서는 보류, roadmap.md에 근거 남김
2026-07-30 02:26:02 +00:00
Claude fb06306d04
Go 코어에서 AI 서비스를 실제로 호출하는 연동 코드 추가
AIServiceClient.requestDraft가 ai-service/의 POST /draft를 호출하고,
core-backend에 POST /conversations/:id/draft 라우트를 추가해 프록시한다.
mock AI 서비스로 정상 응답·404(대화 없음)·400(스타일 소스 없음) 케이스를
테스트로 확인. roadmap.md Phase 1 §2.2 체크리스트 반영.
2026-07-30 02:15:32 +00:00