先日Antigravity CLIが発表されたので早速使ってみたいと思います。
ビジネスシーンでも使えるようにGoogle CloudのGemini Enterprise Agent Platformを使ってAntigravity CLIを利用しました。
Google Cloudのエンタープライズ向けデータプライバシー規約に基づき、やり取りをモデルの学習に利用されないため、ビジネスシーンでも安心して利用できます。
Google Cloudを使う方法は簡単です。
ログインしていない状態でAntigravity CLIを起動すると以下のようにログイン方法を問われます。
2を選択するとログイン用のURLが表示されるので、そのURLにアクセスしてGoogle Cloudにログインすれば準備完了です。
Google Cloudを利用してログインしている場合は、以下のように(Antigravity Business)と表示されます。
ビジネスシーンで利用する場合は、プロンプトを入力する前にこの表示を確認するとよさそうです。
Webアプリを設計・開発・デプロイするSkillsを作る
ふわっとした要望を伝えたら頑張ってプロダクトとして仕上げてくれるSkills等を用意します。
Antigravity CLIに以下のプロンプトで作ってもらいました。
Antigravity CLI用のskillsを作ってください。
Antigravity CLIのskillsに関しては[公式ドキュメント](https://antigravity.google/docs/cli-overview)を参考にしてください。
全てグローバルではなく、プロジェクトスコープで作成してください。
ユースケース: Next.jsベースのWEBアプリケーション開発。DBはPostgreSQLを利用。
skills:
- product-owner: 無茶ぶりのふわっとした要求事項を元にプロダクトの要件を具体化する役目を担う。指摘対応やバグ修正の方針に複数の選択肢が生じた場合、方針決定権を持つ。以下の成果物を作成する。
- プロダクト概要: 背景、プロダクトの価値、差別化要素などプロダクトの骨子を定義
- ユーザー一覧: プロダクトのユーザーを定義
- ユーザーストーリー: ユーザーがどのようにプロダクトを利用し、価値を享受するかを定義
- 主要エンティティ一覧: プロダクト中に現れる主要概念を定義
- 機能一覧: ユーザーに提供する機能を定義(適切に分類して表形式で表現)
- frontend-designer: [デジタル庁のデザインシステム](https://design.digital.go.jp/dads/)をベースにUIを設計し、以下の成果物を作成する。
- 画面遷移図: drawio.png形式で画面間の遷移を定義
- 画面一覧: 画面分母を定義し、各画面が何の機能を持つかをマッピング
- 画面レイアウト: drawio.png形式で画面の見た目を表現(画面ごとに作成)
- 画面項目定義: 画面が持つユーザ操作項目・動的項目の仕様を定義(画面ごとに作成)
- backend-designer: データ中心設計をベースにサーバーサイドで実装する機能を設計する。成果物は以下の通り。
- ER図: 主要エンティティ一覧と機能一覧を元に具体化したテーブル間のリレーションを定義
- テーブル一覧: 適切に分類し、テーブルの分母を定義
- DDL: 各テーブルの項目を定義
- データ仕様: テーブルの分類単位にデータライフサイクル(CRUD)におけるデータの変更内容を説明
- チェック一覧: データの登録・更新・削除時に行うチェック仕様を定義
- infrastructure-designer: Google CloudでCloud RunとCloud SQLを用いて構築するためのTerraformコードを作成する。コンテナイメージのパスは実行時に変数として受け取るようにする。
- security-reviewer: セキュリティの観点から設計書とソースコードをレビューする。[OWASP Top 10 2025](https://owasp.org/Top10/2025/)と[IPA 安全なウェブサイトの作り方](https://www.ipa.go.jp/security/vuln/websecurity/ug65p900000196e2-att/000017316.pdf)を参考に脆弱性を指摘する。指摘事項はMarkdown形式でファイルに書き込み、他のサブエージェントによる対応を未済管理できるようにする。
- maintainability-reviewer: SOLIDの原則をはじめとした保守性を高めるプラクティスの観点から、設計書とソースコードをレビューする。指摘事項はMarkdown形式でファイルに書き込み、他のサブエージェントによる対応を未済管理できるようにする。
- performance-reviewer: 性能(レイテンシおよびスループット)・リソース効率の観点から設計書・ソースコードをレビューする。指摘事項はMarkdown形式でファイルに書き込み、他のサブエージェントによる対応を未済管理できるようにする。
- test-planner: 設計書に基づいてvitestによるテストコードを作成する。テストコードは適切にグルーピングし、describeを用いてテスト観点が第三者に伝わるように作成する。
- developer: 設計書に基づいてNext.jsのソースコードを作成する。ソースコード修正時は必ず、ESLint・Prettier・vitestを実行し、指摘事項やテストNGがない状態にする。
- deployer: 完成したソースコードをCloud Buildでビルドし、terraformを用いてデプロイする。
- validator: Cloud Runにデプロイされたアプリケーションに対して、Playwright CLIを用いて疎通確認を行う。実施する疎通確認の内容はユーザーストーリーや画面遷移図に従う。
- inspector: Cloud LoggingからCloud Runのログを確認し、エラー原因を特定する。validatorによる疎通確認が失敗した場合のみ起動される。
開発の流れ:
1. product-ownerが要件を定める各種成果物を作成する。
2. backend-designerがバックエンドの各種設計書を作成する。
3. frontend-designerがフロントエンドの各種設計書を作成する。
4. 下記レビュアーが同時に設計書のレビューを進める。
- security-reviewer
- maintainability-reviewer
- performance-reviewer
5. product-ownerが指摘事項を確認し、相反する指摘があれば優先順位が低い方を対応不要とする。
6. backend-designerとfrontend-designerが指摘対応を行う。
7. test-plannerがテストコードを作成する。
8. developerがアプリケーションのソースコードを作成する。同時にinfrastructure-designerがTerraformコードを作成する。
9. 下記レビュアーが同時にソースコードのレビューを進める。
- security-reviewer
- maintainability-reviewer
- performance-reviewer
10. product-ownerが指摘事項を確認し、相反する指摘があれば優先順位が低い方を対応不要とする。
11. developerとinfrastructure-designerが指摘対応を行う。
12. deployerがアプリケーションをGoogle Cloudにデプロイする。
13. validatorがデプロイされたアプリケーションの疎通確認を行う。操作に成功したら開発を完了する。
14. validatorの疎通確認が失敗したらinspectorが調査を行い、結果をまとめて開発を一時終了する。
完成したskillsとAGENTS.mdはこちらです。
### 📂 作成したファイル構成
/workspace/
├── .agent/
│ └── skills/
│ ├── product-owner/
│ │ └── SKILL.md # 要件具体化、成果物の定義、方針決定権
│ ├── frontend-designer/
│ │ └── SKILL.md # DADS準拠UI設計、画面遷移図、モック、項目定義
│ ├── backend-designer/
│ │ └── SKILL.md # データ中心設計、ER図、PostgreSQL DDL、CRUD仕様
│ ├── infrastructure-designer/
│ │ └── SKILL.md # GCP (Cloud Run, Cloud SQL) 構築用のTerraform設計
│ ├── security-reviewer/
│ │ └── SKILL.md # OWASP Top 10/IPA準拠監査、未済管理(Markdown)
│ ├── maintainability-reviewer/
│ │ └── SKILL.md # SOLID原則/Next.js設計監査、未済管理(Markdown)
│ ├── performance-reviewer/
│ │ └── SKILL.md # DBインデックス/Next.js表示性能監査、未済管理(Markdown)
│ ├── test-planner/
│ │ └── SKILL.md # Vitestテスト設計、describeによる論理グルーピング
│ ├── developer/
│ │ └── SKILL.md # Next.js+PostgreSQL実装、ESLint/Prettier/Vitest必須実行
│ ├── deployer/
│ │ └── SKILL.md # Cloud Buildコンテナ化、Terraformデプロイ
│ ├── validator/
│ │ └── SKILL.md # PlaywrightによるE2E疎通検証、障害時のトリガー
│ └── inspector/
│ └── SKILL.md # Cloud Loggingエラー調査、トラブルシューティング報告
└── AGENTS.md # 全エージェント向けの共通連携フロー規約(ルートに配置)
各skillsは良が多いので割愛しますが、AGENTS.mdは生成された内容をそのまま共有します。
ここから生成されたAGENTS.mdです。
Project-Wide Agent Guidelines (AGENTS.md)
このドキュメントは、プロジェクト全体の開発フロー、エージェントの各ロール(スキル)の責務、およびフェーズごとの連携を定義した共通ガイドラインです。すべてのエージェント(サブエージェント)およびスキルは、このポリシーを最優先で遵守して動作します。
🗺️ 開発プロセス全体のワークフロー
本プロジェクトは、要件定義からインフラプロビジョニング、E2Eテストによる疎通確認、障害調査まで、14個のステップで構成される完全な協調フローを採用します。
👥 各ロール(スキル)の役割と成果物
| ロール(スキル名) | 責務概要 | 主な成果物と配置パス |
|---|---|---|
product-owner |
無茶ぶり要件を具体化し、方針決定権を持つ。 |
docs/requirements/ (概要、ストーリー、機能一覧など) |
frontend-designer |
デジタル庁デザインシステム(DADS)準拠の画面設計。 |
docs/designs/frontend/ (画面遷移図、レイアウト、項目定義) |
backend-designer |
データ中心設計に基づくDB・サーバーサイド機能設計。 |
docs/designs/backend/ (ER図、テーブル一覧、DDL、チェック一覧) |
infrastructure-designer |
Cloud Run / SQL を構築するセキュアな Terraform 開発。 |
terraform/ (main.tf, variables.tf など) |
security-reviewer |
OWASP Top 10 / IPA ガイドラインに準拠した監査。 |
docs/reviews/security_issues.md (未済管理) |
maintainability-reviewer |
SOLID原則 / クリーンアーキテクチャ規約に準拠した監査。 |
docs/reviews/maintainability_issues.md (未済管理) |
performance-reviewer |
データベースインデックス / Next.js の表示レイテンシ監査。 |
docs/reviews/performance_issues.md (未済管理) |
test-planner |
設計に準拠した論理的グルーピングの Vitest コード作成。 |
src/**/*.test.ts (テストコード) |
developer |
Next.js/PostgreSQL実装。ESLint, Prettier, Vitest必須実行。 |
src/ (アプリケーション本体コード) |
deployer |
Cloud Build でのビルドと Terraform でのデプロイ。 | デプロイログ、Cloud Run URL |
validator |
Playwright を用いたデプロイ済実環境への E2E 疎通確認。 |
tests/e2e/ (Playwrightテストコード、テスト結果) |
inspector |
validator失敗時の GCP ログ原因究明。 | docs/reviews/inspection_report.md |
⚙️ フェーズ間ガバナンスと協調のお約束
1. 意思決定プロセスと相反(コンフリクト)の解消
設計またはコードレビュー時、security, maintainability, performance の3つのレビュアーから、時として背反する(同時に満たすことが不可能な)指摘が上がる場合があります。
[!IMPORTANT]
相反する指摘があった場合、または開発コスト・インフラコストが著しく高い場合、product-ownerが優先順位の低い方の指摘を「対応不要」としてクローズする権利を持ちます。 デザイナーやデベロッパーは、POの決定に厳密に従ってください。
2. 未済管理(チケット・ステータス管理)の仕組み
すべてのレビュアー(security, maintainability, performance)は、指摘を個別のチャットで行うのではなく、指定されたマークダウン形式の管理票ファイル(docs/reviews/ 配下)に記述します。
- 指摘された担当者(
developerやbackend-designerなど)は、修正時にそのステータスを[ ] 未着手から[x] 完了(またはPO判断により対応不要)に更新し、修正結果やPO決定をその詳細セクションに記述します。 - すべての指摘事項が
完了または対応不要となるまで、次のフェーズ(デプロイやリリース)に進むことはできません。
3. ソースコード変更時のローカルバリデーション
developer がコードを作成、または指摘に基づいて修正した際は、手動デプロイやマージを行う前に、必ずローカルで以下のバリデーションを実行し、すべて成功していることを実証してください。
- フォーマッタ (Prettier)
- 静的解析 (ESLint)
- テスト (Vitest)
4. 異常検知と自動エスカレーション
validator が Playwright E2E テストで失敗を検出した場合、即座にプロセスを止め、inspector に依頼します。
-
inspectorは Cloud Logging の情報を引き出し、docs/reviews/inspection_report.mdを作成して現状を Blocked(障害中)とし、全体の開発サイクルを一度一時終了します。
[!TIP]
このプロジェクトは、最高水準の自動化、堅牢なセキュリティ、および高い保守性を両立した、プレミアムな開発環境を目指しています。各エージェントは自身の専門スキル(.agent/skills/以下)を最大限に活かし、チーム一丸となってこの高品質な開発フローを自律的に維持してください。
ここまでがAGENTS.mdです。
プレミアムな開発環境という表現を私は普段使わないのでちょっとニヤッとしてしまいました。
フローが私の意図する内容と若干違うのですが、今回は手直しせずそのまま開発を進めてみました。
ちなみに、私はバックエンドの設計を元にフロントエンドの設計をさせるつもりでした。
実際に使って簡単なアプリケーションを作ってみる。
「一人目の育児をする両親のために、おすすめの育児用品を紹介しあうレビューサイトを作って」と雑なお願いをしてみました。
※私は絶賛育児中なので、ちょうど思いついたのが上記の内容でした。
PRDの作成まで
私の雑な依頼を元にproject-ownerスキルを使って以下のドキュメントを作成してくれました。
./
├── docs/
└── requierments/
├── feature_list.md # 機能一覧
├── major_entities.md # 主要エンティティ一覧
├── product_overview.md # プロダクト概要
├── user_stories.md # ユーザーストーリー
└── users.md # ユーザー一覧
生成されたプロダクト概要とユーザーストーリーの一部を共有します。
# プロダクト概要 (Product Overview)
一人目の育児に直面する新米両親のための、リアルで信頼性の高い「おすすめ育児用品」レビュー・共有プラットフォーム。
## 背景 (Background)
初めての育児(一人目の育児)は、両親にとって未知の連続であり、多くの不安や疑問を伴います。世の中には膨大な育児用品が溢れていますが、「本当に必要なものは何か」「いつからいつまで使えるのか」「自分たちのライフスタイルに合うのか」を判断するのは非常に困難です。
一般的なECサイトのレビューはサクラや広告、一般的な評価が多く、新米両親の「一人目の、特定の月齢・ライフスタイル」に特化したリアルな体験談(「本当に買ってよかった」「これは不要だった」という本音)にたどり着くのが難しいという課題があります。
## プロダクトの価値 (Value Proposition)
1. **新米両親の不安解消と時間短縮**:
同じような境遇(子どもの月齢、住環境、ライフスタイル)の先輩パパ・ママが「一人目のときに本当に助けられた育児用品」をピンポイントで検索・比較でき、無駄な買い物を防ぐとともに、調べる時間を大幅に短縮できます。
2. **「おすすめの時期(対象月齢)」の明確化**:
育児用品は使用する時期が限られています。各レビューには「生後何ヶ月から何ヶ月まで使ったか」というリアルな使用期間や「おすすめの開始時期」が紐づいており、今買うべきかどうかが直感的にわかります。
3. **デジタル庁デザインシステム(DADS)準拠によるアクセシビリティ**:
育児で疲れ切った両親が片手(スマホ)で操作しても、迷わず、優しく、直感的に使えるアクセシブルで高品質なUIを提供します。
## 差別化要素 (Differentiators)
- **「一人目育児」への特化**:
二人目以降と異なり、「何もかもが初めて」の状態で、何が本当に役立つのかに焦点を当てています。
- **「役立った時期・使わなくなった時期」の可視化**:
単なる5つ星評価だけでなく、「いつ買って、いつまで活躍したか」の使用期間情報をレビューの必須・推奨項目とします。
- **押し売り広告の排除とコミュニティの信頼性**:
アフィリエイトや広告主体のキュレーションサイトとは異なり、一般のパパ・ママ同士が「これ本当に良かったよ!」と紹介し合う、温かく信頼できる相互扶助コミュニティを目指します。
# ユーザーストーリー (User Stories)
各アクターの視点から、プロダクトが提供する価値と受け入れ基準(Acceptance Criteria)を定義します。
## 1. 育児用品の検索・閲覧(ゲスト・一般ユーザー共通)
### US-1-1: カテゴリやフリーワードでの育児用品検索
- **ストーリー**:
- **ゲスト/一般ユーザー** として、**自分のニーズに合う育児用品をスムーズに見つける** ために、**カテゴリ分類やキーワードから育児用品を検索・一覧表示** したい。
- **受け入れ基準 (Acceptance Criteria)**:
- トップページまたは一覧ページに、育児用品の主要カテゴリ(例:授乳・離乳食、ねんね、おでかけ等)が表示されていること。
- カテゴリを選択すると、そのカテゴリに属する育児用品の一覧が、平均評価の高い順や投稿の新しい順などで表示されること。
- フリーワードによるあいまい検索(商品名や商品説明文の部分一致)ができること。
- 検索結果がない場合は、わかりやすいメッセージと、別のキーワードでの検索を促すUIが表示されること。
私の雑な依頼を元に具体化をしてくれていますね。
最初に受け入れ基準となるユーザーストーリーが生成されていることで、後続の設計・実装が安定しそうです。
設計書の作成まで
PRDの作成までで一旦Antigravity CLIの動きが止まったので、「続きをお願いします」とだけ指示して設計を進めてもらいました。
するとフロント・バック両方の設計とレビュー指摘対応まで一気に完了しました。
作成された設計書はこちらです。
./
└── docs/
└── designs/
├── backend/
│ ├── check_list.md # 入力値検証・整合性チェック一覧(Zodバリデーション仕様)
│ ├── data_spec.md # データ仕様(API・サーバーアクション処理仕様)
│ ├── ddl.sql # データベース物理定義(PostgreSQL DDLスキーマ)
│ ├── er_diagram.md # ER図(Mermaidによるデータベース構造関係図)
│ └── tables.md # テーブル一覧定義(論理・物理カラム定義)
└── frontend/
├── screen_list.md # 画面一覧(全画面ID・パス・概要の定義)
├── screen_transition.md # 画面遷移図(Mermaidによる画面遷移フロー定義)
└── specs/
├── scr_01_top.md # SCR-01 トップ画面設計書(レイアウト・検索項目定義)
├── scr_02_detail.md # SCR-02 用品詳細画面設計書(レイアウト・レビュー一覧項目定義)
├── scr_03_04_auth.md # SCR-03 ログイン/SCR-04 会員登録 画面設計書(フォーム項目定義)
├── scr_05_mypage.md # SCR-05 マイページ画面設計書(プロフィール・お気に入り・履歴項目定義)
└── scr_06_07_post.md # SCR-06 用品&レビュー同時登録/SCR-07 レビュー編集
画面レイアウトも作ってほしかったのですが、作られていないですね…
生成されたER図はこんな感じです。
結構それっぽい感じですね。
画面遷移図はこんな感じです。
線が重なってみずらいですが、こちらもそれっぽい感じがします。
レビュー結果は以下のように観点毎のMarkdownファイルが出力されました。
./
└── docs/
└── reviews/
├── maintainability_issues.md # 保守性・可読性レビュー指摘管理票(SOLID原則・Next.js規約)
├── performance_issues.md # 性能・リソース効率レビュー指摘管理票(N+1問題・表示遅延対策)
└── security_issues.md # セキュリティ脆弱性レビュー指摘管理票(BOLA対策・入力値検証等)
性能レビュー指摘の生成結果は以下の通りです。
# 性能レビュー指摘管理票
このファイルは、システムの性能、レスポンス速度、リソース効率の観点で検出された設計・コード・設定の課題と対応状況を管理します。
## 📊 指摘事項一覧
| ID | 指摘タイトル | 深刻度 | 該当領域 | ステータス | 発生箇所 | 担当者 |
| :---------- | :--------------------------------------------------- | :---------: | :----------------------------- | :--------- | :---------------------------------------------- | :---------------- |
| **PRF-001** | レビュー統計(平均星・レビュー数)の計算ボトルネック | 中 (Medium) | データベース (PostgreSQL) | [x] 完了 | `docs/designs/backend/data_spec.md#L20` | backend-designer |
| **PRF-002** | 育児用品一覧・検索時における N+1 クエリの予防 | 高 (High) | データベース (ORM/SQL) | [x] 完了 | `docs/designs/backend/data_spec.md#L17` | backend-designer |
| **PRF-003** | 育児用品・レビュー登録における画像最適化 | 中 (Medium) | フロントエンド (React/Next.js) | [x] 完了 | `docs/designs/frontend/specs/scr_06_07_post.md` | frontend-designer |
---
## 📝 指摘詳細
### [x] PRF-001: レビュー統計(平均星・レビュー数)の計算ボトルネック
- **発生箇所**: `docs/designs/backend/data_spec.md#L20`
- **問題内容**: 仕様書において「詳細取得時、紐づくレビューを同時(あるいは別途API)に読み込み、評価の平均値や総件数をメモリ上で(または SQL の AVG, COUNT で)集計して表示する」と記述されている。育児用品ごとのレビュー件数が少ない初期は問題ないが、件数が増加した場合、詳細表示時やトップページのカード一覧表示時に毎回全レビューレコードをスキャンして `AVG` / `COUNT` 計算を走らせると、DB負荷が極めて高くなり、APIレイテンシが増大する。
- **影響**: データベースCPU使用率、API応答速度(LCP劣化)
- **推奨される修正方針**:
- 短期(プロトタイプ段階): SQLで結合して一括集計、またはキャッシュ。
- 中長期(本番運用時): `items` テーブルに `average_rating` (NUMERIC) と `review_count` (INTEGER) の集計キャッシュ用カラムを追加。
- レビューの登録・更新・削除が発生するタイミング(レビューのCUD操作)で、対象商品の集計キャッシュカラムをトランザクション内で自動的に再計算・更新する(DBのトリガーまたは Prisma/Drizzle 内でのトランザクション処理)。これにより、参照時のクエリを単一テーブルの高速な `SELECT` に最適化できる。
- **対応結果・PO判断**: **[PO決定: 対応(短期/中長期の段階的対応)]** プロトタイプ開発である今回は、実装コストを抑えるため「効率的な SQL の LEFT JOIN と一括集計」を採用し、APIやServer Componentsでの N+1 を防ぎます。一方で、中長期の拡張性設計として、指摘の通り `items` への集計キャッシュカラムの追加および更新時の連動ロジック(トリガー/トランザクション)を「中長期改善ロードマップ」としてデータ仕様書に追記します。
### [x] PRF-002: 育児用品一覧・検索時における N+1 クエリの予防
- **発生箇所**: `docs/designs/backend/data_spec.md#L17`
- **問題内容**: トップページ(`SCR-01`)で用品一覧を読み込む際、各用品レコードに対して個別にレビュー平均点や最新レビュー1件などを個別に問い合わせるループ(N+1 クエリ)が発生しがちである。ORMを愚直に使うと、商品が20件あれば21回のクエリが走ってしまい、レスポンスが大きく遅延する。
- **影響**: ネットワーク往復遅延 (Round Trip Time), APIレイテンシ
- **推奨される修正方針**:
- 一覧表示時、`items` からのデータロードの際に `categories` および `reviews` を SQL の `LEFT JOIN` や ORM の Eager Loading (`relation` の include 一括読み込み) で1回のクエリに結合・取得する。
- これを可能にするために、ORMのクエリ構築ルールを規定・ドキュメント化する。
- **対応結果・PO判断**: **[PO決定: 対応必須]** 検索結果の応答速度は、離脱率に直結するため非常に重要です。ORMやRaw SQLのクエリ定義において、Eager Loading(一括JOINロード)を適用し、N+1クエリを発生させない実装規約をデータ仕様書に明記します。
### [x] PRF-003: 育児用品・レビュー登録における画像最適化
- **発生箇所**: `docs/designs/frontend/specs/scr_06_07_post.md`
- **問題内容**: 新米パパ・ママがスマホ(高解像度カメラ)で撮影した育児用品の画像をそのままアップロードすると、ファイルサイズが数MB〜10MBに及び、ストレージコストを圧迫するとともに、他ユーザーが閲覧する際(特にモバイル回線下)の読み込み速度が著しく低下する。
- **影響**: クライアント通信量、ストレージ容量・コスト、LCP(ページの最大コンテンツの描画)の劣化
- **推奨される修正方針**:
1. クライアント側のアップロードフォームにおいて、アップロード前に Canvas API 等を利用した画像の縮小(アスペクト比維持、最大幅1200px等へのリサイズ)や、圧縮処理を行う。
2. Next.js で商品画像を表示する箇所では、ブラウザ幅に最適化された画像サイズを自動配信・最適化(WebP/AVIF形式)する `<Image>` コンポーネント (`next/image`) を強制的に利用する。
- **対応結果・PO判断**: **[PO決定: 対応必須]** 育児中の両親はモバイル回線での閲覧(おでかけ時や寝かしつけ時など)が多いため、読み込み速度とパケット消費の配慮は必須です。フロントエンド of 画面項目定義において、Next.js `<Image>` の利用と、クライアント側での簡易的な圧縮/リサイズ(あるいはサーバーアップロード時のリサイズ)を行う設計を追記します。
よくある性能問題を設計時点で要考慮事項として挙げてくれていますね。
POによって対応可否判断が行われ、指摘対応として設計書の修正が行われたことも記載されている点がとても良いと思います。
実装完了まで
設計完了後、一度Antigravity CLIの動きが終了したので、今回も「続きをお願いします。」とだけ伝えて実装を進めてもらいました。
出来上がったファイルは以下の通りです。
./
└── src/
├── app/ # Next.js アプリケーションルーティング・プレゼンテーション層
│ ├── actions.ts # 共通サーバーアクション(新規登録・用品投稿・レビュー編集・削除等)
│ ├── auth/ # 認証(ログイン・会員登録)ルーティング
│ │ ├── login/
│ │ │ └── page.tsx # SCR-03 ログイン画面
│ │ └── register/
│ │ └── page.tsx # SCR-04 新規会員登録画面
│ ├── components/ # UIコンポーネント(共通および部分パーツ)
│ │ ├── DeleteReviewButton.tsx # レビュー削除を実行する非同期ボタン
│ │ ├── FavoriteButton.tsx # お気に入り(ブックマーク)登録/解除トグルボタン
│ │ ├── HeaderNav.tsx # ヘッダーメニュー(認証セッション状態・メニュー開閉制御)
│ │ ├── HeaderSearch.tsx # ヘッダーに配置された用品検索入力窓
│ │ ├── ItemReviewForm.tsx # SCR-06 用品情報&初発レビュー同時投稿フォーム
│ │ ├── MypageTabs.tsx # SCR-05 マイページ専用タブ(お気に入り/投稿履歴の切り替え)
│ │ └── ReviewForm.tsx # SCR-07 レビュー作成・編集フォーム
│ ├── favicon.ico # サイトファビコン
│ ├── globals.css #
グローバルスタイル(デジタル庁DADS準拠のカラー・タイポグラフィ・変数定義)
│ ├── items/ # 育児用品詳細・登録・編集ルーティング
│ │ ├── [id]/
│ │ │ ├── page.tsx # SCR-02 育児用品詳細画面
│ │ │ └── reviews/
│ │ │ └── [reviewId]/
│ │ │ └── edit/
│ │ │ └── page.tsx # SCR-07 レビュー編集画面
│ │ └── new/
│ │ └── page.tsx # SCR-06 用品&レビュー同時登録画面
│ ├── layout.tsx # アプリ共通レイアウト(デジタル庁DADS準拠のヘッダー・フッター内包)
│ ├── mypage/
│ │ └── page.tsx # SCR-05 マイページ画面(お子様情報・お気に入り一覧・投稿履歴)
│ └── page.tsx # SCR-01 トップ画面(用品一覧・カテゴリフィルタ・検索結果表示)
└── lib/ # ビジネスロジック・インフラ層・ドメイン共通ロジック
├── db.ts # prisma風のデータベースクライアントインターフェース(Mock/DB両対応)
├── mockData.ts # システム初期データ・およびシード用マスタデータ
├── services/ # 各種ドメインサービス(CRUD・バリデーション検証)および対応するテスト
│ ├── authService.ts # ログインセッション認証・Cookie制御サービス
│ ├── favoriteService.test.ts # お気に入りサービスの単体テスト
│ ├── favoriteService.ts # お気に入り関連ビジネスロジック(トグル登録、Eager Load一覧取得)
│ ├── itemService.test.ts # 用品サービスの単体テスト
│ ├── itemService.ts # 用品データ操作(N+1対策Eager Load一括取得、詳細取得)
│ ├── reviewService.test.ts # レビューサービスの単体テスト
│ ├── reviewService.ts # レビュー操作(BOLA所有者検証、二重投稿防止)
│ ├── userService.test.ts # ユーザーサービスの単体テスト
│ └── userService.ts # ユーザー登録(bcrypt強度10ハッシュ化、メール小文字統一)
└── validation/ # バリデーション検証スキーマ
├── schemas.test.ts # Zod スキーマの境界値・網羅性検証テスト(22ケース)
└── schemas.ts # Zod
テストコードはlib配下のバックエンドロジックしか作ってくれませんでした。
また、先にテストコードを書くように指示していたせいか、途中から追加されたファイルに対してはテストがありません。
ソースコードを見てみるとtsxはビューに専念しており、ロジックはactions.tsに切り出されていました。
これは、ソースコードがとても読みやすくて良いと思います。
スタイルに関しては、グローバルに定義されたCSSクラスとstyle要素にべた書きで作られていました。
style要素に直接CSSを記述すると冗長になるので、tsxのファイルが無駄に長くなってしまった点は残念です。
CSS Modulesを使って小さなスコープのCSSクラスを作ってもらえると私好みでした。
ここでもAGENTS.mdの定義通り、各種レビューが行われました。
各関連のレビュー記録表には指摘事項がない旨の記載が追記されました。
なお、実装時はlintやbuild, testを随時動かして問題があれば即時修正してくれていました。
これらの操作は時間がかかるためか、Antigravity CLIがバックグラウンドタスクとして動かしており、/tasksコマンドを実行することで各タスクの状態を確認できました。
E2Eテストまで
実装が完了するとまた一時終了したため、ここでも「続きをお願いします。」とだけ伝えて進めてもらいました。
するとdeployerスキルを使ってローカルPC上でNext.jsのプロダクションビルドを行い、アプリケーションを起動し始めました。
(あれ、deployerはGoogle Cloudにデプロイするスキルのはずでは…)
起動が完了すると、validatorスキルでPlaywrightのE2Eテストコードが生成され、一連の代表操作ができるまでバグを修正してくれました。
作成されたテストコードはこちらです。
import { test, expect } from "@playwright/test";
test.describe("いっぽめベビー プロダクト疎通確認 (E2E Smoke Test)", () => {
const baseUrl = process.env.BASE_URL || "http://localhost:3001";
test("ユーザー登録 -> 用品&レビュー同時登録 -> レビュー編集 -> マイページ確認 -> レビュー削除の一連の流れが正常に完了すること", async ({
page,
}) => {
test.setTimeout(60000);
// 1. トップページへアクセス
await page.goto(baseUrl);
await expect(page).toHaveTitle(/いっぽめベビー/);
// 2. 新規会員登録
// ヘッダーの登録リンクをクリック
await page.click("id=nav-register-link");
await expect(page).toHaveURL(new RegExp(`${baseUrl}/auth/register`));
const testEmail = `e2e-parent-${Math.random().toString(36).substring(2, 9)}@example.com`;
await page.fill("id=email", testEmail);
await page.fill("id=password", "MamaPapa2026!");
await page.fill("id=name", "新米パパE2E");
await page.fill("id=birthdate", "2026-01-15"); // 過去10ヶ月〜未来10ヶ月の範囲
await page.click("id=register-submit-btn");
// 登録完了後にトップページへ自動リダイレクトされることを確認
await expect(page).toHaveURL(baseUrl);
// ヘッダーにニックネームが表示されていることを確認
await expect(page.locator("id=user-menu-button")).toContainText(
"新米パパE2E",
);
// 3. 用品&レビュー同時登録 (SCR-06)
await page.click("id=nav-post-link");
await expect(page).toHaveURL(new RegExp(`${baseUrl}/items/new`));
const itemRandName = `E2Eテスト用哺乳瓶-${Math.random().toString(36).substring(2, 6)}`;
await page.fill("id=itemName", itemRandName);
await page.selectOption("id=categoryId", { label: "授乳・お食事" });
await page.fill("id=referencePrice", "1980");
await page.selectOption("id=recommendedStage", "neonatal"); // 新生児期 (生後0ヶ月)
await page.fill("id=title", "授乳が格段にスムーズになりました!");
await page.fill(
"id=pros",
"非常に使いやすく、赤ちゃんも全く嫌がらずに飲んでくれて大満足です。",
);
await page.fill(
"id=cons",
"少し洗うときにパーツが細かくて面倒ですが、許容範囲内です。",
);
await page.click("id=post-submit-btn");
// 登録完了後、用品詳細ページ (SCR-02) に遷移することを確認
await expect(page).toHaveURL(new RegExp(`${baseUrl}/items/item-`));
await expect(page.locator("h1")).toContainText(itemRandName);
// 詳細ページに自分の投稿したレビューがレンダリングされていることを確認
await expect(page.locator("body")).toContainText(
"授乳が格段にスムーズになりました!",
);
await expect(page.locator("body")).toContainText(
"非常に使いやすく、赤ちゃんも全く嫌がらずに飲んでくれて大満足です。",
);
// 4. レビュー編集・削除 (SCR-07)
// 自分のレビューカードに表示されている「編集する」リンクをクリック
await page.click("id=edit-review-link");
await expect(page).toHaveURL(
new RegExp(`${baseUrl}/items/item-.*/reviews/rev-.*/edit`),
);
// 編集画面で内容を更新
await page.fill("id=title", "【編集済】新生児期に最も役立った哺乳瓶です");
await page.fill(
"id=pros",
"【編集済】2週間使ってみて、明らかにミルクの飲みこぼしが減りました。本当におすすめ。",
);
await page.click("id=review-submit-btn");
// 更新完了後に詳細ページへ戻り、変更が反映されていることを確認
await expect(page).toHaveURL(new RegExp(`${baseUrl}/items/item-`));
await expect(page.locator("body")).toContainText(
"【編集済】新生児期に最も役立った哺乳瓶です",
);
await expect(page.locator("body")).toContainText(
"【編集済】2週間使ってみて、明らかにミルクの飲みこぼしが減りました。",
);
// 5. マイページ (SCR-05) での確認
await page.click("id=user-menu-button");
await page.click("id=nav-mypage-link");
await expect(page).toHaveURL(new RegExp(`${baseUrl}/mypage`));
await expect(page.locator("body")).toContainText("新米パパE2E");
await expect(page.locator("body")).toContainText("生後 4 ヶ月"); // 2026-01-15から現在時刻での自動月齢計算
// マイページの自分のレビュー履歴タブに該当レビューが表示されていることを確認
await page.click("id=tab-reviews");
await expect(page.locator("body")).toContainText(
"【編集済】新生児期に最も役立った哺乳瓶です",
);
// 6. マイページ上でのレビュー削除
// マイページのレビューカードにある「削除する」ボタンをクリック
page.on("dialog", async (dialog) => {
expect(dialog.message()).toContain("本当にこのレビューを削除しますか?");
await dialog.accept(); // confirm ダイアログを承認
});
await page.click("id=mypage-delete-review-btn");
// 削除後にマイページのリストから消去されることを確認
await expect(page.locator("body")).not.toContainText(
"【編集済】新生児期に最も役立った哺乳瓶です",
);
// 7. ログアウト
await page.click("id=user-menu-button");
await page.click("id=logout-button");
await expect(page).toHaveURL(baseUrl);
// ログアウト完了により、ヘッダーメニューがログイン/登録に戻っていることを確認
await expect(page.locator("body")).toContainText("ログイン");
});
});
概ね主要な導線を確認できていそうですね。
アプリケーション側のHTMLタグにidが付けられていることもあり、シンプルで読みやすいテストコードができています。
テストが通るようになったら、以下のように開発フローにおける現在の状況を報告してくれました。
(最高水準は言いすぎですね笑)
完成した画面
トップ画面はこんな感じです。
検索もできました。
新規登録からユーザー登録をしてみます。
パスワードが短いとバリデーションエラーになります。
エラーが発生すると入力項目が空になってしまうのはいまいちですね。
登録済みのメールアドレスを入れてみるとちゃんと重複エラーが出ました。
ユーザー登録が完了すると、ヘッダーにユーザー名が表示されログイン状態になったことがわかります。
用品詳細画面に遷移し、レビューが表示されている部分はこんな感じです。
レビューを投稿してみます。
ちゃんと反映されました。
自分の書いたレビューは編集や削除ができるようになっています。
このベビーカーをお気に入り登録してみました。
マイページに行くとお気に入り登録した商品が表示されました。
大分いい感じですね!
まとめ
本当はこの後Google Cloudにデプロイするステップもあるのですが、結構動かしたので課金も心配かつ記事の量的にも長くなったのでここまでにしました。
Antigravity CLIを使って開発フローの整備から、実際の開発までやってみました。
開発フローを整備したことで、雑なインプットでもうまく開発ができたのではないかと思います。
開発にかかった時間・金額は以下の通りです。
時間:1h17m
料金:3,472円
このスピード・出来栄えなら破格の安さですね。
Antigravity CLI + Gemini3.5 Flashはかなり早かったです。
ちょっと眺めている間にどんどん進捗していきました。
今回の雑な進め方でも思った以上にうまく開発が進みました。
さらに良くするためには以下を行うと効果がありそうに感じました。
- AGENT.mdの見直し(フローが意図通りでない部分を修正したり、人間によるレビュータイミングを明記したり…)
- Skillsの見直し(designerによる設計方法をより具体的に定めたり、reviewerの観点をより具体化したり、test-plannerの観点を具体化したり…)
- 適宜、生成物を人間がレビューし、フィードバックを伝える(せっかくPRDや設計書を書く形で段階を踏ませているので、フィードバックをすることでより良いものができそう)
Antigravity CLIはかなり使えると思いましたので、今後も利用していきたいと思います。















