Private-group motorcycle route and segment weather planner for Korea
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
지인 라이더를 위한 국내 24시간 미만 오토바이 경로·시간대별 날씨 계획 PWA입니다. 사용자가 순서대로 정한 경유지를 지나는 오토바이 안전 추천 경로 1개의 실제 도로 형상, 예상 복귀 시각, 구간별 통과 시각과 기상청 예보를 보여줍니다. KMA 정시 요청 교정을 8bd8878로 Preview에 반영했고, 앞서 막혔던 실제 날씨·컬렉션 저장/복원·공유 발행/회수/재발행 검증이 통과했습니다(연결 1 PASS, 실패·오류·skip·재시도 0). 정확한 테스트 소유 데이터 정리도 완료했습니다. Production 승격은 별도 승인·검증 대상입니다. 교정은 초단기 요청에 기존 :45 선택 기준과 정시를 사용하고, 요청·응답 발표시각의 정확 일치는 계속 검증합니다. 초단기는 도착 목표 시각의 예보가 없으면 다른 시각을 대신 쓰지 않고 기존 오류·오래된 저장본 표시 경로로 처리합니다. 단기의 3시간 간격 자료 선택은 유지합니다. 두 임시 실측 함수는 사용 후 삭제했으며, 비밀·원문·실제 사용자 위치를 기록하지 않았습니다. 실측과 구현 계약, 배포·연결 검증 기록을 참조하세요.查看完整 README ↗
지인 라이더를 위한 국내 24시간 미만 오토바이 경로·시간대별 날씨 계획 PWA입니다. 사용자가 순서대로 정한 경유지를 지나는 오토바이 안전 추천 경로 1개의 실제 도로 형상, 예상 복귀 시각, 구간별 통과 시각과 기상청 예보를 보여줍니다.
KMA 정시 요청 교정을
8bd8878로 Preview에 반영했고, 앞서 막혔던 실제 날씨·컬렉션 저장/복원·공유 발행/회수/재발행 검증이 통과했습니다(연결 1 PASS, 실패·오류·skip·재시도 0). 정확한 테스트 소유 데이터 정리도 완료했습니다. Production 승격은 별도 승인·검증 대상입니다.
교정은 초단기 요청에 기존 :45 선택 기준과 정시를 사용하고, 요청·응답 발표시각의 정확 일치는 계속 검증합니다. 초단기는 도착 목표 시각의 예보가 없으면 다른 시각을 대신 쓰지 않고 기존 오류·오래된 저장본 표시 경로로 처리합니다. 단기의 3시간 간격 자료 선택은 유지합니다. 두 임시 실측 함수는 사용 후 삭제했으며, 비밀·원문·실제 사용자 위치를 기록하지 않았습니다. 실측과 구현 계약, 배포·연결 검증 기록을 참조하세요.
최신 실제 연결 검사는 PASS 1 / FAIL 0 / ERROR 0 / SKIP 0 / DESELECTED 0 / XFAIL 0 / SETUP_OR_IMPORT_FAILURE 0입니다. 컬렉션·공유 발행·회수·재발행과 정확한 테스트 소유 데이터 정리가 완료됐고 예상 밖 운영 오류는 없었습니다. Production·DB·비밀값·유료 API·자동 결제는 변경하지 않았습니다.
배포된 B1 진단은 이미 거절된 응답의 관계를 제한된 범주로만 기록합니다. COMPLETE는 받은 배열 전체 검사이며 원격 모든 페이지 증명이 아닙니다. 일정 분류는 기존 공식 :30 기준이므로 실측 정시는 INVALID/INTERSTITIAL로 표시될 수 있지만, B1은 정상 수용 판정에 사용하지 않습니다.
car_type=7)와 자동차전용도로 회피(avoid=motorway)를 항상 함께 사용합니다. 안전 조건을 완화하거나 자동차 경로로 대체하지 않습니다.경유지는 Kakao가 자동으로 찾는 와인딩 속성이 아니라 사용자가 정한 필수 통과점입니다. Kakao 대안 경로를 탐색하지 않으며 안전 추천 경로를 만들 수 없으면 명시적으로 실패합니다.음식점 추천 받기로 실제 방문할 식당 1곳 또는 2곳을 추천받을 수 있습니다. 내가 저장한 식당만 대상이며, 원하는 식사 시간 앞뒤 허용 범위(기본 30분, 30분 단위로 최대 90분) 안에 도착하고 주행이 1시간(두 곳은 합계) 이내로 늘어나는 후보를 늘어나는 주행 시간이 짧은 순으로 보여 줍니다. 조건을 자동으로 넓히지 않고, 사용자가 고른 식당만 식사로 추가한 뒤 경로를 다시 계산합니다. 영업정보는 제공하지 않으며 추천 설계·검증 기록을 따릅니다.공유 준비는 완전한 코스를 적용한 뒤 새 안전 경로와 아직 유효한 최신 날씨가 저장되어야 간결한 여행 루트·날씨 미리보기를 한 번 열며 자동 게시하지 않습니다.0.2.3은 카카오 전체 소요시간을 유지하면서 구간 도착 시각을 비례 배분하는 수정입니다. 도착 시각은 추정값으로 안내하며, 정차·날씨 조회·저장에도 같은 시간을 사용합니다. 거리·경유지·도로 연결성과 이륜차 안전 조건 검증은 유지합니다. 수정 범위와 실제 배포·검증 상태를 참조하세요.
화면 아래의 현재 버전 링크와 /updates에서 사용자가 체감할 주요 변화만 확인할 수 있습니다. 새 버전은 로그인한 사용자마다 첫 접속에 한 번 안내하며, 팝업을 닫은 뒤에도 업데이트 페이지에서 다시 읽을 수 있습니다. 같은 계정의 다른 기기·브라우저도 확인 기록을 공유합니다.
공유받은 링크는 라이딩 요약으로 열립니다. 0.3.0 이후 발행한 링크는 로그인한 활성 회원이 내 경로로 저장을 눌러 자신의 컬렉션으로 복사하거나 새 일정으로 출발로 바로 계획할 수 있습니다. 장소·경유 순서·휴식 시간은 유지하고 날짜·출발 시각·당시 경로 결과와 날씨는 저장하지 않습니다. 저장 경로를 적용하면 새 출발 일정을 선택합니다. 이번 기능의 검증·배포 및 사용자가 요청한 이전 기록 정리 상태는 실행 기록을 확인하세요.
0.3.0의 화면 개편은 홈·경로 편집·라이딩 요약·저장한 경로 모음을 구분하고, 모바일의 전체 화면 장소 검색과 PC의 지도·편집 병렬 배치를 제공합니다. 날짜·시·분 선택과 경유지 순서·휴식 설정도 새 흐름에 맞춥니다. 기존 개편은 Figma 앱 반영 기록을 참조하세요.
0.10.0 후보는 라이딩 스팟과 식당을 계정당 합계 1,000개 저장하고 자주 찾는 곳 5개에 별표를 지정합니다. 검색·지도 좌표 등록, 별명, 시·도 필터와 독립 지도 핀 표시를 지원하며 역할·정차 확인 후 경유지에 추가합니다. 경로·날씨는 직접 다시 계산합니다. 실제 적용 환경과 검증 상태는 Issue99 실행 기록을 확인하세요.
버전 번호와 공개 기록은 버전·업데이트 규약을 따릅니다. 버전·기록·페이지·팝업 및 사용자별 확인 상태를 함께 검증한 뒤 기존 develop -> main 절차로 배포합니다.
0.4.0에서 소유자 라이딩 요약의 중복 수정 버튼을 경로 실행으로 바꾸고, 뒤로가기는 경로·시간 편집으로 유지하는 동작을 구현했습니다. 실제 배포 상태와 검증 결과는 상세 계획 및 릴리스 기록을 참조하세요. PC는 카카오맵 웹을, 모바일은 카카오맵 앱을 열며 미설치·실행 불가 시 설치 후 복귀·재실행을 안내합니다. 모바일 웹 길찾기 대체는 사용하지 않습니다. 경유지 5개 초과와 소유자 입력 수정 후 미계산 결과는 실행을 막습니다.
공유받은 요약에서도 경로 실행을 주요 버튼으로 제공하며 저장·새 일정 생성 없이 장소와 방문 순서를 전달합니다. 공유 당시 시간·날씨는 현재 주행 기준이 아님을 안내합니다. 새 일정으로 출발은 내 날짜·시간으로 경로·날씨를 다시 계산하고, 내 경로로 저장은 나중을 위해 컬렉션에 저장하는 보조 동작입니다. 상단은 홈으로로 구분합니다. 공유 경유지가 5개를 넘으면 실행을 막고 새 일정에서 사용자가 직접 줄여 재계산하도록 안내합니다. 소유자 요약의 수정 후 재계산 조건은 그대로 유지합니다.
0.4.1은 Figma 댓글을 반영해 안전 안내를 두 항목으로 줄이고 별도 설치 화면을 제거했습니다. Android Intent와 iPhone의 제한적 자동 이동으로 공식 스토어 연결을 시도하고, 실행 후 복구 링크를 제공합니다. 기존 휴대폰 앱 실행은 사용자 확인 PASS이며 새 미설치/스토어 이동은 NOT_RUN입니다. 배포·검증 결과, 카카오맵 실행 계획, Issue #59를 참조하세요.
2026-09-18 사용자 결정에 따라 남은 카카오맵 실기기 검증은 버그 발생 시 대응하며, 다음 순서는 공유 발행 상태 문구 #66 수정·검증 → Android API 기반 #30 준비입니다. 현재 수정·검증 기록과 Android 요구사항을 참조하세요. 로컬 수정과 실제 배포 상태는 구분합니다.
빈 출발 날짜·시간 선택창에는 현재 이후 가장 가까운 5분 시각을 제안합니다. 분은 00분부터 5분 단위이며, 자정을 넘으면 다음 날짜로 제안합니다. 직접 선택한 일정은 유지하고 이미 지난 날짜·시간은 계속 거부합니다. 월말 공유 준비 테스트도 미래 일정을 명확히 선택하도록 수정했습니다. 검증·배포 상태를 참조하세요.
웹과 Android에서 같은 지도 확대·이동·경유지 확인 동작을 전체화면에서도 지원합니다. 닫을 때 보던 지도와 코스를 유지하며, 공유 지도는 읽기 전용입니다. 공통 기능은 같은 서비스 버전과 업데이트 내역으로 함께 출시하는 SCOPE-003 규범을 따릅니다. 디자인·검증·배포 상태와 개발 구조 제안에 실제 진행 상태를 기록합니다.
웹과 Android는 지도에서 고른 좌표의 주소를 서버에서 확인한 뒤, 기존 장소 선택 화면의 명시 선택으로 경유지를 추가합니다. 지도 이동·확대·취소만으로 코스를 바꾸지 않으며, 추가 후 경로와 날씨를 다시 계산해야 합니다. 기존 회원·호출 한도와 장소 서명을 유지합니다. 공통 API 계약, 현재 검사·배포 상태와 산번지 날씨 조사를 참조하세요. 후보 구현과 실제 운영 배포는 구분합니다.
Node.js 24.x가 필요합니다. 로컬은 .nvmrc로 버전을 선택하고 GitHub CI도 같은 파일을 읽습니다. Vercel은 package.json의 engines.node를 우선 사용하며, 프로젝트 설정도 24.x로 맞춥니다. 빌드 로그 첫 부분의 실제 Node.js 버전으로 적용 여부를 확인합니다.
npm ci
npm run dev
실제 연결이 필요하면 .env.local을 직접 만들고 NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, NEXT_PUBLIC_KAKAO_MAP_JS_KEY만 넣습니다. 파일이나 값을 Git에 추가하지 않습니다. 외부 서비스 없이 화면만 확인하려면 환경변수를 비워 둔 채 실행하면 합성 위치와 합성 예보를 사용하는 데모 모드로 열립니다. 연결 환경에서도 실제 경로 계산 전에는 결과 영역에 예시 데이터가 표시되지만 지도 위에 지점 간 직선을 그리지 않습니다. 추천 경로가 안전하게 계산된 뒤에만 Kakao Mobility 도로 좌표를 사용한 선과 실제 경로 표시로 전환됩니다.
검증 명령은 다음과 같습니다.
npm run lint
npm run typecheck
npx --yes deno check supabase/functions/search-places/index.ts supabase/functions/plan-route/index.ts supabase/functions/weather-timeline/index.ts supabase/functions/save-collection/index.ts supabase/functions/kakao-oidc/index.ts supabase/functions/recommend-restaurants/index.ts
npm test
npx playwright install chromium
npm run test:e2e
npm run build
Playwright는 Chromium을 headless, worker 1개, 재시도 0회로 실행합니다. 기본 npm run test:e2e는 외부 API 키를 비운 프로덕션 빌드(next start)를 새 포트 서버로 띄워 PWA/service worker까지 확인하며, 기존 서버를 재사용하지 않습니다. 인증이 없는 로컬 실패 증거만 /tmp 아래에 남고 CI에서는 3일 동안 보존됩니다. npm run test:e2e:preview와 npm run test:e2e:auth는 정확한 develop Preview origin과 Preview Supabase project ref에만 결속되며, 다른 HTTPS 주소나 Production 주소를 거부합니다. 로그인 상태는 WSL/Linux의 저장소 밖 전용 0700 디렉터리와 0600 일반 파일에 원자적으로 저장하고 origin/project metadata와 함께 검증합니다. NTFS owner-only ACL을 이 도구로 증명할 수 없는 native Windows 인증 실행은 fail-closed입니다. 인증된 Preview 실행은 cookie·token 유출을 막기 위해 screenshot/trace/video를 저장하지 않습니다.
DB migration과 RLS/RPC는 실제 프로젝트와 분리된 로컬 Supabase PostgreSQL 17에서 검증합니다.
로컬 DB 초기화는 127.0.0.1:54322의 폐기 가능한 테스트 데이터만 삭제하므로, 대상을 확인하고 명시적으로 승인한 경우에만 수행합니다.
npx --yes [email protected] start --exclude gotrue,realtime,storage-api,imgproxy,kong,mailpit,postgrest,postgres-meta,studio,edge-runtime,logflare,vector,supavisor
npx --yes [email protected] test db --local supabase/tests/database/auth_rls_budget.test.sql supabase/tests/database/live_acl_readback.test.sql supabase/tests/database/plan_collection_share.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/collection_version_concurrency.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/invite_budget_concurrency.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/route_finalization_concurrency.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/recommended_route_concurrency.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/kakao_oidc_handoff.test.sql
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f supabase/tests/database/optional_meal_route.test.sql
supabase/migrations/의 migration을 순서대로 적용합니다.Allow users without an email을 켭니다. Kakao 앱에는 이메일을 등록하지 않고 OpenID Connect, 선택 동의 닉네임·프로필 사진, 프로젝트별 kakao-oidc/callback URI만 등록합니다.search-places, plan-route, weather-timeline, save-collection, recommend-restaurants, kakao-oidc Edge Function을 배포하고 서버 전용 비밀값을 Supabase Dashboard secret store에 등록합니다. kakao-oidc만 로그인 시작 전 공개 진입점이므로 verify_jwt=false이며 나머지 함수는 JWT 검증을 유지합니다.AUTH-007의 play-admission은 Google Play 설치 증명을 검증한 신규 Kakao 사용자만 일반 회원으로 등록합니다. 웹과 개발 앱은 기존 활성 회원만 로그인할 수 있으며, 미가입자에게 앱에서 먼저 가입하도록 안내합니다. 초대 가입·관리 화면과 클라이언트는 폐기하고 과거 초대 기록·회원 역할·회수 상태는 보존합니다. 프로젝트별 정확한 환경 flag·인증서·versionCode·검증 계정 및 JWT 검증을 유지합니다. 실제 배포와 Play 가입·기기 검증은 공동 출시 기록에서 구분하며, Play 가입 운영 절차를 따릅니다.
프로젝트별 데이터·비밀값·배포 경계와 현재 상태는 Preview/Production 운영 절차를 따릅니다.
이전 /admin/invites 주소는 홈으로 이동하고 /invite는 앱 가입 안내로 이동합니다. /api/invites/accept는 초대 사용을 처리하지 않습니다. 데이터베이스의 초대 발급·사용·회수 함수는 모든 앱 역할에서 호출을 거절하며, 이미 저장된 감사 기록은 삭제하지 않습니다.
Edge Function 배포 예시는 다음과 같습니다. 실제 프로젝트 연결과 비밀값 등록은 Supabase CLI 로그인 후 수행합니다.
supabase functions deploy search-places
supabase functions deploy plan-route
supabase functions deploy weather-timeline
supabase functions deploy save-collection
supabase functions deploy recommend-restaurants
supabase functions deploy kakao-oidc --no-verify-jwt
KAKAO_LOCAL_DAILY_LIMIT, KAKAO_CURRENT_DAILY_LIMIT, KAKAO_FUTURE_DAILY_LIMIT, KMA_DAILY_LIMIT도 반드시 양의 정수로 설정합니다. 비밀값이나 key는 명령 인자에 넣지 않습니다. 이 값은 비용을 보장하는 공급자 설정의 대체물이 아니므로 Kakao·기상청 콘솔에서도 유료 사용을 비활성화하고 더 낮은 쿼터를 사용해야 합니다.
COST-001 사용자 인터뷰를 다시 수행합니다.git diff --cached와 git grep으로 비밀값을 확인한 뒤에만 공개 저장소에 push합니다.더 자세한 신고·키 관리 기준은 SECURITY.md를 따릅니다.
develop: 기본 개발 브랜치입니다. 개발 변경과 통합은 이 브랜치에서 진행합니다.main: 운영 배포 브랜치입니다. 같은 저장소의 develop → main Pull Request만 허용합니다.develop과 main의 push 및 두 브랜치를 대상으로 하는 Pull Request에서 lint, TypeScript, Deno, 단위 테스트, 동일한 npm run test:e2e Chromium 검증, 프로덕션 빌드를 실행합니다.pull_request_target 기반의 별도 검사는 main 대상 PR의 출발 브랜치와 저장소 소유권을 검사합니다. PR 코드는 checkout하거나 실행하지 않습니다.main의 GitHub 보호 규칙은 Pull Request와 verify, develop-only 검사를 필수로 요구하며 직접 push, 강제 push, 삭제를 막습니다. 현재 라이선스는 정하지 않았으므로, 저장소가 공개되어 있어도 재사용 권한이 자동으로 부여되지는 않습니다.
vercel.json은 비용과 불필요한 배포를 줄이기 위해 develop과 main만 자동 배포 대상으로 허용합니다.
develop push: Vercel Authentication으로 보호된 Preview 배포, Preview 전용 Supabase 사용develop → main 병합: Production 배포Vercel CD는 저장소의 비밀값으로 CLI 토큰을 보관하는 방식 대신 Vercel 공식 GitHub 연동을 사용합니다. 최초 한 번 Vercel에서 tocomboy/motocast를 가져오고 Production Branch가 main인지 확인해야 합니다. Vercel에는 NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, NEXT_PUBLIC_KAKAO_MAP_JS_KEY만 환경별로 등록합니다. Kakao REST 키와 기상청 키는 프런트엔드가 아니라 Supabase Edge Function secrets에 둡니다.
커밋 전 확인:
git status --short
git diff --check
npm run lint && npm run typecheck && npm test && npm run test:e2e && npm run build
develop → main PR, Production 사용자 관점 검증