[{"data":1,"prerenderedAt":506},["ShallowReactive",2],{"content-/oneworld-explorer-rtw-flight-planning":3,"all-pages-for-dir":486,"related-/oneworld-explorer-rtw-flight-planning":487,"og-image-/oneworld-explorer-rtw-flight-planning":505},{"id":4,"title":5,"body":6,"category":467,"concepts":468,"description":469,"extension":470,"meta":471,"navigation":472,"ogImage":468,"path":473,"project_name":474,"published":475,"publishedAt":476,"seo":477,"stem":478,"tags":479,"todo":468,"unpublished":475,"updatedAt":468,"__hash__":485},"pages/2026-07/2026-07-22/oneworld-explorer-rtw-flight-planning.md","ワンワールド世界一周航空券(oneworld Explorer)の旅行プラン8選とルール判定アプリを作った記録",{"type":7,"value":8,"toc":457},"minimark",[9,13,17,20,24,27,30,33,36,39,43,46,49,52,55,58,61,64,67,71,74,211,214,217,221,224,227,230,435,438,441,444,447,450,453],[10,11,5],"h1",{"id":12},"ワンワールド世界一周航空券oneworld-explorerの旅行プラン8選とルール判定アプリを作った記録",[14,15,16],"p",{},"きっかけは、ワンワールドの世界一周(RTW)航空券についての記事だった。ビジネスクラスよりわずかな差額でファーストクラスに乗れる、という触れ込みを材料に渡し、oneworld Explorer(大陸数ベースの世界一周運賃。距離ベースのoneworld Global Explorerとは別商品)の詳細ルールと他社の同種プレミアムクラス体験を調べてもらったうえで、既存の滞在ガイドと同じ構造で独立ページも作ってもらった。ここまでは順調だった。",[14,18,19],{},"「これ記事をまとめてくれただけなような気がするんですけど」と、localhost 4321番のページを開いたまま口にした。画面に並んでいるのはルール解説と他社比較で、自分がこの航空券をどう使うかという行程が一行もない。欲しかったのは要約ではなく、実際に使える具体的なプランだった。",[21,22,23],"h2",{"id":23},"旅行プランナー役のサブエージェントを5人走らせる",[14,25,26],{},"発注し直した。ビジネスクラス前提、3つでは足りないので5つ、予算は気にせず最適なルートを組んでほしい、と伝えた。出し方も決めた。5人のサブエージェントに旅行プランナー役を割り振り、それぞれ違うテーマ(ラウンジ&機材制覇/記念日ロマンティック/美食巡り/秘境・自然遺産/歴史・文化探訪)で具体的なルートを組ませ、oneworld Explorerの制約(大陸数・都市数・方向ルール)を守れているかとルート自体の満足度で評価させる、という進め方にした。",[14,28,29],{},"5案は完成順もバラバラに戻ってきた。プランA(5大陸6都市19日間、ラウンジの入場条件や改装スケジュールまで踏まえた行程)、プランC(リマ・ロサンゼルス・ドーハなど「今、美食シーンが最も注目される瞬間」を捉えた5大陸8都市27日間)、プランB(モルディブ→ドーハ→サントリーニ→南仏→フィレンツェ→パリ→NY→ハワイの4大陸12都市34日間)、プランE(6大陸14都市・16フライトという上限ぎりぎりの45日間)、最後にプランD(南極クルーズを含む)が届いた。",[21,31,32],{"id":32},"予算が抜けたまま出てきた",[14,34,35],{},"5案とも行程は細かいのに、金額が一つも書かれていなかった。「予算とかが書いてないと思うんですけど、ちゃんと予算もある程度現実的な金額で入れといて、全部」と頼み直した。oneworld Explorerのビジネスクラス基本運賃(3大陸65.6万円〜6大陸97.8万円、日本発1人あたり)を共通前提として渡し、航空券代・宿泊費・食事代・現地体験費を都市ごとに積み上げさせた。",[14,37,38],{},"戻ってきた総額(夫婦2名)は、プランAが約635万円、プランCが約910万円、プランBが約1,130万円、プランEが約696万円。南極クルーズを含むプランDが最も高額になった。",[21,40,42],{"id":41},"移動を減らせば安くなるわけではなかった","「移動を減らせば安くなる」わけではなかった",[14,44,45],{},"次に気になったのはコストの抑え方だった。移動を減らした方がいいのか、宿泊を伸ばした方が航空券代より安いのか、思いついたまま質問にぶつけてみた。",[14,47,48],{},"返ってきた答えは予想と少しずれていた。移動を減らすことはあまり効かない。効くのは大陸数を絞ること、ホテルのグレードを落とすこと、高額オプションを削ること、の3つだという。この結論を踏まえて、①3大陸に絞って航空券代を最小化する案、②同格ホテルでも都市選びだけで宿泊費を抑える案、③少数都市に長期滞在してアパートメントホテル+自炊で圧縮する案、の3プランを追加で作らせた。",[14,50,51],{},"長期滞在型のプランH(28日間)は1人あたり約177万円で、それまで最安だったプランAよりさらに4割強安くなった。同一ホテルブランドのまま都市選びだけで宿泊費を半額以下にするプランG(24日間)は約205万円。",[14,53,54],{},"コストバランス案を眺めながら、Airbnbや民泊についても言い添えた。現地のスーパーの近くでうまく物件が取れれば、ホテルほど高くつかずに自炊もできる。ただし台北のように自炊文化があまりない街では、結局は外食のほうが安いはずだとも思った。この視点はロングステイ型のプランHに注記として残してもらった。",[21,56,57],{"id":57},"料金体系を勘違いしたまま突き進んでいた",[14,59,60],{},"プランF(3大陸ライト紀行、8区間)について、oneworld Explorerを使わず個別に航空券を買った場合との比較を追加してもらった。ところが表示されたものを見て「あー違う違う違う」と言い直すことになった。個別購入との比較ではなく、oneworld Explorer自体をビジネスではなくエコノミーで買った場合の差額が知りたかった。バラバラにビジネスクラスの航空券を買う予定はそもそもない。型定義からデータ、テンプレートまで作り直してもらった。",[14,62,63],{},"修正後の表を見て、初めてoneworld Explorerにエコノミー区分があることを知った。しかもビジネスとエコノミーの差は656,300円÷335,000円で約1.96倍、ほぼ2倍にしかならない。個別購入ならビジネスはエコノミーの3〜5倍、長距離国際線だと10倍近いこともあるので、この「2倍」という価格差は破格に近い。夫婦2名で差額約64万円を払うだけで、19日間の全区間がフルフラットシートになる。エコノミーの座席は長距離だと体への負担が大きく、寿命を縮めかねないほどのストレスになるとも思っている。その負担を数字と並べて比べると、差額の見え方が変わった。",[14,65,66],{},"ただ、基本運賃だけの比較では足りなかった。335,000円は燃油サーチャージと空港税(目安19万円/人)を含まない基本運賃で、実際の支払総額はエコノミーで1人あたり約52.5万円になる。ここでもう一度「ごめん、比較するときちゃんとしてくれませんか?わかりづらいです」と言い直してもらい、基本運賃と諸税を分けた表に整理し直してもらった。",[21,68,70],{"id":69},"比較テーブルが読めないと気づく","比較テーブルが読めない、と気づく",[14,72,73],{},"一連の修正を重ねるうちに、ページの見出しは「モデルルート5選」から「モデルルート8選」に変わっていたが、8案それぞれの個別テーブルはページのあちこちに散らばったままだった。冒頭で全体像をつかめないと気づき、8案をまとめた一覧テーブルをヒーロー直後に追加してもらった。各行から詳細セクションへ飛べるようにして、初めて「一覧してから読む」順番に整った。当時わかっていた数字を並べると、こういう内訳になっている。",[75,76,77,96],"table",{},[78,79,80],"thead",{},[81,82,83,87,90,93],"tr",{},[84,85,86],"th",{},"プラン",[84,88,89],{},"コンセプト",[84,91,92],{},"1人あたり予算",[84,94,95],{},"日数",[97,98,99,114,128,142,156,170,183,197],"tbody",{},[81,100,101,105,108,111],{},[102,103,104],"td",{},"A",[102,106,107],{},"ラウンジ&機材制覇",[102,109,110],{},"約318万円",[102,112,113],{},"19日間",[81,115,116,119,122,125],{},[102,117,118],{},"B",[102,120,121],{},"記念日ロマンティック",[102,123,124],{},"約565万円",[102,126,127],{},"34日間",[81,129,130,133,136,139],{},[102,131,132],{},"C",[102,134,135],{},"美食巡り",[102,137,138],{},"約455万円",[102,140,141],{},"27日間",[81,143,144,147,150,153],{},[102,145,146],{},"D",[102,148,149],{},"秘境・自然遺産(南極クルーズ含む)",[102,151,152],{},"8案中最高額",[102,154,155],{},"—",[81,157,158,161,164,167],{},[102,159,160],{},"E",[102,162,163],{},"歴史・文化探訪",[102,165,166],{},"約348万円",[102,168,169],{},"45日間",[81,171,172,175,178,181],{},[102,173,174],{},"F",[102,176,177],{},"3大陸ライト紀行",[102,179,180],{},"エコノミー/ビジネス比較の起点",[102,182,155],{},[81,184,185,188,191,194],{},[102,186,187],{},"G",[102,189,190],{},"格安ハブ都市周遊",[102,192,193],{},"約205万円",[102,195,196],{},"24日間",[81,198,199,202,205,208],{},[102,200,201],{},"H",[102,203,204],{},"ロングステイ中級(Airbnb自炊)",[102,206,207],{},"約177万円",[102,209,210],{},"28日間",[14,212,213],{},"ここまでの変更をコミット・デプロイしてもらった。学習ゲートは今回スキップするよう指示した。GitHubへのpushでCloudflare Pagesの自動ビルドがトリガーされ、本番URLを自分で開いて表示を確認した。",[14,215,216],{},"この時点で計画書だけは書かせておき、続きは別のセッションに引き継ぐことにした。次に手を付けたのは、8案を作らせている間ずっと頭の中で数えていた大陸数・区間数・方向ルールを、自分の手で検証できる場所を作ることだった。",[21,218,220],{"id":219},"ルールシミュレーターアプリを入力フォームのバリデーションに例えて発注する","ルール・シミュレーターアプリを、入力フォームのバリデーションに例えて発注する",[14,222,223],{},"プラン作りと並行して、oneworld Explorerの複雑なルール(大陸数・区間数・方向ルール)を自分で検証できるシミュレーターアプリを新規実装してもらうことにした。型定義とバリデーションの純粋関数群、都市マスタ、コンポーネント一式を実装してもらい、既存の8プランを回帰テストとして通し、79件のテストが全て緑になったところで実機確認に進んだ。",[14,225,226],{},"本番ページを見て、直したい点にすぐ気づいた。判定結果を選択の後に表示する作りになっていたが、欲しかったのはそこではない。入力フォームで電話番号や住所にバリデーションを効かせて、提出ボタンを押せないようにする、あの感覚に近い。足りない項目にはアラートを出し、選びすぎている場合はそもそも選べないようにしてほしい。この例えをそのまま発注文にした。",[14,228,229],{},"サイトの既存デザイン原則ページを確認してもらい、制限コントロール・展開表示・データ整合性・建設的なエラー表示(C-43/C-44/C-39/A-55)の考え方に沿って、コンポーネントを「後から違反を表示する」方式から「そもそも無効な操作をさせない」方式へ書き直してもらった。都市を追加する前に仮の行程を計算し、上限を超える組み合わせだけボタンを無効化する形になっている。",[231,232,237],"pre",{"className":233,"code":234,"language":235,"meta":236,"style":236},"language-ts shiki shiki-themes vitesse-light vitesse-light","const addDisabledReason = (city: City): string => {\n  if (isSegmentCapReached.value) return `区間数の上限（${MAX_SEGMENT_COUNT}区間）に達しているため追加できません`\n  const preview = computeRouteStats(addStop(routeStops.value, city))\n  const capCheck = checkContinentalSegmentLimits(preview)\n  return capCheck.status === 'error' ? capCheck.message : ''\n}\n","ts","",[238,239,240,283,330,368,388,429],"code",{"__ignoreMap":236},[241,242,245,249,253,257,260,264,267,271,274,277,280],"span",{"class":243,"line":244},"line",1,[241,246,248],{"class":247},"stQ0i","const ",[241,250,252],{"class":251},"senZ8","addDisabledReason",[241,254,256],{"class":255},"shFtX"," =",[241,258,259],{"class":255}," (",[241,261,263],{"class":262},"s4oTP","city",[241,265,266],{"class":255},": ",[241,268,270],{"class":269},"sSkh3","City",[241,272,273],{"class":255},"):",[241,275,276],{"class":269}," string",[241,278,279],{"class":255}," =>",[241,281,282],{"class":255}," {\n",[241,284,286,290,292,295,298,301,304,307,311,315,318,321,324,327],{"class":243,"line":285},2,[241,287,289],{"class":288},"sHkkW","  if",[241,291,259],{"class":255},[241,293,294],{"class":262},"isSegmentCapReached",[241,296,297],{"class":255},".",[241,299,300],{"class":262},"value",[241,302,303],{"class":255},")",[241,305,306],{"class":288}," return",[241,308,310],{"class":309},"sMJiu"," `",[241,312,314],{"class":313},"sdGka","区間数の上限（",[241,316,317],{"class":288},"${",[241,319,320],{"class":313},"MAX_SEGMENT_COUNT",[241,322,323],{"class":288},"}",[241,325,326],{"class":313},"区間）に達しているため追加できません",[241,328,329],{"class":309},"`\n",[241,331,333,336,339,341,344,347,350,352,355,357,359,362,365],{"class":243,"line":332},3,[241,334,335],{"class":247},"  const ",[241,337,338],{"class":262},"preview",[241,340,256],{"class":255},[241,342,343],{"class":251}," computeRouteStats",[241,345,346],{"class":255},"(",[241,348,349],{"class":251},"addStop",[241,351,346],{"class":255},[241,353,354],{"class":262},"routeStops",[241,356,297],{"class":255},[241,358,300],{"class":262},[241,360,361],{"class":255},",",[241,363,364],{"class":262}," city",[241,366,367],{"class":255},"))\n",[241,369,371,373,376,378,381,383,385],{"class":243,"line":370},4,[241,372,335],{"class":247},[241,374,375],{"class":262},"capCheck",[241,377,256],{"class":255},[241,379,380],{"class":251}," checkContinentalSegmentLimits",[241,382,346],{"class":255},[241,384,338],{"class":262},[241,386,387],{"class":255},")\n",[241,389,391,394,397,399,402,405,408,411,413,416,418,420,423,426],{"class":243,"line":390},5,[241,392,393],{"class":288},"  return",[241,395,396],{"class":262}," capCheck",[241,398,297],{"class":255},[241,400,401],{"class":262},"status",[241,403,404],{"class":247}," === ",[241,406,407],{"class":309},"'",[241,409,410],{"class":313},"error",[241,412,407],{"class":309},[241,414,415],{"class":247}," ? ",[241,417,375],{"class":262},[241,419,297],{"class":255},[241,421,422],{"class":262},"message",[241,424,425],{"class":247}," : ",[241,427,428],{"class":309},"''\n",[241,430,432],{"class":243,"line":431},6,[241,433,434],{"class":255},"}\n",[14,436,437],{},"区間の上限に達した大陸のチップは選択肢から自動的に消え、他の大陸は影響を受けずに選べたままになる。書き直した後のテストは82件まで増えていて、全部通っていた。この挙動を実機で確かめて、「めちゃくちゃ使いやすくなった」と感じた。",[21,439,440],{"id":440},"ルール解説の独立記事ページを作る",[14,442,443],{},"シミュレーターが形になったところで、次に欲しくなったのはルールそのものの解説だった。5区間という数字を見ながら、このルールを一通り確認できるページが欲しいと思い、ビジネスクラス世界一周チケットをどう有効活用するかという観点で、独立した記事ページの執筆を頼んだ。",[14,445,446],{},"シミュレーターのルール定数をそのまま記事側にもインポートしてもらい、コード側の数値と記事の数値がずれないようにした。この過程で、運賃が3大陸から6大陸まで何段階に分かれるかの説明を、正しくは4段階なのに「6段階」と誤記していた箇所が見つかり、直してもらった。実機確認では黒い矩形が表示されて一瞬焦ったが、正体はブラウザ確認用ツールのフローティングバーで、ページ本体には問題がなかった。プランF・D・Bへのアンカーリンクが正しく機能することも確かめてから、この分も学習ゲートをスキップしたうえでコミット・デプロイしてもらった。",[21,448,449],{"id":449},"振り返り",[14,451,452],{},"一枚の要約記事から出発して、5つのプラン評価、予算積算、料金体系の勘違いの訂正、比較テーブルの作り直し、バリデーション付きのシミュレーターアプリ、独立したルール解説記事まで進んだ。ワンワールドのRTW航空券は、まだ実際に予約していない。8案のうちどれを選ぶかは、まだ決めていない。",[454,455,456],"style",{},"html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sSkh3, html code.shiki .sSkh3{--shiki-default:#2E8F82;--shiki-dark:#2E8F82}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":236,"searchDepth":285,"depth":285,"links":458},[459,460,461,462,463,464,465,466],{"id":23,"depth":285,"text":23},{"id":32,"depth":285,"text":32},{"id":41,"depth":285,"text":42},{"id":57,"depth":285,"text":57},{"id":69,"depth":285,"text":70},{"id":219,"depth":285,"text":220},{"id":440,"depth":285,"text":440},{"id":449,"depth":285,"text":449},"dev",null,"ワンワールドRTW航空券(oneworld Explorer)のプレミアムフライトプランをサブエージェント5人に競作させ、予算漏れと料金体系の勘違いを訂正しながら8選に整理し、区間バリデーション付きのルールシミュレーターと解説記事まで作った記録。","md",{},true,"/oneworld-explorer-rtw-flight-planning","family-trips",false,"2026-07-22T00:00:00.000Z",{"title":5,"description":469},"2026-07/2026-07-22/oneworld-explorer-rtw-flight-planning",[480,481,482,483,484],"旅行プラン","oneworld Explorer","世界一周航空券","UI設計","Claude Code","cg95x2avYV36U5ay1Z9hpPzH8cidJWfnOQj5iM9lVV8",[],[488,491,495,499,502],{"title":489,"path":490,"publishedAt":476},"しまなみ海道サイクリング旅行プランを地図とフォトギャラリーで作った記録","/shimanami-kaido-cycling-trip-plan",{"title":492,"path":493,"publishedAt":494},"UIモックファーストな実装計画のすすめ：AIとの協働開発で学んだこと","/ui-mock-first-planning","2026-01-23T00:00:00.000Z",{"title":496,"path":497,"publishedAt":498},"KUSANAGI SFTPへ1Password経由で接続した記録","/kusanagi-sftp-1password-connection-test","2026-07-23T00:00:00.000Z",{"title":500,"path":501,"publishedAt":476},"2026年7月22日の開発日記 - Micronの格上げニュースと、語源単語コンテンツに眠っていた画像の使い回しバグ","/2026-07-22-diary",{"title":503,"path":504,"publishedAt":476},"会計システムのBS/PL実装から年度繰越まで、Codexレビューで固めたPhase4・Phase5開発","/accounting-system-lab-phase4-5","https://log.eurekapu.com/og/blog/oneworld-explorer-rtw-flight-planning.png?v=2026-07-22T00%3A00%3A00.000Z&title=%E3%83%AF%E3%83%B3%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E4%B8%96%E7%95%8C%E4%B8%80%E5%91%A8%E8%88%AA%E7%A9%BA%E5%88%B8(oneworld%20Explorer)%E3%81%AE%E6%97%85%E8%A1%8C%E3%83%97%E3%83%A9%E3%83%B38%E9%81%B8%E3%81%A8%E3%83%AB%E3%83%BC%E3%83%AB%E5%88%A4%E5%AE%9A%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%9F%E8%A8%98%E9%8C%B2&author=Kei%20Komatsu&sig=a6e1c3b094e48450",1784786441886]