本記事は ZOZO Advent Calendar 2025 シリーズ 2 の 21 日目の記事です。
概要
先日のLooker User Meetupで、@mashiike さんが「コーディングエージェントに独自Extension書かせてみた」という発表をされていました。
Looker Extensionは通常のReactアプリとは異なり、サンドボックス化されたiframe内で動作するため、AIに書かせるにも工夫が必要とのこと。この発表を聞いて「自分も何か作ってみたい」と思いました。
何を作ろうか考えた結果、ダッシュボードを複数人で見る時にファシリをルーレットで決めたいことあるよね!という安直な発想で、コーディングエージェント(Claude Code)と一緒にルーレットアプリを作ることにしました。
本記事では、開発の流れと、一番ハマった結果判定ロジックのバグ解消について紹介します。
デモ
早速、完成したルーレットをお見せします。
「ダンボー」と「フルくん」は誰やねん...?となりましたが、これはZOZOTOWNでおなじみのキャラクターとして生成AIが追加していました。選択肢は自由に編集できるので、実際に使う際はチームメンバーの名前などに変更できます。
開発の流れ
プロジェクト構成の生成
最初に「ルーレットアプリを作りたい」と伝えると、Claude Codeが以下のファイルを生成してくれました。
-
roulette-app/src/components/RouletteWheel.tsx- ルーレット本体 -
roulette-app/src/App.tsx- メインコンポーネント -
roulette-app/src/index.tsx- エントリーポイント -
roulette-app/src/index.css- CSSスタイル -
roulette-app/package.json- 依存関係 -
roulette-app/webpack.config.js- ビルド設定 -
roulette-app/tsconfig.json- TypeScript設定 -
manifest.lkmlへの追記
SVGで円弧を描画する部分、CSS transitionでアニメーションさせる部分など、基本的な実装はすべてコーディングエージェントが書いてくれました。
ハマったポイント:結果判定ロジック
ただし、一発で完璧に動いたわけではありません。
特に修正する必要があったのは結果判定のロジックでした。ルーレットが止まった後、「ポインターが指しているセグメントと表示される結果が一致しない」という問題が発生しました。例えば、ポインターが「フルくん」を指しているのに「ZOZO太郎」と表示されてしまいます。
問題の原因
最初のコードはこうでした。
const selectedIndex = Math.floor((totalRotation % 360) / segmentAngle);
これだと、ホイールの回転方向とポインターの位置関係が考慮されていません。
修正後のロジック
何度かやり取りを重ねて、以下のロジックに修正しました。
const segmentAngle = 360 / options.length;
const normalizedRotation = totalRotation % 360;
const pointerPosition = (360 - normalizedRotation + 360) % 360;
const selectedIndex = Math.floor(pointerPosition / segmentAngle) % options.length;
ポイントは 360 - normalizedRotation の部分です。
- ポインターは上(0度の位置)に固定
- ホイールが時計回りに回転
- ホイールが72度回転すると、ポインターから見ると反時計回りに72度移動したように見える
つまり、ホイールの回転方向を反転させる必要がありました。
Looker Extensionとしての設定
manifest.lkmlでダッシュボードタイルとして使えるように設定します。
application: roulette_app {
label: "Looker Roulette"
file: "roulette-app/dist/roulette_app.js"
mount_points: {
standalone: yes
dashboard_tile: yes
}
entitlements: {
local_storage: yes
}
}
dashboard_tile: yesを設定することで、ダッシュボードに埋め込むことができます。
まとめ
コーディングエージェントを使うことで、Looker Extensionの開発がかなり楽になりました。実際に1〜2時間ほどで作成することができました。SVGの描画やアニメーションなど、自分で一から書くと時間がかかる部分をお任せできます。
ただし、ロジックの細かい部分はやはり人間が検証する必要があります。今回の結果判定のように「動いているように見えて実は間違っている」パターンは、コーディングエージェントだけでは気づきにくいです。
Looker Extension特有の制約(サンドボックス化されたiframe)を理解した上で、AIと協力して開発するのが良いアプローチだと感じました。
