feat(flutter): AI 코스 입력·만드는 중·결과 화면(8–10) 추가

백엔드 AI 코스 API(4–6단계)를 앱에서 쓸 수 있게 화면 8–10 을 붙였다(설계 ai-course §14 7단계).

- 기반: 첫 실행 때 만든 기기 ID 를 안전 저장소에 두고 X-Device-Id 로 보낸다(비로그인 하루 횟수 기준).
  앱 언어를 Accept-Language 로 보내 AI 문구 언어를 맞춘다
- 홈 'AI에게 코스 맡기기' → 입력(8): 문장을 1초 멈추면 조건을 해석해 줄마다 채우고 고칠 수 있다.
  서버와 같은 조건 규칙을 앱에서도 먼저 본다. 하루 횟수를 다 썼으면 만들지 않고 안내한다
- 만드는 중(9): 1.5초마다 진행을 조회한다. 나가면 취소하고(차감 없음), 만들던 생성 id 를 남겨
  앱을 다시 켜거나 AI_004 를 받으면 이어 본다
- 결과(10): 사실 값 · 경고 · 이동 · 바꾸기 후보(한 번에 한 곳, 횟수 안 듦) · 평가 · 다시 만들기(확인 뒤 차감) ·
  출처와 AI 생성 표시. 요청 칸과 다시 만들기는 이 기기에서 입력한 생성일 때만 보인다
- 디자인 캔버스와 맞춤: 결과의 코스 제목은 빼고 'AI 추천 코스'와 요약으로 시작한다(사용자 결정).
  마스코트 그림을 홈 · 입력 · 만드는 중 · 결과 · 횟수 소진에 넣었다
- 화면 전체를 못 불러왔을 때의 공통 오류 화면(그림 · 다시 시도 · 오류 코드와 추적 ID)을 만들어 만드는 중 화면에 쓴다

