Commit Graph

6 Commits

Author SHA1 Message Date
Cursor Agent b288d5ed90
Implement Phase 1 A1/A2 APIs and record build plan in roadmap
Add conversation/contact/history/escalation-log endpoints, contact-scoped
whitelist matching, bearer sessions, ADMIN_API_TOKEN guards, and
`go run . migrate`. Update Flutter client to persist/send session tokens
and mark A1/A2 complete in the prioritized checklist.

Co-authored-by: okuma <o0kuma@users.noreply.github.com>
2026-07-30 04:47:06 +00:00
Claude a741001197
화이트리스트 규칙 CRUD API + 메시지 되돌리기(undo) API 추가
화이트리스트 CRUD:
- POST/GET /users/:id/whitelist-rules, DELETE /users/:id/whitelist-rules/:ruleId
- Flutter의 자율성 설정 화면(roadmap.md 2.3)이 바로 붙여 쓸 수 있게
  준비. contact_id는 저장되지만 매칭 로직(whitelistMatches)은 아직
  전역 키워드만 봄 -- 대화방-연락처 연결 모델링 필요(기존에 문서화된
  한계, 그대로 유지)

되돌리기(one-tap undo, AGENTS.md 안전 불변식):
- Message.Retracted 필드 추가
- POST /messages/:id/retract -- 트윈이 자동발송한 메시지만 대상(사람이
  쓴 메시지는 400), 이미 되돌린 건 409
- 성공 시 같은 대화방 WebSocket에 {"type":"retraction", "id":...}
  브로드캐스트. 일반 메시지 브로드캐스트도 {"type":"message"}를 붙여서
  클라이언트가 두 이벤트를 구분할 수 있게 함

되돌리기 버튼/사후알림 UI 자체는 여전히 Flutter 쪽 몫으로 남아있음
2026-07-30 03:01:06 +00:00
Claude f79108b9cd
2.6 베타 배포 준비: 실제 초대 코드 시스템 + 운영 지표 + 거부권 안전 불변식 수정
발견한 문제(2.6 진행 중): 거부권(peer veto) 안전 불변식이 코드에 전혀
구현되어 있지 않았음. Contact.TwinDisabledByPeer는 스키마에만 있고
어디서도 읽거나 쓰지 않았고, tech-design.md §4는 "대화방 단위 플래그"
라는데 실제로는 상대(Contact) 단위로 모델링돼 있어 설계 문서와도
불일치. Conversation.TwinDisabledByPeer로 옮기고 POST
/conversations/:id/veto 추가, 메시지 발송 시 거부권 -> 에스컬레이션
-> 자율성 레벨 순으로 체크(앞 단계가 뒤 단계를 항상 이김)하도록 수정.

2.6 본작업:
- 초대 기반 가입: 기존엔 아무 문자열이나 처음 쓰면 통과돼서 실제로는
  초대 기반이 아니었음. InviteCode 테이블 + POST /invites(발급)
  추가하고 /auth/signup이 미리 발급된 미사용 코드인지 검증하도록 변경
  (모르는 코드 400, 이미 쓴 코드 409). 계정 삭제 시 코드는 "사용됨"
  상태를 유지한 채 유저 참조만 지움
- GET /admin/metrics 추가 -- 메시지 수(휴먼/트윈), 에스컬레이션
  사유별 집계, 거부권 발동률(vision.md 거부율 지표의 1차 근사),
  초대 코드 발급/사용 수. 생성 지연시간·오류율은 별도 계측 계층이
  없어 넣지 않고 문서에 명시

실제 베타 오픈 시점 자체는 roadmap.md §3(PoC 결과 필요)이 끝나야
정할 수 있어서 여전히 보류 -- 이번엔 서버 인프라만 준비함
2026-07-30 02:51:15 +00:00
Claude de8b44d536
2.5 QA: ai-service pytest 스위트 승격 + 자율성 플로우(L0~L2) 통합 테스트
ai-service:
- escalation_filter/retrieve_style/generation/main(FastAPI)의 ad-hoc
  TestClient 검증을 ai-service/tests/ 정식 pytest 스위트로 승격(34개).
  Gemini 호출은 mock, retrieve_style은 overlap이 recency를 항상
  이긴다는 것(과거 버그 재발 방지)까지 포함
- on_event(deprecated) -> lifespan 컨텍스트 매니저로 교체

core-backend: 자율성 플로우(L0->L1->L2) 통합 테스트를 쓰려면 실제 분기
로직이 있어야 해서, roadmap.md §2.2에서 미결로 남아있던 자율성 엔진
오케스트레이션 최소 버전을 이번에 구현:
- PATCH /users/:id/twin-settings -- 자율성 레벨 변경 (기본값 L0)
- 트윈 발송 시 에스컬레이션 통과 후 레벨 확인: L0는 항상 차단, L1은
  approved:true 필요, L2는 화이트리스트 매칭 시 즉시 자동발송·매칭
  없으면 L1과 동일하게 승인 필요. 에스컬레이션은 레벨/화이트리스트/
  승인 여부와 무관하게 항상 우선(테스트로 확인)
- 화이트리스트 매칭은 v1 최소 구현(전역 키워드 매칭, 상대별 예외는
  아직) -- 대화방↔연락처 연결이 모델링되지 않아 보류, README에 명시

온보딩·채팅·설정 수동 QA는 Flutter 클라이언트가 없어 이 환경에서는
보류, roadmap.md에 근거 남김
2026-07-30 02:37:36 +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 3902597418
Implement core backend in Go (item 2 of the build order)
Ports the Python prototype (backend/) to the actual chosen stack --
Gin + gorilla/websocket + GORM, same DB schema (models.go mirrors
backend/app/models.py), same endpoints (signup, message send,
WebSocket relay). backend/ stays as a reference prototype, not
removed.

Verified with go test: signup, duplicate-invite-code rejection (409),
404 on an unknown conversation, and WebSocket broadcast delivery all
pass -- the same cases the Python version was checked against.

Push notifications, AI service integration, and multi-device sync
are not in this commit -- see core-backend/README.md.
2026-07-30 01:42:48 +00:00