6.4 KiB
6.4 KiB
Friendly Map — Claude 작업 지침 (인수인계)
이 파일은 이전 대화(claude.ai 프로젝트 "Frindly Map")에서 정한 것을 새 세션에 넘기는 문서다. 세션을 시작하면 먼저 이 파일, README.md, tool/check_modules.py 를 읽고, 작업 전에 아래 원칙을 한 번 읊고 시작한다.
사용자와 일하는 규칙 (1순위, 어기지 말 것)
- 모든 답변은 한글. 고친 파일은 일부 발췌가 아니라 처음부터 끝까지 완본으로 보여 준다.
- "목업"이라는 말은 쓰지 않는다 ("화면 설계"라고 한다).
- 나는 솔루션 개발자다: 구조가 기능보다 먼저다. 화면과 내부를 분리한다.
- 모듈화 필수. 모듈은 다른 모듈을 고치지 않고 빼고 끼울 수 있어야 한다.
tool/check_modules.py가 의존 방향을 검사한다(새 모듈은 ALLOW 표에 등록). - 소스 파일은 300~400줄, 최대 700줄.
- 모듈별로 시험한다(
tool/test_module.sh <모듈>). 시험이 끝난 모듈은 다시 만들지 않고 그 위에 쌓는다. - 한 번에 한 플랫폼. 지금은 안드로이드만. 다른 플랫폼은 사용자가 지정할 때
platform_<이름>모듈만 새로 붙인다. - 단계마다 되묻지 말고 합리적으로 정해 진행하고, 결정한 내용은 결과에 적는다. 멈춰 서서 "대기"하지 않는다. (단, 되돌릴 수 없는 파괴적 작업은 먼저 묻는다.)
제품
Android 다크모드 인맥 앱(Flutter/Dart). 옛 "Family MAP" + 카카오톡식 대화. 목적별 명함(개인/회사/학교/그룹·여행/가족) 교환, "어디서 봤지?" 유추, 가계도, 연결 고리, 검색, 자동 연동 추천, 내 정보 숨기기, 가족 모임(촌수·통화 요약·생일/기일 알림).
이미 정한 기술 결정 (바꾸지 말 것)
- 모든 데이터는 기기에 암호화 저장(안드로이드 SQLCipher). 전화번호는 식별자일 뿐 키 재료가 아니다.
- 모든 기기가 서버 겸 클라이언트(P2P). 외부 DB(server/)는 암호화된 임시 우편함 + 기준 시각 제공뿐.
- 12단어 복구 코드, Shamir 조각 기본 5/3(설정으로 조절), 사람 식별은 전화번호 1순위·이름 2순위.
- 대화는 영구 보관, 1MB/기기 사용률 80% 초과 시 별도 저장(조절 가능). 시각은 1/100초, 충돌 시 먼저 쓴 변경이 앞선다. 고친 명함은 "다시 보내기"에서만 보낸다. 그룹 대화 키는 돌리지 않는다.
- 가족 모임 데이터(가계도, 생일, 기일, 통화 주제)는 기기 안에만 저장하고 어디로도 보내지 않는다. 전화번호 없는 친척은
local:<id>번호의 기기 안 전용 사람이다.
구조
lib/modules/<이름>/<이름>.dart가 모듈의 공개 입구(예외: platform_ui.dart, storage_sqlite.dart). 다른 모듈은 입구 파일만 import.- 모듈: core, platform, platform_android, storage, keys, sharing, sync, transport, discovery, inference, layout, visibility, kinship, events, groups, app, ui.
- 조립은 모듈 밖:
lib/main.dart,lib/composition/android_bootstrap.dart. - 안드로이드 전용 플러그인은 platform_android 에서만 import (PLATFORM_ONLY 목록).
- 화면은
AppScope.of(context).app(FriendlyApp)의 서비스만 쓴다.
상태 (2026-10-26 기준)
- 맥 podman Flutter(stable) 컨테이너에서
flutter analyze문제 없음,flutter test266개 통과(widget_test.dart 포함), 서버(Python) 18개 통과, check_modules.py 통과. - 2026-10-26 추가: groups 모듈(그룹 정의·비밀번호 잠금), 주소록 가져오기(flutter_contacts), 설정의 "그룹 · 주소록". 다음은 "채팅에서 시작하는 관계망" 로드맵 1단계(그룹 계층).
flutter build apk --debug성공(app-debug.apk 약 190MB). 첫 빌드는 SDK 34·35, CMake 를 내려받느라 약 17분 걸린다.- 빌드 경고(아직 빌드를 막지는 않음):
nsd_android가 Kotlin Gradle Plugin 을 직접 적용한다. 앞으로 Flutter 판에서 빌드가 실패할 수 있으니, 지원 판이 나오면 nsd 버전을 올린다. geolocator_android 는 deprecated API 를 쓴다는 Note 만 나온다. - 확인 안 된 곳: 실제 기기에서 화면 실행과 플러그인 동작(geolocator, call_log, url_launcher, flutter_local_notifications, timezone, sqflite_sqlcipher, nsd, mobile_scanner, sensors_plus, flutter_secure_storage).
- pubspec.lock 은 이 컨테이너(Flutter stable)에서 풀린 판을 기준으로 올린다(2026-10-26 flutter_contacts 추가 때부터).
- 빌드 캐시:
-v fm-gradle:/root/.gradle -v fm-pub:/root/.pub-cache를 붙이면 두 번째 빌드부터 빨라진다. - 알려진 한계: 윤달 생일 미지원(기일만 지원), 음력 변환 1951~2049년, 통화 기록 읽기(READ_CALL_LOG)는 Play 스토어 제한, WebRTC·앱 잠금·복구 단어 재확인 알림·공유 이미지/PDF 저장·우편함 요청 서명은 미구현. 문자 인증은 서버에
--sms-webhook연결이 필요.
빌드·시험 방법 (Mac Pro 2013, podman)
Flutter 는 직접 설치하지 않고 컨테이너로 쓴다 (프로젝트는 홈 폴더 안에 있어야 podman machine 이 공유한다):
podman machine start
podman run --rm -it -v "$PWD":/app -w /app ghcr.io/cirruslabs/flutter:stable bash
flutter create --platforms=android --org com.friendlymap --project-name friendly_map .
python3 tool/android_patch.py # 권한·수신기·desugaring·minSdk 패치 (여러 번 돌려도 같은 결과)
flutter pub get && flutter analyze && flutter test
flutter build apk --debug # build/app/outputs/flutter-apk/app-debug.apk
build/,.dart_tool/는 만들어지는 폴더라 저장소에 올리지 않는다(.gitignore).android/는 Gitea 에는 올라가 있다.- 서버 시험:
cd server && python3 -m unittest test_mailbox test_verify. - 모듈 경계 검사:
python3 tool/check_modules.py. - 저장소: http://192.168.88.15:3180/diadmin/frindlymap (Gitea, remote origin). 고친 뒤 커밋해서 Gitea 에 푸시한다.
- GitLab 에는 올리지 않는다. 단, 하루 한 번 메이저 업그레이드 때만 GitLab 에 올린다(원격은 아직 등록되지 않음).
작업 방식
- 고치면 해당 모듈 시험을 다시 돌리고, 마지막에 전체 시험과 check_modules.py 를 돌린다.
- 새 기능은 (1) 순수 모듈 또는 서비스 + 시험 → (2) 화면 순서로, 기존 시험이 끝난 모듈은 고치지 않는다.
- 끝낼 때 한글로: 무엇이 바뀌었나, 무엇을 돌려 확인했나, 확인 못 한 것은 무엇인가.