← 목록으로

teamai 핸드오프 — 2026-08-19

프로젝트를 되살린 날의 기록. 내일 여기부터 읽고 이어서 하면 된다.
어제(8/18) 저장소를 다시 클론한 시점엔 앱이 아예 안 떴고, 대화도 안 됐다. 지금은 둘 다 된다.


지금 상태 한 줄

미리보기 https://dev-take-6.the-moment.us — 로그인 없이 들어가서 크루와 실제로 대화가 된다.

항목 수치
크루 203개 (이미지 보유 100)
상담 904건
메시지 3,626건
크루 기억 1,534건 (임베딩 전량 보존)
내 크루 62건
DB 테이블 38개

접속·자격 정보 (전부 .env 에 있음, git 미추적)

무엇 값/위치 상태
Supabase 프로젝트 tshbvqqvdycougdqrgza (team-ai) ACTIVE_HEALTHY
DB 직접 접속 .env 의 DATABASE_URL psql 로 바로 붙는다
LLM Vercel AI Gateway (AI_GATEWAY_API_KEY) 엣지 함수 시크릿 등록 완료
미리보기 계정 p2j2dyffpf@privaterelay.appleid.com / TeamAiDevPreview2026 자동 로그인됨
미리보기 서빙 로컬 도커 teamai-web → 40025 → 터널 restart unless-stopped

⚠️ 미리보기 URL 은 이 맥에서 도는 컨테이너에 물려 있다. 맥이 꺼지면 주소도 죽는다.


오늘 한 일 (커밋 9개)

2f561a23 크루 203개 게이트웨이 최신세대 모델 재배정 + 대화 복구
cd522a0a Vercel AI Gateway 프로바이더 추가, 폴백 경로 교체
33a5654a 아바타 1.7MB→69KB, 큐레이티드 3인방 아바타 R2 에서 회수
80ebacd8 사용자 관계·기억 이관 + expert_id 잔재를 crew_id 로 통일
213fa429 구 카탈로그 experts 200건을 crews 로 이관
49f7cde0 복원된 DB 에 빠져 있던 테이블 10개 복구
93d58477 미리보기 자동 로그인
13aa56e2 키가 번들에 구워지던 것 차단 + 로그인 없이 확인용 우회
7dc9ef29 모바일 전용 초기화 실패로 웹 앱 전체가 죽던 것 차단

이번에 배운 것 — 관통하는 원인 하나

expert → crew 개명이 절반만 끝난 채 방치돼 있었다. 그게 층마다 다른 증상으로 터졌다.

층 증상 조치
테이블 크루 3개만 보임 (진짜 200개는 experts 에) 데이터 이관, id 보존
컬럼 대화 목록 비어 있음 (consultations.expert_ids) crew_ids 로 개명
값 응답 저장 실패 (sender_type='crew' 거부) 제약 교체 + 3,399건 이관
함수 대화 404 (coordinate-experts 만 배포됨) coordinate-crews 배포

→ 새 이름을 쓰기 전에 그 이름이 DB·제약·배포까지 다 갔는지 확인할 것.


🔴 백로그

우선순위 정의 — P0 지금 안 하면 손해가 계속 커짐 / P1 이거 없으면 다음 작업이 느림
/ P2 있으면 좋음, 급하지 않음 / P3 제품 방향이 정해져야 시작 가능

진행 표시: [ ] 미착수 · [~] 진행중 · [x] 완료
각 항목의 완료 판정은 "무엇을 보면 끝난 줄 아는가"다. 추측 말고 그걸 확인하고 체크할 것.


🟥 P0 — 보안 (손해가 시간에 비례해 커짐)

P0-1. 살아있는 키 2개 재발급 ⚠️ 8/21 재확인: 아직 안 됨

저장소에 하드코딩돼 GitHub에 커밋됐고, 8/21 실측에서 여전히 유효(둘 다 HTTP 200).
git 히스토리에 남아 파일만 고쳐선 소용없다 — 무효화가 유일한 해결책.

cd ~/Projects/teamai
sed -i '' 's|^SUPABASE_SERVICE_KEY=.*|SUPABASE_SERVICE_KEY=새값|' .env
sed -i '' 's|^SUPABASE_ACCESS_TOKEN=.*|SUPABASE_ACCESS_TOKEN=새값|' .env
SUPABASE_ACCESS_TOKEN=새값 supabase secrets set SUPABASE_SERVICE_ROLE_KEY=새값 \
  --project-ref tshbvqqvdycougdqrgza

완료 판정: 옛 키로 /rest/v1/crews 호출 시 401이 떠야 한다. 200이면 아직이다.

OpenAI·FAL 키는 이미 죽어 있어(401 실측) 조치 불필요.

P0-2. Apple 서명 개인키 상태 확인

lib/AuthKey_KXD92Y2WLM.p8 가 저장소에 평문 커밋돼 있다. 유효성은 내가 테스트할 수단이 없다.

완료 판정: git ls-files | grep p8 결과 0건.

P0-3. .env 가 웹 번들에 통째로 실리는 구조

pubspec.yaml:86 이 .env 를 앱 자산으로 등록 → 웹 빌드하면 .env 전체가 공개된다.
지금은 서빙 단계에서 걸러 막아뒀을 뿐이라, 누가 그냥 배포하면 service_role 키까지 나간다.

완료 판정: flutter build web 후 build/web/assets/.env 가 없어야 한다.


🟧 P1 — 속도와 품질 (이게 막혀 다음 작업이 느리다)

P1-1. 개발 루프 12분 → 1초 (가장 큰 병목)

