AI駆動開発ハンズオン 演習E の題材です。レガシー風の Java コード(551行・9クラス)を移行し、Cloudflare Workers 上で実際に動かしています。このページの「移行後」の出力はすべて、いま この Worker が生成した実物です。
移行で最初に証明すべきは「速くなった」ではなく 「壊れていない」 です。Java版 Main.java と同じシナリオを実行し、出力を突き合わせます。
created: ORD-00001 total=12803 yen created: ORD-00002 total=5940 yen search 'ta' -> 2 orders ============================== MONTHLY ORDER REPORT 2026/08 ============================== orders : 2 canceled : 0 sales : 18743 yen ------------------------------ [sales by category] BOOK : 3800 yen DEVICE : 9000 yen FOOD : 5400 yen ------------------------------ [orders by customer] tamura : 1 tanaka : 1 ==============================
読み込み中…
Java側は Windows の JDK 21 で java com.example.orders.Main を実行して採取した出力です(ブラウザ内で Java は動かせないため記録値)。移行後は右側の GET /api/scenario?at=2026-08-13T06:30:00Z をこのページから呼んで取得しています。同じ判定は npm test でも自動実行されます。
Java版の OrderService.createOrder() がそのまま HTTP API になっています。税・割引・送料の計算順序は移行前と完全に同じです。
ここにレスポンスが表示されます
バリデーションを試すなら、数量を 99 にして在庫3個の「27インチモニタ」を選ぶと out of stock が返ります(Java版と同じ文言)。
機械的に置き換えられない箇所です。移行はこの判断の集まりであって、文法の変換作業ではありません。
| 論点 | 移行前(Java) | 移行後(TS) | そう判断した理由 |
|---|---|---|---|
| static な共有状態 | private static Map STORE | リクエストごとに new | Workers は分散実行で、どの isolate に載るか保証がない。static を素直に移すと在庫が増減して見える非決定な挙動になる。永続化するなら D1/KV へ外部化する。 |
| 時刻の取得 | new Date() を直接呼ぶ | 生成時刻を引数で注入 | Java版はテストから時刻を固定できなかった。注入可能にしたことで「同じ入力なら常に同じ出力」になり、レポートの差分比較ができるようになった。 |
| タイムゾーン | Calendar.getInstance() | JST(UTC+9) を明示 | JVM のデフォルトTZ依存だった。Workers は常に UTC なので、そのまま移すと毎月1日の 0:00〜8:59 JST に前月扱いになる時差バグが出る。 |
| Map の反復順序 | HashMap の keySet() | キーを明示的にソート | HashMap は反復順序を保証しない=レポートの出力順が「たまたま」だった。ソートして決定的にした(今回のデータでは Java版と同じ並びになる)。 |
| 改行コード | System.out.println | 常に LF を返す | println はプラットフォーム依存の改行を出す(Windows なら CRLF)。同じコードなのに OS で出力が変わっていた。HTTP レスポンスとして扱うため LF に統一。 |
いずれも Java版のコードを読まないと気付けないものです。AIに移行させる場合も、この判断を下してレビューするのは人間の仕事になります。
| エンドポイント | 説明 |
|---|---|
| GET /api/scenario | Main.java と同じシナリオを実行。?at= で時刻固定 |
| GET /api/products | 商品マスタ10件(ProductRepository.findAll) |
| POST /api/orders | 注文作成(OrderService.createOrder)。エラーは 400 |
| GET /api/health | 疎通確認 |