Go to file
Claude a8c7b98922
스팸/도배 감지 최소 버전(2.7-C) 구현: 대화방 단위 자동 응대 일시중단 + 재개
PRD.md §4 엣지케이스가 "안전 관련이라 v1 최소 버전 필요"로 명시한 항목(P0)인데
관련 로직이 0건이었던 마지막 콘텐츠 갭(roadmap.md §2.7-C, deploy-checklist.md
N4-C3a/b)을 채운다. Track C(콘텐츠 갭) A/B/C 전체 완료.

- core-backend/flood_detect.go(신규): floodMessageThreshold=5건 /
  floodWindow=2분 상수 + floodDetected()/floodReason(). 안전을 위해 반드시
  있어야 하는 기술적 최소값이라 명시적으로 placeholder로 남기고 구현했다 —
  roadmap.md §3의 "PoC 결과가 있어야 정할 수 있는 것"(자율성 기본값 등 UX
  기본값)과는 성격이 다름. 카운트는 대화방 내 sender_id != 소유자인 메시지만
  집계(트윈 자동발송·소유자 본인 발송은 소유자 ID로 남으므로 자동 제외).
- core-backend/main.go: POST /conversations/:id/messages 하드게이트에
  peer-veto → 그룹 대화 차단 다음, 에스컬레이션 체크 이전 지점으로 추가 —
  트윈 자동발송 시도가 전부 지나가는 동일한 우회 불가 지점. 이미
  TwinDisabledByFlood가 켜져 있으면 재계산 없이 즉시 차단(중복 로그/쿼리
  방지). 새로 임계치를 넘기면 대화방을 영구 차단하고 EscalationLog 기록 +
  notifyUser 푸시.
- core-backend/models.go: Conversation.TwinDisabledByFlood 필드 추가.
  TwinDisabledByPeer(거부권, 사람의 일방적 선택 — v1엔 되돌리기 API 없음)와
  달리 이건 시스템이 자동으로 취하는 조치라서 AGENTS.md "every automatic
  action needs post-hoc notification + one-tap undo"가 그대로 적용됨 —
  POST /conversations/:id/flood-reset로 되돌릴 수 있게 별도 필드로 분리.
- core-backend/a1_a2_routes.go: GET /conversations 응답에
  twin_disabled_by_flood 추가(twin_disabled_by_peer와 동일한 자리).
- core-backend/flood_detect_test.go(신규): 임계치 경계값(정확히 N건은
  통과, N+1건은 차단), 사람 발송은 게이트 안 걸림, 윈도우 밖 과거 메시지는
  집계 제외, flood-reset으로 재개, 존재하지 않는 대화방 404 — 5개 테스트.
- mobile/lib/models/models.dart, services/api_client.dart: 모델·API
  클라이언트에 twinDisabledByFlood/resetFlood() 추가.
- mobile/lib/screens/conversation_list_screen.dart: 대화 목록에 도배 차단
  배지(거부권과 같은 자리, 다른 아이콘/문구).
- mobile/lib/screens/chat_screen.dart: 채팅방을 열면(목록에서 넘어온 초기
  상태) 또는 발송 시도가 다시 차단되면 배너에 "자동응대 재개" 버튼을 보여줌
  — one-tap undo. 새 알림 메커니즘을 만들지 않고 기존 EscalationLog/
  InboxScreen을 그대로 재사용.
- mobile/test/models_test.dart: twin_disabled_by_flood 파싱 테스트 추가.
- docs/roadmap.md §2.7-C, docs/deploy-checklist.md N4-C3a/b·Track C 요약·
  "바로 다음 5개"를 완료로 갱신.