코드 한 줄 고칠 때마다 도커 빌드 12분 + 터널 왕복. 이 상태로는 고도화가 불가능하다.
원인은 이 맥의 Dart 실행 파일이 실행 즉시 멈추는 것 — 서명·quarantine 모두 정상인데
프로세스가 CPU 0%, RSS 96KB 로 정지한다. 그래서 도커로 우회 중이고 도커는 핫리로드가 안 된다.

완료 판정: flutter run -d chrome 이 뜨고, 코드 저장 시 1~2초 내 화면 반영.

P1-2. 미리보기 URL이 이 맥에 묶여 있다

dev-take-6.the-moment.us 는 로컬 도커 컨테이너 → 터널 구조라 맥이 꺼지면 주소도 죽는다.

완료 판정: 맥 재부팅 후에도 URL 이 200.

P1-3. 크루 품질 — 플레이북·지식베이스가 3개뿐

이관한 200개는 system_prompt 만 있고 leader_playbook/member_playbook/지식베이스가 없다.
목록엔 다 뜨지만 대화 깊이가 3개(토스합격왕·맛있으면0칼·아노센세)와 확연히 다르다.

완료 판정: 플레이북 보유 크루 수가 3 → 목표치. crew_knowledge 행 수 > 0.

P1-4. 모델 실사용 비교 (지금 배치의 목적)

제공사를 일부러 섞어 배정해 뒀다. 같은 프롬프트가 어디서 잘 도는지 실사용으로 판정하는 게 목적.

완료 판정: 어느 모델을 왜 골랐는지 한 문단으로 적을 수 있는 상태.

P1-5. 로그인 경로 정상화 (지금은 개발 우회 중)

완료 판정: 우회 플래그 없이 구글 로그인으로 앱 진입 성공.


🟨 P2 — 정리 (급하지 않지만 쌓이면 부담)

P2-1. 크루 이미지 103개 없음

203개 중 100개만 보유. 나머지는 로컬·Supabase·Cloudflare R2 어디에도 없다(전수 확인).
깨진 게 아니라 생성된 적이 없다. 대표 지시로 보류 중.

P2-2. 구 테이블·함수 정리 (되돌릴 자리로 남겨둔 것)

며칠 써보고 이상 없으면 삭제. P1 끝나기 전엔 건드리지 말 것.

P2-3. 레거시 코드 제거

P2-4. 테스트·회귀 방어

오늘 고친 것들이 다시 깨지지 않게.


🟩 P3 — 제품 방향이 정해져야 시작 가능



자주 쓰는 명령

# DB 붙기
cd ~/Projects/teamai
psql "$(grep '^DATABASE_URL=' .env | cut -d= -f2-)"

# 웹 빌드 (도커. 약 12분)
docker run --rm -v ~/Projects/teamai:/app -w /app ghcr.io/cirruslabs/flutter:stable \
  bash -lc "git config --global --add safe.directory /app; flutter pub get; flutter build web --release"

# 배포본 갱신 (민감 키 걸러서)
cd ~/Projects/teamai/build && rm -rf web-public && cp -R web web-public && \
  { grep -E '^(SUPABASE_URL|SUPABASE_ANON_KEY)=' ../.env; \
    printf 'DEV_SKIP_AUTH=true\nDEV_AUTOLOGIN_EMAIL=p2j2dyffpf@privaterelay.appleid.com\nDEV_AUTOLOGIN_PASSWORD=TeamAiDevPreview2026\n'; } \
  > web-public/assets/.env && docker restart teamai-web

# 엣지 함수 배포
cd ~/Projects/teamai && SUPABASE_ACCESS_TOKEN=$(grep '^SUPABASE_ACCESS_TOKEN=' .env | cut -d= -f2-) \
  supabase functions deploy coordinate-crews --project-ref tshbvqqvdycougdqrgza --no-verify-jwt

# 모델 갈아끼우기 (파일의 모델 문자열만 고치고 실행)
psql "$(grep '^DATABASE_URL=' .env | cut -d= -f2-)" -f scripts/assign_crew_models.sql

현재 모델 배정

전부 Vercel AI Gateway 경유. 제공사를 섞어 같은 프롬프트를 실사용 비교하는 배치다.
"옛날 레거시 싼 것"(claude-haiku-4.5, gemini-2.5-flash-lite)은 대표 지시로 제외.

티어 모델 입력/출력 ($/1M) 크루 수
normal xai/grok-4.1-fast-non-reasoning 0.20 / 0.50 70
rare google/gemini-3.1-flash-lite 0.25 / 1.50 81
premium openai/gpt-5.6-luna 0.20 / 1.20 49
플래그십 anthropic/claude-sonnet-5 2.00 / 10.00 3

네 모델 전부 한국어 캐릭터 응답 실측 확인(3~9초).
게이트웨이엔 모델 347종이 있어, 바꾸고 싶으면 문자열만 교체하면 된다.


이번에 만든 스크립트

파일 용도
scripts/assign_crew_models.sql 크루별 LLM 모델 배정
scripts/migrate_experts_to_crews.sql 구 카탈로그 200건 이관
scripts/migrate_user_crews_and_memories.sql 관계·기억 이관 (임베딩 보존)
scripts/restore_missing_tables.sql 복원 DB 에 없던 테이블 10개 생성
scripts/fix_missing_crew_columns.sql crews 누락 컬럼 3개
scripts/optimize_crew_avatars.sh 아바타 256px 축소 후 업로드
scripts/serve_web.py 미리보기 정적 서버 (민감 키 필터링)
scripts/nginx-web.conf 캐시 금지 설정