diff --git a/AGENTS.md b/AGENTS.md index dd0be71..7c3dd62 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,9 +81,10 @@ depend on PoC results (see `docs/roadmap.md` Phase 1 §2 for which workstreams those are). The tech stack for Phase 1 is decided — see `docs/tech-design.md` §8 -(Flutter/Dart client, Python/FastAPI backend, PostgreSQL, WebSocket relay, -drift+SQLCipher on-device). Do not re-litigate or invent a different stack; -build within this one unless a decision-log-style update changes it. +(Flutter/Dart client, Go core backend + Python AI service, PostgreSQL, +WebSocket relay, drift+SQLCipher on-device). Do not re-litigate or invent a +different stack; build within this one unless a decision-log-style update +changes it. ### Phase 1 앱 빌드 작업 규칙 diff --git a/backend/README.md b/backend/README.md index 00e89f2..08de9b1 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,8 +1,10 @@ -# 분신 backend +# 분신 backend (Python 프로토타입 — 참고용, Go로 포팅 예정) -Phase 1 백엔드 인프라 뼈대 (`docs/roadmap.md` Phase 1 §2.1). 스택 결정은 -`docs/tech-design.md` §8 참고 — Python/FastAPI, PostgreSQL(프로덕션)/SQLite(로컬 개발), -WebSocket 릴레이. +**스택이 바뀌었다**: `docs/tech-design.md` §8에서 코어 백엔드를 Go로 재확정했다 +(성능/동시성, 향후 스케일 대비). 이 디렉토리는 그 결정 전에 만든 Python/FastAPI 프로토타입으로, +인증·메시지 릴레이·DB 스키마가 실제로 동작하는 걸 검증하는 용도로는 여전히 유효하다 — +**API 설계·DB 스키마 참고용으로 남겨두고, Go 코어 백엔드를 새로 만들 때 이 동작을 그대로 재현한다.** +AI 서비스(2.2)는 그대로 Python으로 간다 — 그건 이 디렉토리가 아니라 별도 서비스로 만들 것. ## 실행 diff --git a/docs/roadmap.md b/docs/roadmap.md index 4bee807..f88e2a7 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -27,23 +27,26 @@ #### 1. 착수 전 확정 필요 (기술 스택) -- [x] 기술 스택 결정 — `tech-design.md` §8 (Flutter/Dart, 백엔드 Python/FastAPI, - PostgreSQL, WebSocket 릴레이, drift+SQLCipher, Gemini 키 분리) +- [x] 기술 스택 결정 — `tech-design.md` §8 (Flutter/Dart 클라이언트, Go 코어 백엔드 + + Python AI 서비스 투트랙, PostgreSQL, WebSocket 릴레이, drift+SQLCipher, Gemini 키 분리) #### 2. 워크스트림별 작업 -**2.1 백엔드 인프라** (PoC 결과 무관 — 지금 착수 가능) -- [x] 계정/인증 (초대 코드 기반 가입) — `backend/app/main.py` `POST /auth/signup`, 중복 코드 409 확인함 -- [x] 메시지 릴레이 서버 (송수신) — `backend/app/main.py` WebSocket + REST, 실제 TestClient로 브로드캐스트 확인함. - 멀티 디바이스 동기화(같은 유저 여러 기기)는 아직 — 지금은 대화방 단위 인메모리 커넥션 매니저뿐 -- [x] DB 스키마: users, contacts, conversations, messages, twin_settings, escalation_logs, whitelist_rules - — `backend/app/models.py` +**2.1 코어 백엔드** (Go, PoC 결과 무관 — 지금 착수 가능) +- [ ] 계정/인증 (초대 코드 기반 가입) — Python(`backend/app/main.py`)으로 프로토타입 구현·검증 + 완료(중복 코드 409 등), **Go로 포팅 필요** (스택 결정이 Python→Go로 바뀜) +- [ ] 메시지 릴레이 서버 (송수신) — 마찬가지로 Python 프로토타입은 WebSocket 브로드캐스트까지 + 검증됨, **Go(`gorilla/websocket` 등)로 포팅 필요**. 멀티 디바이스 동기화는 프로토타입에도 아직 없음 +- [ ] DB 스키마: users, contacts, conversations, messages, twin_settings, escalation_logs, whitelist_rules + — 스키마 설계 자체는 `backend/app/models.py`(SQLAlchemy)로 확정됨, Go 쪽 ORM(`pgx`/GORM)으로 재작성 - [ ] 푸시 알림 서비스 연동 -**2.2 AI 파이프라인 프로덕션화** (PoC 스크립트 → 서비스로 승격) -- [ ] `poc/tone-corpus/generate_draft.py`·`escalation_filter.py`·`retrieve_style.py`를 백엔드 API로 이식 +**2.2 AI 서비스** (Python, PoC 스크립트 → 내부 API로 승격) +- [ ] `poc/tone-corpus/generate_draft.py`·`escalation_filter.py`·`retrieve_style.py`를 감싸는 + FastAPI 서비스로 승격 (Go 코어가 내부망 HTTP로 호출) - [ ] 자율성 엔진(L0~L2) 오케스트레이션: 에스컬레이션 게이트 → 검색 → 초안 생성 → 승인/자동발송 분기 - (`tech-design.md` §3 흐름 그대로) + (`tech-design.md` §3 흐름 그대로) — 이 오케스트레이션이 Go 코어와 Python AI 서비스 중 어디 + 책임인지는 구현 시작 시 정할 것 (에스컬레이션 하드게이트는 Go 코어에 두는 게 안전선 원칙상 더 맞을 수 있음) - [ ] 온디바이스 말투 이력 저장 + 서버 최소 전송 원칙 구현 - [ ] 사후 알림 + 되돌리기 로그 스키마/API @@ -77,10 +80,10 @@ #### 4. 권장 착수 순서 (진행 상황) -1. [x] §1 기술 스택 결정 -2. [~] 2.1 백엔드 기본 인프라 (계정/인증, DB 스키마, 메시지 릴레이 — `backend/` 완료, 푸시 알림만 남음) - + 2.3 채팅 UI 뼈대 (병행) — **안드로이드 클라이언트 쪽이 다음 작업** -3. [ ] 2.2 AI 파이프라인 프로덕션화 (PoC 스크립트 재사용) +1. [x] §1 기술 스택 결정 (Go 코어 + Python AI 서비스로 재확정, `backend/`는 Python 프로토타입 — + 설계 참고용으로 남기고 Go로 포팅 필요) +2. [ ] 2.1 코어 백엔드를 Go로 (신규 구현) + 2.3 Flutter 채팅 UI 뼈대 (병행) — **다음 작업** +3. [ ] 2.2 AI 서비스 (Python, PoC 스크립트를 FastAPI로 승격) 4. [ ] 2.3 나머지 UX(온보딩·설정·뱃지) 5. [ ] 2.4/2.5 안전장치·QA 6. [ ] PoC 결과 반영 → §3 확정 → 2.6 베타 오픈 diff --git a/docs/tech-design.md b/docs/tech-design.md index 1410fc1..f03d875 100644 --- a/docs/tech-design.md +++ b/docs/tech-design.md @@ -109,14 +109,24 @@ v1에서는 커스텀 모델을 새로 학습하지 않는다. 대신 **검색 `roadmap.md` Phase 1 §1의 "착수 전 확정 필요" 항목에 대한 결정. PoC 데이터와 무관하게 지금 확정할 수 있는 것들이라 여기서 정리한다 — 자율성 기본값 같은 PoC 의존 값은 여전히 미정으로 남는다. +백엔드는 단일 서비스가 아니라 **두 개로 나눈다** — 코어(인증·메시지·DB)는 Go, AI 파이프라인은 +Python. 순수 성능/동시성만 보면 이 프로젝트 규모(소규모 지인 네트워크 베타)에서 Python +비동기(FastAPI/asyncio)로도 충분하다 — 메신저 릴레이는 CPU-bound가 아니라 I/O-bound라 GIL이 +병목이 되지 않고, 실제 지연은 백엔드 언어가 아니라 Gemini API 왕복 시간이 좌우한다. 그럼에도 +Go를 코어에 쓰기로 한 건 향후 스케일 대비 선제적 판단이며, `poc/tone-corpus/`의 이미 검증된 +AI 파이프라인(generate_draft·escalation_filter·retrieve_style)을 다시 짜지 않기 위해 AI 쪽만 +Python으로 남긴다. + | 항목 | 결정 | 근거 | |---|---|---| | 클라이언트 | Flutter (Dart) | Q7이 안드로이드 우선을 확정했지만 네이티브를 강제하진 않음. 채팅 UI(이미 클릭 프로토타입으로 검증된 디자인)를 핫리로드로 빠르게 만들 수 있어 v1 개발 속도에 유리. v2 OS 레이어의 알림 접근 권한(NotificationListenerService)은 platform channel로 네이티브 Android 모듈을 붙여 해결 — 클라이언트 전체를 네이티브로 갈 필요는 없음 | -| 백엔드 | Python (FastAPI) | `poc/tone-corpus/`의 AI 파이프라인(generate_draft·escalation_filter·retrieve_style)이 이미 Python — 언어를 바꾸면 그대로 재사용 못 하고 다시 짜야 함. 클로즈드 베타 규모에서 성능은 병목이 아님 | -| 메시지 릴레이 | FastAPI WebSocket | 자체 서버로 충분한 규모(소규모 지인 네트워크 베타). Kafka·관리형 pub-sub 같은 건 지금 시점에 과한 인프라 | -| 데이터베이스 | PostgreSQL | users/contacts/conversations/messages/escalation_logs/whitelist_rules 관계형 스키마에 적합, 운영 경험 풍부 | +| 백엔드 — 코어 서비스 | Go (Gin/Echo + `gorilla/websocket`) | 인증, 메시지 릴레이, DB 접근. 동시성·성능 이점, 향후 스케일 대비. 이 프로젝트 규모에선 Python으로도 충분했지만 선제적으로 Go 선택 | +| 백엔드 — AI 서비스 | Python (FastAPI) | `generate_draft.py`·`escalation_filter.py`·`retrieve_style.py`를 그대로 감싸는 내부 API. 이미 실행 검증까지 끝난 코드를 다시 짜지 않기 위함 | +| 서비스 간 통신 | Go 코어 → Python AI 서비스, 내부망 HTTP(REST) | 처음부터 gRPC 등으로 과설계하지 않음 — 필요해지면 그때 전환 | +| 메시지 릴레이 | Go 코어 서비스 내 WebSocket | 자체 서버로 충분한 규모. Kafka·관리형 pub-sub은 지금 시점에 과한 인프라 | +| 데이터베이스 | PostgreSQL | users/contacts/conversations/messages/escalation_logs/whitelist_rules 관계형 스키마에 적합. Go 쪽 접근은 `pgx`나 GORM | | 온디바이스 저장소 | Flutter `drift`(SQLite) + `sqlcipher_flutter_libs` 암호화 | 말투 이력·설정을 기기 내 암호화 저장한다는 §2/§5 원칙을 그대로 구현 | -| Gemini API 키 관리 | 프로덕션 키는 서버 환경변수/시크릿 매니저로, PoC 키와 분리 | `poc/tone-corpus/.env`는 PoC 전용 — 프로덕션 트래픽과 쿼터를 섞지 않음 | +| Gemini API 키 관리 | Python AI 서비스에서만 보관 (Go 코어는 키를 안 가짐) | `poc/tone-corpus/.env`는 PoC 전용 — 프로덕션 키·쿼터는 AI 서비스 환경에서만 분리 관리 | 이 표 밖의 결정(자율성 기본값, 화이트리스트 기본 주제, 신뢰 UX 문구)은 `roadmap.md` Phase 1 §3에 남아있는 PoC 의존 항목이다 — 여기서 같이 정하지 않는다.