♻️ Clubs との突合を dojo2dojo.csv から global_club_id に切り替える - #42
Merged
Merged
Conversation
8 tasks
クラブ名を手で対応付ける dojo2dojo.csv (301 行) をやめ、coderdojo.jp の global_club_id で直接突き合わせる。CSV は削除した。 名前での突合には次の問題があった。 - 新しい Dojo を追加するたび CSV に 1 行足す運用が必要で、実際に漏れていた - Clubs 側で改名されると追従できない - 同名クラブが二重登録されていると、先に現れた方を拾ってしまう active な全エントリが global_club_id を持つことは coderdojo.jp 側の spec が 保証しているため、名前で救済する経路は置いていない。 ## 同じ入力データで新旧の出力を比較した結果 - 日本のマーカー 195 -> 202 件。地図から消えた Dojo は 0 件 - 増えた 7 件は CSV に行が無く漏れていたもの 播磨科学公園都市 / 八戸@吹上 / 川西 / 明石 / 吉祥寺 / 氷見@bigberries / 豊橋 - 流山・古河は約 0.1km 移動。Clubs 側の同名二重登録のうち、coderdojo.jp が 指定した UUID のクラブを選ぶようになったため ## あわせて整理したもの - tmp/unmatched_dojos.json と Slack 通知を追加。CSV が無くなった今、Clubs 側の 削除・ID 変更を検知できるのはこれだけになる - deploy_to_pages.yml のデータ取得に Japan 側の件数・UUID 数チェックを追加。 取得は成功したが中身が劣化した場合に、コミット済みデータへ復元させる - 突合の情報源が Japan DB 自体になり到達不能となったガードを削除 (#43) - 名前突合を前提にしたテスト・ドキュメントを更新
yasulab
force-pushed
the
use-global-club-id-for-matching
branch
from
August 29, 2026 15:42
a0fc229 to
5c2eade
Compare
## 一時エンドポイント /dojo2dojo.json を削除 `_data/dojo2dojo.json` をそのまま公開するページで、名寄せデータの比較用として 2025年12月に一時的に追加したもの (54b8547)。UUID 突合に切り替わり、名前の 対応付けを目視で比べる必要が無くなったため削除する。 このページを参照しているコード・リンクは無いことを確認済み。生成物である `_data/dojo2dojo.json` 自体は残る (テストが下限を検査している)。 ## 生成タスクの終了コードを見る `_plugins/build_hooks.rb` が `system()` の戻り値を捨てていたため、GeoJSON の 生成が失敗しても Jekyll のビルドは成功し、コミット済みの古い地図がそのまま 出荷されていた。突合を global_club_id に切り替えてこの生成への依存が上がった ので、静かに古いものを出すより止める方が安全になる。 わざと失敗させて、ビルドが停止することを確認した。 Command failed with status (1): [ruby _tasks/upsert_dojos_geojson.rb] _plugins/build_hooks.rb:13:in 'Kernel#system': Command failed with exit 1
## PR でテストが走っていなかった このリポジトリのワークフロー 5 つのうち、PR で起動するのは claude-review と dependabot だけで、どちらもテストを走らせていなかった。`bundle exec rake test` は deploy_to_pages.yml の中にあり、main への push 時にしか走らない。つまり テストが落ちるのはマージした後で、デプロイがブロックされる形になっていた。 突合を global_club_id に切り替えた PR #42 は、安全性の根拠を新しいテスト (tests/dojo_matching_test.rb の件数下限・UUID 検査) に置いている。その根拠が PR 上で一度も検証されない状態だった。 ## PR ではデプロイ手前まで走らせる `on:` に pull_request を足し、2 つのステップを PR ではスキップする。 - データ取得: コミット済みのデータだけでビルドすることで、PR の結果が外部 API の 状態で揺れなくなり、リポジトリの中身そのものを検証できる - API キー注入: デプロイしないので不要。fork からの PR には secrets が渡らない デプロイのステップは元から `github.ref == 'refs/heads/main'` で守られている。 pull_request イベントの github.ref は常に refs/pull/N/merge になるため、fork 側の ブランチ名が main でも一致しない。 fetch をスキップした時 steps.fetch.outcome は 'skipped' になるので、復元ステップ (`== 'failure'`) も正しくスキップされる。 ## ci.yml に改名 テストとデプロイの両方を持つ実態に名前を合わせる。あわせてジョブに表示名を付けた。 PR のチェック欄に「deploy」とだけ出るのは実態と違うため。 branch protection と ruleset がいずれも未設定であることを確認しており、 required check 名の互換問題は起きない。将来設定した後だと改名が破壊的変更に なるので、今のうちに直しておく。 README のバッジと CLAUDE.md の手動実行手順も追従させた。
前のコミットで「役目を終えた一時エンドポイント」として削除したが、これは
誤りだった。coderdojo.jp の doc/how_to_add_dojo.md が、新しい Dojo が地図に
出たかを確認する手順でこの URL を使っている。
curl -s https://map.coderdojo.jp/dojo2dojo.json | ruby -rjson -e '...'
削除前に参照を調べたが、map リポジトリ内しか見ておらず、coderdojo.jp 側を
見ていなかった。追加された経緯(名寄せデータの比較用)は確かに終わっている
ものの、その後この確認手順という別の用途が付いていた。
配信内容は突合の結果そのもので、global_club_id と突合先のクラブ名が分かる。
UUID 突合に切り替えた後もこの用途には合っているため、名前は変えずに残す。
何のためのファイルかを front matter のコメントに書いた(Jekyll のコメントは
出力に現れないので、配信される JSON は変わらない)。
dojo2dojo という名前は dojo2dojo.csv(Japan 登録名 ↔ Clubs 登録名の対応表)に
由来していた。CSV を消したので、この名前が指すものは存在しなくなった。
配信している中身は「地図に載った日本の Dojo 一覧」で、どの Clubs 上のクラブと
突合したかが分かる。dojos.geojson の隣に dojos.json が並ぶ形になる。
https://map.coderdojo.jp/dojos.json
日本の Dojo 202 件だけで、地図に出ている海外のクラブは含まない。名前からは
読み取れないため、ページの front matter に明記した。
生成物のファイル名 (_data/) も揃えた。
このエンドポイントは coderdojo.jp の doc/how_to_add_dojo.md が掲載後の反映確認で
参照している。旧 URL は残さないので、同 doc の URL を差し替える必要がある。
同 doc の「DojoMap への反映(暫定手順)」節は、CSV に 1 行足す手順そのもので
本 PR のマージで不要になるため、どのみち書き直しが要る。
Clubs 側の登録名をそのまま引用していたが、伝えたいのは「改名されると 追従できない」ことなので、変わった事実だけ書けば足りる。
yasulab
added a commit
to coderdojo-japan/coderdojo.jp
that referenced
this pull request
Aug 29, 2026
DojoMap が global_club_id (UUID) で突合するようになり、地図側で
dojo2dojo.csv に 1 行足す作業が不要になった。手順書がその作業を
指示したままだったので、現状に合わせる。
- 手順一覧から「マージ後、DojoMap への反映の 1 行を追加する」を削除
- 「DojoMap への反映(暫定手順)」節を、UUID 突合の説明に置き換え
- 反映のタイミング(翌朝 5:59 JST の日次 Actions)と即時実行の方法
- 確認 URL を /dojo2dojo.json から /dojos.json に差し替え
- 地図に出ない時の切り分け。Slack に通知が飛ぶのは
global_club_id が Clubs 上のクラブと一致しない場合だけで、
座標・ステータスの問題は Actions のログにしか出ない
あわせて、この変更で読み手が誤解しうる2箇所を直した。
- global_club_id は「省略可」と書いてあったが、休止・閉鎖していない
Dojo では必須になっている(spec が落ちる)。承認確認 URL が無い
場合の探し方も、実行できるコマンドと注意点を添えた。Clubs 上の
登録名は掲載名と大きく異なることがあり、掲載名では引けない
- フィールド表の is_active は実装と食い違っていた。db/dojos.yml に
is_active は 0 件で、lib/tasks/dojos.rake が読むのは
inactivated_at のみ。YAML に is_active: false と書いても効かない
cf. coderdojo-japan/map.coderdojo.jp#42
yasulab
added a commit
that referenced
this pull request
Aug 31, 2026
見直しで、実装に無いものを案内している記述が見つかった。 ## 存在しない cache_dojo_logos の案内 (6 箇所) ロゴの取り込みは #44 でやめ、coderdojo.jp から直接読み込む方式にした。 その際 CLAUDE.md と README を直しておらず、実行するとエラーになる コマンドを案内したままだった。 bundle exec rake cache_dojo_logos # このタスクは存在しない `_tasks/cache_dojo_logos.rb` も Rakefile のタスクも無い。ビルドフックが 実行するのは upsert_dojos_geojson と compact_geojson の 2 つだけ。 `images/dojos/*.webp` も同じ理由で残骸になっていた。 ## 実在しないスクリプト名 (3 箇所) get_dojos_from_earth.rb -> get_data_from_earth.rb get_dojos_from_japan.rb -> get_data_from_japan.rb get_events_from_japan.rb -> 存在しない (イベントは get_data_from_japan.rb が取得する) ## Slack 通知の対象が、スクリプトとワークフローで食い違っていた upsert_dojos_geojson.rb のコメントは「uuid_not_in_clubs だけが要対応」の ままだったが、#42 で no_uuid も通知対象にしている。no_uuid は coderdojo.jp 側の spec が防いでいるはずの状態で、出たら上流の保証が破れている。 club_excluded_by_status_or_coordinates を通知しない理由も併記した。 ## ステータスの説明が不正確だった 「座標が無いか活動中ではない」と書いていたが、PLANNING (準備中) も地図に 出すため「準備中・活動中のどちらでもない」が正しい。coderdojo.jp 側の 手順書は直していたが、こちらを直し忘れていた。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
coderdojo.jp の active な全エントリが
global_club_idを持つようになった(coderdojo.jp#1900)ので、Clubs DB との突合を名前照合から UUID 直結に切り替え、dojo2dojo.csv(301 行)を削除します。名前照合の何が問題だったか
dojo2dojo.csvへ 1 行足す運用が必要同じ入力データで新旧の出力を比較しました
「地図が変わらないこと」を確かめるため、同じ
_data/*.jsonに対して main のスクリプトと本 PR のスクリプトを走らせ、出力を突き合わせています。地図から消えた Dojo: 0 件
増えた 7 件(CSV に行が無く漏れていたもの)
名前が一致しないもの(
八戸@吹上⇔八戸@鮫)や表記ゆれ(Coderdojo⇔CoderDojo)が並んでいます。名前照合が構造的に取りこぼしていた分です。これで active な 202 エントリが全件地図に載ります(突合できなかったもの 0 件)。
座標が動いた 2 件(流山・古河)— いずれも約 0.1 km
Clubs 側に同名クラブが 2 件ずつ登録されており、main は「名前で先に見つかった方」を拾っていました。本 PR は coderdojo.jp が
global_club_idで指定した方を選びます。同じ町内での移動で、どちらを拾うかが Clubs API の返却順まかせでなくなった結果です。
名前で救済する経路は置きません
active な全エントリが
global_club_idを持つことは coderdojo.jp 側の spec が保証しており、UUID の無い Dojo が入るとあちらの CI が落ちます。こちらに手動のマッピングを残す理由がなくなりました。あわせて、名前照合を前提にしていた次のものを削除しています。
dojo2dojo.csvと_config.ymlの exclude 設定matched_by(どの経路で載ったかの記録)とその検査静かに壊れる経路を塞ぎます
名前照合には「壊れても縮退して生き延びる」性質がありました。
_data/dojos_japan.jsonが空でも、CSV とローカルのデータだけで日本のマーカーは出ていました(ロゴがデフォルトになるだけ)。UUID 直結にはその性質が無く、入力が空なら日本のマーカーは全滅します。海外分 1,100 件あまりは残るため、既存の GeoJSON 検査では検出できません。次の 4 つで塞ぎます。
scheduler_daily.ymlの件数ガードdeploy_to_pages.ymlの件数・UUID 数ガードtests/dojo_matching_test.rbdeploy_to_pages.ymlのガードを足した理由Earth 側には件数チェックがあるのに Japan 側には無く、挙動が割れていました。
rake testでデプロイ全体がブロック後者はこのステップが明記する目的(「Geolonia 障害時の緊急デプロイが外部 API の状態に左右されてはならない」)を破ります。劣化時は復元パスへ落とすようにしました。
global_club_id消失通知対象に
no_uuidを加えました当初は
uuid_not_in_clubsだけを通知し、「UUID が無い状態は新規追加直後にも起きるので通知しない」としていました。UUID 必須化でこの前提が逆転しています。 coderdojo.jp の spec が全 active に UUID を強制する今、no_uuidが出たら上流の保証が破れた信号なので、通知します。club_excluded_by_status_or_coordinates(Clubs 側で座標が消えた・活動中でなくなった)はこちらから直せないため、ログのみに留めます。検証
bundle exec rake test→ minitest 14 runs + 7 runs / 0 failures、HTML-Proofer 成功next if japan_dojo.nil?を外すと、日本の Dojo が海外用フォールバックで描画されテストが落ちることを実測deploy_to_pages.ymlのガードが発火することを実測(上表)ついでに整理したもの
dojo2dojo.csv前提の記述CLAUDE.mdのトラブルシューティング手順を UUID 突合のものに差し替え。deploy_to_pages.ymlのコメントも更新fetch_latest_data.shrake cache_dojo_logosを呼んでいた(#44 でロゴキャッシュを消した際の取り残し)/dojo2dojo.json→/dojos.jsondojo2dojoは CSV に由来する名前で、CSV を消すと指すものが無くなる。中身は「地図に載った日本の Dojo 一覧」なのでdojos.geojsonの隣にdojos.jsonが並ぶ形にした。日本の 202 件のみで海外は含まないため、その旨をページに明記している。_plugins/build_hooks.rbsystem()の終了コードを捨てていたため、GeoJSON の生成が失敗してもビルドは成功し、コミット済みの古い地図がそのまま出荷されていた。exception: trueを足して止める最後の 1 件は、わざと失敗させてビルドが停止することを確認しています。
PR でテストが走っていませんでした
作業中に気づいた別の問題です。ワークフロー 5 つのうち PR で起動するのは
claude-reviewとdependabotだけで、どちらもテストを走らせていませんでした。bundle exec rake testはdeploy_to_pages.ymlの中にあり、main への push 時にしか走りません。つまりテストが落ちるのはマージした後で、デプロイがブロックされる形です。本 PR は安全性の根拠を新しいテストに置いているのに、その根拠が PR 上で一度も検証されない構造でした。
on:にpull_requestを足し、次の 2 ステップを PR ではスキップします。github.ref == 'refs/heads/main'で守られているpull_requestイベントのgithub.refは常にrefs/pull/N/mergeになるため、fork 側のブランチ名がmainでもデプロイ条件には一致しません。また fork からの PR ではGITHUB_TOKENが read-only で secrets も渡らないため、仮に条件をすり抜けても push は失敗します。データ取得をスキップした時
steps.fetch.outcomeは'skipped'になるので、復元ステップ(== 'failure')も正しくスキップされます。ci.ymlに改名しましたテストとデプロイの両方を持つ実態に名前を合わせ、ジョブにも表示名を付けました(PR のチェック欄に
deployとだけ出るのは実態と違うため)。branch protection とルールセットがいずれも未設定であることを確認済みで、required check 名の互換問題は起きません。将来設定した後だと改名が破壊的変更になるため、今のうちに直しています。README のバッジと
CLAUDE.mdの手順も追従させました。なお、これで防げるのは「リポジトリの中身が原因でテストが落ちる」場合です。main への push 時は取得した実データでテストするため、「PR は green だがマージ後に外部データ起因で赤」は残ります(その場合は復元パスで縮退します)。
この PR に含めていないもの
連名道場の個別表示は含めません。西宮・梅田(2 箇所)と大田・邑南、他(7 箇所)は 1 エントリ 1 マーカーのままで、7 箇所が地図に出ない状態が続きます。これは本 PR で生じるものではなく、
counterの再設計と掲載名変更の確認を伴う別の話です。db/dojos.ymlの該当エントリがどのクラブを指すかは確定済みなので、分割の前提は整っています。マージ後にやること
coderdojo.jpのdoc/how_to_add_dojo.mdに、本 PR で不要・不正確になる記述があります。マージ後すぐに doc の PR を出す必要があります。dojo2dojo.csvに 1 行足す手順そのもの。doc 自身にも「UUID で突合するようになったら、この節は丸ごと削除してください」と書いてあるhttps://map.coderdojo.jp/dojo2dojo.jsonhttps://map.coderdojo.jp/dojos.jsonに差し替えglobal_club_idの「申請に「承認確認」URL が無い場合は省略してください」