ブログ一覧へ戻る

前回の記事でAI駆動開発の手法を公開した。今回はそれを実践する。

1時間のスプリントサイクルで、ダッシュボード・データベース基盤・認証システムを一気に構築する。

Building in Public の真骨頂 — 進捗も失敗もリアルタイムで。

1. 1時間サイクルの設計

前回までの状態

まず、現時点で完成しているものを整理する。

足りないもの

プロダクトとして「使える」状態にするには、まだ大きなピースが欠けている。

これら全てを従来の開発プロセスで実装すると、最低でも2-3週間。しかし、AI駆動の1時間サイクルなら話が変わる。

サイクルの構造

1時間スプリントサイクル

分析5分
設計5分
並列実装35分
統合・テスト10分
デプロイ5分

なぜ1時間なのか。理由は2つある。

第一に、集中力の限界。人間が深い集中を維持できるのは60-90分が限界だ。1時間を1サイクルとすることで、集中力が切れる前に必ず成果物が生まれる。

第二に、フィードバックループの最短化。1時間ごとにデプロイ可能な状態にすることで、「作ったけど動かない」というリスクを最小化できる。動くものが手元にあれば、次のサイクルの方向修正も容易だ。

2. Cycle 1 の実装内容

今回のサイクルでは、3つのAIエージェントを並列に起動し、それぞれ独立したタスクを同時実行する。

3エージェント並列実行

Agent 1
ダッシュボード
Agent 2
DBスキーマ
Agent 3
デプロイ更新
AGENT 1

ダッシュボード構築

フロントエンドのメインUI。Single-page HTMLにSupabase JSクライアントとChart.jsを統合し、サーバーレスで動作するダッシュボードを構築する。

ポイントは「デモデータで動く」設計だ。DBスキーマが完成する前でも、UIの動作確認とデザインレビューができる。並列開発を可能にする鍵はこの疎結合な設計にある。

AGENT 2

Supabase DBスキーマ設計

PostgreSQLベースのデータベーススキーマ。Supabaseの認証・RLS機能をフル活用し、マルチテナント対応の堅牢なデータ基盤を構築する。

-- stores テーブル: 店舗情報の中核
CREATE TABLE stores (
  id          UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  owner_id    UUID REFERENCES auth.users(id) NOT NULL,
  name        TEXT NOT NULL,
  address     TEXT,
  timezone    TEXT DEFAULT 'Asia/Tokyo',
  created_at  TIMESTAMPTZ DEFAULT now(),
  updated_at  TIMESTAMPTZ DEFAULT now()
);

-- RLS: オーナーのみ自分の店舗にアクセス
ALTER TABLE stores ENABLE ROW LEVEL SECURITY;
CREATE POLICY "owner_access" ON stores
  USING (owner_id = auth.uid());

-- visitor_counts テーブル: 来客カウントの時系列データ
CREATE TABLE visitor_counts (
  id          UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  store_id    UUID REFERENCES stores(id) NOT NULL,
  camera_id   UUID REFERENCES cameras(id),
  count_in    INTEGER DEFAULT 0,
  count_out   INTEGER DEFAULT 0,
  counted_at  TIMESTAMPTZ DEFAULT now()
);

-- 時間帯別集計関数
CREATE FUNCTION hourly_counts(target_store UUID, target_date DATE)
RETURNS TABLE(hour INT, total_in BIGINT, total_out BIGINT) AS $$
  SELECT
    EXTRACT(HOUR FROM counted_at)::INT,
    SUM(count_in),
    SUM(count_out)
  FROM visitor_counts
  WHERE store_id = target_store
    AND counted_at::DATE = target_date
  GROUP BY 1 ORDER BY 1;
$$ LANGUAGE sql STABLE;

RLS (Row Level Security) がなぜ重要か。SaaSにおいて、あるユーザーが他のユーザーのデータにアクセスできてしまうのは致命的なセキュリティバグだ。SupabaseのRLSを使えば、データベースレベルでアクセス制御が強制される。アプリケーションコードにバグがあっても、データ漏洩は起きない。

AGENT 3

デプロイメント更新

既存のCI/CDパイプラインとDockerコンテナにダッシュボードを統合し、本番環境で即座にアクセス可能にする。

Agent 3の役割は地味だが極めて重要だ。Agent 1とAgent 2の成果物が「本番で動く」状態にするのはインフラの仕事であり、ここが遅れると全体が止まる。

3. 成果と数字

Cycle 1 の実行結果を定量的に振り返る。

3
並列エージェント
1時間
実装時間
6テーブル
+ RLS完備
5画面
ダッシュボード

具体的な成果を列挙する。

  1. /dashboard/ でログイン・ダッシュボード表示: メールアドレスとパスワードでサインアップ・ログインし、即座にダッシュボード画面が表示される
  2. Supabase PostgreSQLスキーマ完成: 6テーブル、3集計関数、2トリガーを含む本番レディなスキーマ
  3. RLSでマルチテナント対応: 全テーブルにRow Level Securityを適用。ユーザーは自分の店舗データのみ参照可能
  4. Chart.jsでリアルタイムチャート表示: 時間帯別来客数、日別推移、曜日比較の3種類のチャート
  5. モバイル対応レスポンシブUI: サイドバーがハンバーガーメニューに変化し、スマートフォンでも快適に操作可能

4. 次のサイクルで何をするか

Cycle 1 はダッシュボード・DB・認証の「ハコ」を作った。ここからは、ハコの中身を充実させていく。

Cycle 1
ダッシュボード・DB・認証 完了 -- 本記事の内容
Cycle 2
Rust API → Supabase接続(sqlx統合) 推論エンジンとDBを繋ぎ、カメラ映像から来客データを自動記録する
Cycle 3
LINE通知Bot実装 来客急増・不審行動・営業時間外の入室をリアルタイム通知
Cycle 4
Stripe決済統合 フリープラン → スタータープラン → プロプランの課金フロー
Cycle 5
クローズドベータテスト 実店舗での動作検証。実データによるチューニングとフィードバック収集

各サイクルは1時間を基本単位とする。5サイクル = 5時間で、プロダクトはMVPとして「使える」状態になる計算だ。

1時間あれば、プロダクトは1歩進む。100時間あれば、100歩。完璧を待つな、サイクルを回せ。

次回の記事では、Cycle 2 の実装記録を公開する。Rustの推論エンジンとSupabase PostgreSQLをsqlxで接続し、カメラ映像から来客データをリアルタイムでDBに書き込むパイプラインを構築する。

1時間スプリントで生まれたダッシュボードを体験しませんか?

ミセバンAIは、この記事で紹介したスプリントサイクルで開発されています。
既存の防犯カメラがAI店長に変わる、小規模店舗のための次世代AI分析。