코스로 저장 · 지도 미리보기 · 홈의 비 소식 줄 · 횟수 소진의 로그인 버튼은 그 기능이 생기면 붙인다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 15:48:23 +09:00
parent 8e53974c3f
commit af1a0f26fc
44 changed files with 7864 additions and 19 deletions
+148 -1
View File
@@ -32,6 +32,8 @@
"homeEventsEmpty": "No shows or events nearby yet.",
"seeAll": "See all",
"retry": "Try again",
"errorCodeLine": "Error code {code}",
"errorCodeTraceLine": "Error code {code} · Trace ID {traceId}",
"loadFailed": "Couldn't load this.",
"eventKindFestival": "Festival",
"eventKindPerformance": "Performance",
@@ -140,5 +142,150 @@
"nearbyPlaces": "Good to go with",
"photoCredit": "Photo: {provider} · {license}",
"koglType1": "KOGL Type 1",
"koglType3": "KOGL Type 3"
"koglType3": "KOGL Type 3",
"aiHomeTitle": "Let AI plan your day",
"aiHomeBody": "Just tell us what you want — we check opening hours, distance and pet rules for you.",
"aiHomeQuota": "{count} a day, no sign-in needed",
"aiHomePlaceholder": "e.g. Saturday afternoon, cafés and a walk near Suseongmot with a friend",
"aiInputTitle": "Plan with AI",
"aiQuotaRemaining": "{count} left today",
"aiQuotaNone": "None left today",
"aiAskTitle": "What kind of day\ndo you want?",
"aiRequestHint": "When, who with, and what you'd like to do",
"aiExamplesTitle": "Try something like",
"aiExample1": "Café hopping in Apsan with a friend, then a walk until sunset",
"aiExample2": "A quiet solo day at downtown galleries, then dinner",
"aiConditionsTitle": "Details",
"aiConditionsAutoFilled": "Filled in from what you wrote. Tap to change.",
"aiConditionsEmpty": "Write a sentence and we'll fill in the date, time and group.",
"aiParsing": "Reading your request…",
"aiFieldArea": "Area",
"aiFieldDate": "Date",
"aiFieldTime": "Time",
"aiFieldParty": "People",
"aiFieldPet": "Pets",
"aiFieldMobility": "Getting around",
"aiAreaSheetTitle": "Where do you want to go?",
"aiPlaceNear": "Near {name}",
"aiPlaceNearUnknown": "Near the chosen place",
"aiPartyCount": "{count, plural, =1{1 person} other{{count} people}}",
"aiPartyDecrease": "Fewer people",
"aiPartyIncrease": "More people",
"aiPetNone": "No pets",
"aiPetSummary": "{count, plural, =1{1 {label}} other{{count} {label}s}}",
"aiPetSmallDog": "small dog",
"aiPetMediumDog": "medium dog",
"aiPetLargeDog": "large dog",
"aiPetDog": "dog",
"aiPetCat": "cat",
"aiPetOther": "pet",
"aiPetSheetTitle": "Who's coming along?",
"aiPetKindNone": "No pets",
"aiPetKindDog": "Dog",
"aiPetKindCat": "Cat",
"aiPetKindOther": "Other",
"aiPetSize": "Size",
"aiPetSizeUnknown": "Not sure",
"aiPetCount": "How many",
"aiPetCountDecrease": "Fewer pets",
"aiPetCountIncrease": "More pets",
"aiMobilityWalk": "Walk",
"aiMobilityTransit": "Transit",
"aiMobilityCar": "Car",
"aiIndoorIfRain": "Mostly indoors if it rains",
"aiRainChance": "{day}: {percent}% chance of rain",
"aiTimeSheetTitle": "From when to when?",
"aiTimeStart": "Start",
"aiTimeEnd": "End",
"aiTimeEarlier": "{label} 30 minutes earlier",
"aiTimeLater": "{label} 30 minutes later",
"aiDurationHours": "{hours, plural, =1{1 hour} other{{hours} hours}}",
"aiDurationHoursMinutes": "{hours} h {minutes} min",
"aiApply": "Apply",
"aiProblemPastDate": "That date has passed. Pick another date.",
"aiProblemDateOutOfRange": "You can plan up to 30 days ahead.",
"aiProblemInvalidTime": "Pick the time again.",
"aiProblemTooShort": "Make it at least 2 hours.",
"aiProblemTooLong": "Keep it within 12 hours.",
"aiProblemPastTime": "That time has already passed. Pick another time.",
"aiIssueUnsupportedArea": "Only Daegu is available for now. Pick an area in Daegu.",
"aiIssueUnknownPlace": "We couldn't find that place, so we used your base area.",
"aiIssuePastDate": "That date has passed. Pick another date.",
"aiIssueDateOutOfRange": "That's more than 30 days away. Pick another date.",
"aiIssueMultiDay": "We can only plan one day at a time. Pick a single date.",
"aiIssueTooShort": "That's shorter than 2 hours. Add more time.",
"aiIssuePastMidnight": "Pick a time that ends by midnight.",
"aiIssueUnclear": "Tell us a bit more about the day you want.",
"aiCreateNote": "We pick from public data and show why we chose each place.",
"aiCreate": "Plan my course",
"aiQuotaExhaustedHint": "Your count resets at midnight Korea time.",
"aiConfirm": "OK",
"aiPendingTitle": "You have a course in progress",
"aiPendingOpen": "View",
"aiLoadingTitle": "Planning your course",
"aiLoadingSubtitle": "This usually takes 10–20 seconds",
"aiProgressLabel": "Progress",
"aiStepSearching": "Looking for places nearby",
"aiStepFound": "Found {count} places nearby",
"aiStepFoundNear": "Found {count} places near {area}",
"aiStepFoundAt": "Found {count} places · {area}",
"aiStepFiltering": "Narrowing down to what fits",
"aiStepKept": "Narrowed down to {count} places that fit",
"aiStepKeptOpen": "Narrowed down to {count} places open on {day}",
"aiStepKeptOpenPet": "Narrowed down to {count} {pet}-friendly places open on {day}",
"aiKeptPetDog": "dog",
"aiKeptPetAny": "pet",
"aiStepPlanning": "Building a schedule around weather and travel",
"aiStepFinishing": "Writing up why we chose each place",
"aiCancel": "Cancel",
"aiClose": "Close",
"aiFailedTitle": "We couldn't plan this course",
"aiEditConditions": "Edit details",
"aiCanceledTitle": "Course planning canceled",
"aiResultHeading": "AI-planned course",
"aiStopTime": "{start}–{end} · {minutes} min",
"aiMinutes": "{minutes} min",
"aiResultRequestTitle": "Your request",
"aiResultIndoor": "Mostly indoors",
"aiStatStops": "Stops",
"aiStatStopsValue": "{count}",
"aiStatTotal": "Total time",
"aiStatTravelWalk": "Walking",
"aiStatTravelTransit": "Transit",
"aiStatTravelCar": "Driving",
"aiStatPet": "Pet-friendly",
"aiStatPetDog": "Dog-friendly",
"aiOrderTitle": "Your route",
"aiOrderTimes": "{start} start · {end} finish",
"aiHours": "Open {hours}",
"aiEventPeriod": "Runs {period}",
"aiWarnHoursUnknown": "No opening hours on record. Check before you go.",
"aiWarnEventTimeUnknown": "No event times on record. Check before you go.",
"aiWarnPetUnknown": "No pet info on record. Follow the on-site rules.",
"aiWarnEventLastDay": "This is the last day of the event.",
"aiLegWalk": "{minutes} min walk · {distance}",
"aiLegTransit": "About {minutes} min by transit · {distance}",
"aiLegCar": "About {minutes} min by car · {distance}",
"aiAlternatesTitle": "Swap in a different place",
"aiAlternatesBody": "Tap to swap a stop for one at the same time. One swap at a time, and it doesn't count toward your daily limit.",
"aiAlternateFor": "Instead of #{number} · {category}",
"aiAlternateRevert": "Put #{number} back",
"aiRatingTitle": "Do you like this course?",
"aiRatingLike": "Like",
"aiRatingDislike": "Not quite",
"aiRatingThanks": "Thanks for the feedback",
"aiGeneratedNote": "AI planned this course from public data. Check opening hours and pet rules again before you go.",
"aiRegenerate": "Plan again",
"aiRegenerateTitle": "Plan again?",
"aiRegenerateBody": "We'll pick different places with the same details. {count} left today.",
"aiRegenerateBodyNoCount": "We'll pick different places with the same details. This uses one of today's plans.",
"aiPlanStopRemoved": "{name} was left out: {cause}.",
"aiOneStop": "One stop",
"aiCauseClosed": "it's closed that day",
"aiCauseLastOrder": "last orders have passed",
"aiCauseWindow": "it doesn't fit the time",
"aiCauseLegTooLong": "it's too far from the next stop",
"aiCausePet": "pets aren't allowed",
"aiCauseOther": "it didn't fit the details",
"aiPlanIndoorUnmet": "Rain is forecast, but there weren't enough indoor places, so some stops are outdoors."
}
+424 -1
View File
@@ -50,6 +50,25 @@
"homeEventsEmpty": "근처에 예정된 공연·행사가 아직 없어요.",
"seeAll": "전체 보기",
"retry": "다시 시도",
"errorCodeLine": "오류 코드 {code}",
"@errorCodeLine": {
"placeholders": {
"code": {
"type": "String"
}
}
},
"errorCodeTraceLine": "오류 코드 {code} · 추적 ID {traceId}",
"@errorCodeTraceLine": {
"placeholders": {
"code": {
"type": "String"
},
"traceId": {
"type": "String"
}
}
},
"loadFailed": "불러오지 못했어요.",
"eventKindFestival": "축제",
"eventKindPerformance": "공연",
@@ -240,5 +259,409 @@
}
},
"koglType1": "공공누리 제1유형",
"koglType3": "공공누리 제3유형"
"koglType3": "공공누리 제3유형",
"aiHomeTitle": "AI에게 코스 맡기기",
"aiHomeBody": "조건만 말하면 영업시간·거리·반려동물 동반까지 확인해 짜 드려요",
"aiHomeQuota": "로그인 없이도 하루 {count}번",
"@aiHomeQuota": {
"description": "홈 AI 칸 — 비로그인 하루 횟수",
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiHomePlaceholder": "예) 토요일 오후, 친구랑 수성못 근처 카페랑 산책",
"aiInputTitle": "AI 코스 만들기",
"aiQuotaRemaining": "오늘 {count}번 더 만들 수 있어요",
"@aiQuotaRemaining": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiQuotaNone": "오늘 만들 수 있는 횟수를 다 썼어요",
"aiAskTitle": "어떤 하루를\n보내고 싶어요?",
"aiRequestHint": "언제, 누구와, 무엇을 하고 싶은지 적어 주세요",
"aiExamplesTitle": "이렇게 써 봐도 좋아요",
"aiExample1": "친구랑 앞산 카페 들렀다가 해 질 무렵까지 걷기",
"aiExample2": "혼자 조용히 도심 미술관 둘러보고 저녁 먹기",
"aiConditionsTitle": "조건",
"aiConditionsAutoFilled": "적은 내용에서 자동으로 채웠어요. 눌러서 고칠 수 있어요.",
"aiConditionsEmpty": "문장을 쓰면 날짜·시간·인원을 채워 드려요.",
"aiParsing": "적은 내용을 읽고 있어요",
"aiFieldArea": "지역",
"aiFieldDate": "날짜",
"aiFieldTime": "시간",
"aiFieldParty": "인원",
"aiFieldPet": "반려동물",
"aiFieldMobility": "장소 사이 이동",
"aiAreaSheetTitle": "어디서 보낼까요?",
"aiPlaceNear": "{name} 근처",
"@aiPlaceNear": {
"placeholders": {
"name": {
"type": "String"
}
}
},
"aiPlaceNearUnknown": "고른 장소 근처",
"aiPartyCount": "{count, plural, other{{count}명}}",
"@aiPartyCount": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiPartyDecrease": "인원 줄이기",
"aiPartyIncrease": "인원 늘리기",
"aiPetNone": "함께 안 가요",
"aiPetSummary": "{count, plural, other{{label} {count}마리}}",
"@aiPetSummary": {
"description": "반려동물 요약 — label 은 aiPetSmallDog 같은 이름",
"placeholders": {
"count": {
"type": "int"
},
"label": {
"type": "String"
}
}
},
"aiPetSmallDog": "소형견",
"aiPetMediumDog": "중형견",
"aiPetLargeDog": "대형견",
"aiPetDog": "강아지",
"aiPetCat": "고양이",
"aiPetOther": "반려동물",
"aiPetSheetTitle": "누구와 함께 가요?",
"aiPetKindNone": "함께 안 가요",
"aiPetKindDog": "강아지",
"aiPetKindCat": "고양이",
"aiPetKindOther": "다른 동물",
"aiPetSize": "크기",
"aiPetSizeUnknown": "잘 몰라요",
"aiPetCount": "마리 수",
"aiPetCountDecrease": "마리 수 줄이기",
"aiPetCountIncrease": "마리 수 늘리기",
"aiMobilityWalk": "걸어서",
"aiMobilityTransit": "대중교통",
"aiMobilityCar": "자동차",
"aiIndoorIfRain": "비가 오면 실내 위주로",
"aiRainChance": "{day} 비 {percent}%",
"@aiRainChance": {
"description": "그날 강수확률 — day 는 요일 이름",
"placeholders": {
"day": {
"type": "String"
},
"percent": {
"type": "int"
}
}
},
"aiTimeSheetTitle": "언제부터 언제까지?",
"aiTimeStart": "시작",
"aiTimeEnd": "끝",
"aiTimeEarlier": "{label} 30분 당기기",
"@aiTimeEarlier": {
"description": "시각 버튼의 화면 읽기 이름 — label 은 시작/끝",
"placeholders": {
"label": {
"type": "String"
}
}
},
"aiTimeLater": "{label} 30분 늦추기",
"@aiTimeLater": {
"placeholders": {
"label": {
"type": "String"
}
}
},
"aiDurationHours": "{hours, plural, other{{hours}시간}}",
"@aiDurationHours": {
"placeholders": {
"hours": {
"type": "int"
}
}
},
"aiDurationHoursMinutes": "{hours}시간 {minutes}분",
"@aiDurationHoursMinutes": {
"placeholders": {
"hours": {
"type": "int"
},
"minutes": {
"type": "int"
}
}
},
"aiApply": "적용",
"aiProblemPastDate": "지난 날짜예요. 날짜를 다시 골라 주세요.",
"aiProblemDateOutOfRange": "오늘부터 30일 안의 날짜만 만들 수 있어요.",
"aiProblemInvalidTime": "시간을 다시 골라 주세요.",
"aiProblemTooShort": "2시간 이상으로 골라 주세요.",
"aiProblemTooLong": "12시간 안으로 골라 주세요.",
"aiProblemPastTime": "이미 지난 시간이에요. 시간을 다시 골라 주세요.",
"aiIssueUnsupportedArea": "지금은 대구만 만들 수 있어요. 대구 안에서 골라 주세요.",
"aiIssueUnknownPlace": "말한 장소를 찾지 못해 기준 위치로 두었어요.",
"aiIssuePastDate": "지난 날짜라 날짜를 다시 골라 주세요.",
"aiIssueDateOutOfRange": "30일보다 먼 날짜라 날짜를 다시 골라 주세요.",
"aiIssueMultiDay": "하루 코스만 만들 수 있어요. 날짜 하루를 골라 주세요.",
"aiIssueTooShort": "2시간보다 짧아요. 시간을 늘려 주세요.",
"aiIssuePastMidnight": "자정을 넘기지 않게 시간을 골라 주세요.",
"aiIssueUnclear": "어떤 하루를 원하는지 조금 더 적어 주세요.",
"aiCreateNote": "공공데이터에 있는 곳 중에서 고르고, 고른 이유를 함께 보여 드려요",
"aiCreate": "코스 만들기",
"aiQuotaExhaustedHint": "횟수는 한국 시간 자정에 다시 채워져요.",
"aiConfirm": "확인",
"aiPendingTitle": "만들던 코스가 있어요",
"aiPendingOpen": "보기",
"aiLoadingTitle": "코스를 짜고 있어요",
"aiLoadingSubtitle": "보통 10~20초 걸려요",
"aiProgressLabel": "진행률",
"aiStepSearching": "근처에서 갈 만한 곳을 찾는 중",
"aiStepFound": "근처에서 {count}곳을 찾았어요",
"@aiStepFound": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiStepFoundNear": "{area} 근처에서 {count}곳을 찾았어요",
"@aiStepFoundNear": {
"description": "만드는 중 첫 줄 — area 는 동네 이름·현재 위치(장소 기준은 '○○ 근처'라 aiStepFoundAt)",
"placeholders": {
"area": {
"type": "String"
},
"count": {
"type": "int"
}
}
},
"aiStepFoundAt": "{area}에서 {count}곳을 찾았어요",
"@aiStepFoundAt": {
"placeholders": {
"area": {
"type": "String"
},
"count": {
"type": "int"
}
}
},
"aiStepFiltering": "조건에 맞는 곳을 추리는 중",
"aiStepKept": "조건에 맞는 {count}곳을 추렸어요",
"@aiStepKept": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiStepKeptOpen": "{day} 영업으로 {count}곳을 추렸어요",
"@aiStepKeptOpen": {
"placeholders": {
"day": {
"type": "String"
},
"count": {
"type": "int"
}
}
},
"aiStepKeptOpenPet": "{day} 영업·{pet} 동반으로 {count}곳을 추렸어요",
"@aiStepKeptOpenPet": {
"placeholders": {
"day": {
"type": "String"
},
"pet": {
"type": "String"
},
"count": {
"type": "int"
}
}
},
"aiKeptPetDog": "반려견",
"aiKeptPetAny": "반려동물",
"aiStepPlanning": "날씨와 동선에 맞춰 시간표를 짜는 중",
"aiStepFinishing": "고른 이유를 정리할게요",
"aiCancel": "취소",
"aiClose": "닫기",
"aiFailedTitle": "코스를 만들지 못했어요",
"aiEditConditions": "조건 수정",
"aiCanceledTitle": "코스 만들기를 취소했어요",
"aiResultHeading": "AI 추천 코스",
"aiStopTime": "{start}–{end} · {minutes}분",
"@aiStopTime": {
"description": "결과의 장소 시각 — 도착·떠남은 한국 시각 HH:mm",
"placeholders": {
"start": {
"type": "String"
},
"end": {
"type": "String"
},
"minutes": {
"type": "int"
}
}
},
"aiMinutes": "{minutes}분",
"@aiMinutes": {
"placeholders": {
"minutes": {
"type": "int"
}
}
},
"aiResultRequestTitle": "내가 요청한 코스",
"aiResultIndoor": "실내 위주",
"aiStatStops": "장소",
"aiStatStopsValue": "{count}곳",
"@aiStatStopsValue": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiStatTotal": "전체 일정",
"aiStatTravelWalk": "걸어서 이동",
"aiStatTravelTransit": "대중교통 이동",
"aiStatTravelCar": "차로 이동",
"aiStatPet": "반려동물 동반",
"aiStatPetDog": "반려견 동반",
"aiOrderTitle": "코스 순서",
"aiOrderTimes": "{start} 출발 · {end} 마침",
"@aiOrderTimes": {
"placeholders": {
"start": {
"type": "String"
},
"end": {
"type": "String"
}
}
},
"aiHours": "영업 {hours}",
"@aiHours": {
"placeholders": {
"hours": {
"type": "String"
}
}
},
"aiEventPeriod": "행사 기간 {period}",
"@aiEventPeriod": {
"placeholders": {
"period": {
"type": "String"
}
}
},
"aiWarnHoursUnknown": "영업시간 정보가 없어요. 방문 전에 확인하세요.",
"aiWarnEventTimeUnknown": "행사 시간 정보가 없어요. 방문 전에 확인하세요.",
"aiWarnPetUnknown": "반려동물 동반 정보가 없어요. 현장 안내를 따라 주세요.",
"aiWarnEventLastDay": "이날이 행사 마지막 날이에요.",
"aiLegWalk": "걸어서 {minutes}분 · {distance}",
"@aiLegWalk": {
"placeholders": {
"minutes": {
"type": "int"
},
"distance": {
"type": "String"
}
}
},
"aiLegTransit": "대중교통 약 {minutes}분 · {distance}",
"@aiLegTransit": {
"placeholders": {
"minutes": {
"type": "int"
},
"distance": {
"type": "String"
}
}
},
"aiLegCar": "차로 약 {minutes}분 · {distance}",
"@aiLegCar": {
"placeholders": {
"minutes": {
"type": "int"
},
"distance": {
"type": "String"
}
}
},
"aiAlternatesTitle": "이런 곳으로 바꿀 수도 있어요",
"aiAlternatesBody": "누르면 같은 시간대의 장소와 바꿔요. 한 번에 한 곳만 바꿀 수 있고, 하루 횟수에는 들지 않아요.",
"aiAlternateFor": "{number}번 대신 · {category}",
"@aiAlternateFor": {
"description": "바꾸기 후보 — number 는 코스 순서 번호(1부터), category 는 분류 이름",
"placeholders": {
"number": {
"type": "int"
},
"category": {
"type": "String"
}
}
},
"aiAlternateRevert": "{number}번 원래 장소로 되돌리기",
"@aiAlternateRevert": {
"placeholders": {
"number": {
"type": "int"
}
}
},
"aiRatingTitle": "이 코스, 마음에 드세요?",
"aiRatingLike": "좋아요",
"aiRatingDislike": "아쉬워요",
"aiRatingThanks": "의견 고마워요",
"aiGeneratedNote": "AI가 공공데이터를 바탕으로 만든 코스예요. 영업시간과 반려동물 동반 조건은 방문 전에 다시 확인하세요.",
"aiRegenerate": "다시 만들기",
"aiRegenerateTitle": "다시 만들까요?",
"aiRegenerateBody": "같은 조건으로 다른 곳을 골라 새 코스를 만들어요. 오늘 {count}번 남아요.",
"@aiRegenerateBody": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"aiRegenerateBodyNoCount": "같은 조건으로 다른 곳을 골라 새 코스를 만들어요. 하루 횟수가 1번 줄어요.",
"aiPlanStopRemoved": "{name}: {cause} 코스에서 뺐어요.",
"@aiPlanStopRemoved": {
"description": "앱이 뺀 장소 알림 — cause 는 aiCause* 문구",
"placeholders": {
"name": {
"type": "String"
},
"cause": {
"type": "String"
}
}
},
"aiOneStop": "한 곳",
"aiCauseClosed": "그날 영업하지 않아",
"aiCauseLastOrder": "마지막 주문 시간이 지나",
"aiCauseWindow": "그 시간에 머물 수 없어",
"aiCauseLegTooLong": "다음 장소와 너무 멀어",
"aiCausePet": "반려동물과 함께 갈 수 없어",
"aiCauseOther": "조건이 맞지 않아",
"aiPlanIndoorUnmet": "비 예보가 있지만 실내 장소가 모자라 실외도 넣었어요."
}