테스트: go test ./... 51/51, python3 -m pytest tests/ -q 47/47,
flutter analyze 클린 + flutter test 5/5 모두 통과.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YSB5PqF38raTxP5ABgr9m
2026-08-03 05:12:29 +00:00
ai-service 관계별 페르소나(2.7-B) 구현: 관계 티어 필드 + 온보딩/연락처 UI + 톤 프롬프트 분기 2026-08-03 04:59:34 +00:00
backend 제품명 변경(분신→와카뷰) + 소프트 그라디언트/글래스모피즘 UI + 브랜드 로딩 화면 2026-07-31 01:15:42 +00:00
core-backend 스팸/도배 감지 최소 버전(2.7-C) 구현: 대화방 단위 자동 응대 일시중단 + 재개 2026-08-03 05:12:29 +00:00
deploy feat(deploy): Docker Compose stack for msn.iykyka.com (N2-B) 2026-07-31 02:26:40 +00:00
docs 스팸/도배 감지 최소 버전(2.7-C) 구현: 대화방 단위 자동 응대 일시중단 + 재개 2026-08-03 05:12:29 +00:00
mobile 스팸/도배 감지 최소 버전(2.7-C) 구현: 대화방 단위 자동 응대 일시중단 + 재개 2026-08-03 05:12:29 +00:00
poc/tone-corpus Merge origin/main: keep gradient/glassmorphism UI, port demo-invite + boot hardening, purge 분신 branding 2026-07-31 01:30:50 +00:00
scripts docs(ops): complete N3 stabilize — backup, tester guide, smoke results 2026-07-31 04:06:09 +00:00
secrets feat(fcm): send pushes via HTTP v1 service account 2026-07-31 07:33:23 +00:00
.dockerignore feat(deploy): Docker Compose stack for msn.iykyka.com (N2-B) 2026-07-31 02:26:40 +00:00
.env.example feat(fcm): send pushes via HTTP v1 service account 2026-07-31 07:33:23 +00:00
.gitignore feat(fcm): send pushes via HTTP v1 service account 2026-07-31 07:33:23 +00:00
AGENTS.md docs: add deploy/residual checklist (N1–N5) after Phase 1 A–C 2026-07-31 01:54:55 +00:00
CLAUDE.md docs: add deploy/residual checklist (N1–N5) after Phase 1 A–C 2026-07-31 01:54:55 +00:00
README.md docs: record Gemini key live on msn.iykyka.com (draft status=ok) 2026-07-31 04:19:44 +00:00
docker-compose.yml feat(fcm): send pushes via HTTP v1 service account 2026-07-31 07:33:23 +00:00

README.md

hikikomori / 와카뷰 (가칭)

카카오톡 대안 메신저 — "나를 대신해 남과 대화하는 AI 와카뷰".

구조

경로 역할
docs/ 기획·PRD·기술설계·로드맵·PoC 계획
core-backend/ Go 코어 (가입·메시지·WebSocket·자율성·안전장치)
ai-service/ Python AI 내부 API (/draft, /escalate/check)
backend/ 초기 Python 프로토타입 (참고용)
poc/tone-corpus/ PoC 실험 스크립트
mobile/ Flutter 클라이언트 (Android 우선)

문서

AI 에이전트 규칙

  • AGENTS.md · CLAUDE.md
  • 브랜치: 작업·머지는 항상 main
  • 리모트: GitHub origin + Gitea gitea(iykyka) — main 갱신 후 ./scripts/push-both.sh

현재 단계

  • Phase 1 A~C + N2 컷오버 + N3 안정화 완료 — 라이브: https://msn.iykyka.com
  • 테스터 안내: docs/tester-guide.md · 데모 코드 DEMO-YKAVU
  • 다음 (선택): N4 FCM·Android QA
  • 맨 마지막: N5 / D — 사람 PoC (docs/roadmap.md §3). §3 기본값 추측 금지
  • 프로토타입 공유 URL은 docs/prototype.mdSHARE_URL에 Master가 기입

로컬 실행 (요약)

# 터미널 1 — AI 서비스
cd ai-service && pip install -r requirements.txt
export GEMINI_API_KEY=...   # or repo-root .env
uvicorn app.main:app --port 8001

# 터미널 2 — 코어 백엔드
cd core-backend
export ADMIN_API_TOKEN=dev-admin-token
go run . migrate && go run .

# 초대 코드 발급 예:
# curl -X POST http://localhost:8080/invites -H "Authorization: Bearer $ADMIN_API_TOKEN"

# 터미널 3 — Flutter (Android)
cd mobile && flutter run --dart-define=CORE_API_BASE=http://10.0.2.2:8080

Docker (N2-B / msn.iykyka.com)

cp .env.example .env   # ADMIN_API_TOKEN, POSTGRES_PASSWORD 필수
# 로컬: PUBLIC_API_BASE=http://localhost:8088
docker compose up -d --build
curl -sS http://localhost:8088/health

Postgres·AI는 내부망만. 엣지 프록시는 web:80(또는 WEB_HOST_PORT)만 공개.