From 95141686d0db20d68b06c4804d1d122e702edca2 Mon Sep 17 00:00:00 2001 From: diadmin Date: Mon, 26 Oct 2026 12:30:01 +0900 Subject: [PATCH] =?UTF-8?q?CLAUDE.md=20=EC=9D=B8=EC=88=98=EC=9D=B8?= =?UTF-8?q?=EA=B3=84=20=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80:=20Flutter?= =?UTF-8?q?=20analyze=C2=B7test=C2=B7APK=20=EB=B9=8C=EB=93=9C=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=B0=EA=B3=BC=EC=99=80=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EC=86=8C=20=EA=B7=9C=EC=B9=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 맥 podman 컨테이너에서 flutter analyze 문제 없음, flutter test 239개 통과, APK(debug) 빌드 성공 - nsd_android 의 Kotlin Gradle Plugin 경고 기록 - 평소 Gitea 에 푸시, GitLab 은 하루 한 번 메이저 업그레이드 때만 Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8e5c703 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,60 @@ +# 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:` 번호의 기기 안 전용 사람이다. + +## 구조 +- `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, 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 test` 239개 통과(widget_test.dart 포함), 서버(Python) 18개 통과, check_modules.py 통과. +- `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). +- 컨테이너의 `flutter pub get` 은 pubspec.lock 을 낮은 판으로 바꾼다. 검사가 끝나면 `git checkout pubspec.lock` 으로 되돌린다. +- 알려진 한계: 윤달 생일 미지원(기일만 지원), 음력 변환 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) 화면 순서로, 기존 시험이 끝난 모듈은 고치지 않는다. +- 끝낼 때 한글로: 무엇이 바뀌었나, 무엇을 돌려 확인했나, 확인 못 한 것은 무엇인가.