前回の記事でAI駆動開発の手法を公開した。今回はそれを実践する。
1時間のスプリントサイクルで、ダッシュボード・データベース基盤・認証システムを一気に構築する。
Building in Public の真骨頂 — 進捗も失敗もリアルタイムで。
1. 1時間サイクルの設計
前回までの状態
まず、現時点で完成しているものを整理する。
- ランディングページ: デザイン・実装・デプロイ完了
- AI推論エンジン: Rust + ONNX Runtime で動作確認済み
- CI/CDパイプライン: GitHub Actions でテスト→ビルド→デプロイ自動化
- ブログ12本: 技術解説、会議録、戦略記事を公開済み
足りないもの
プロダクトとして「使える」状態にするには、まだ大きなピースが欠けている。
- データベース: 来客データ・店舗情報・ユーザー情報の永続化
- 認証システム: ログイン・サインアップ・セッション管理
- ダッシュボード: データを可視化するUI
- 決済システム: Stripe連携による課金
- LINE通知: リアルタイムアラート配信
これら全てを従来の開発プロセスで実装すると、最低でも2-3週間。しかし、AI駆動の1時間サイクルなら話が変わる。
サイクルの構造
1時間スプリントサイクル
なぜ1時間なのか。理由は2つある。
第一に、集中力の限界。人間が深い集中を維持できるのは60-90分が限界だ。1時間を1サイクルとすることで、集中力が切れる前に必ず成果物が生まれる。
第二に、フィードバックループの最短化。1時間ごとにデプロイ可能な状態にすることで、「作ったけど動かない」というリスクを最小化できる。動くものが手元にあれば、次のサイクルの方向修正も容易だ。
2. Cycle 1 の実装内容
今回のサイクルでは、3つのAIエージェントを並列に起動し、それぞれ独立したタスクを同時実行する。
3エージェント並列実行
ダッシュボード
DBスキーマ
デプロイ更新
ダッシュボード構築
フロントエンドのメインUI。Single-page HTMLにSupabase JSクライアントとChart.jsを統合し、サーバーレスで動作するダッシュボードを構築する。
- 技術スタック: Single-page HTML + Supabase JS SDK + Chart.js
- 認証: Supabase Authによるメール/パスワードログイン・サインアップ
- 画面構成: ログイン、来客数ダッシュボード、カメラ管理、レポート、設定の5画面
- データ設計: デモデータで動作確認 → 本番データに差し替え可能な抽象化レイヤー
- UIデザイン: ダークサイドバー + ホワイトコンテンツの2ペイン構成
ポイントは「デモデータで動く」設計だ。DBスキーマが完成する前でも、UIの動作確認とデザインレビューができる。並列開発を可能にする鍵はこの疎結合な設計にある。
Supabase DBスキーマ設計
PostgreSQLベースのデータベーススキーマ。Supabaseの認証・RLS機能をフル活用し、マルチテナント対応の堅牢なデータ基盤を構築する。
- 6テーブル: stores, cameras, visitor_counts, daily_reports, alerts, api_tokens
- RLS (Row Level Security): ユーザーは自分の店舗データのみアクセス可能
- 集計関数: hourly_counts, weekly_summary, daily_report_aggregation
- トリガー: updated_at自動更新、store_id自動補完
-- 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を使えば、データベースレベルでアクセス制御が強制される。アプリケーションコードにバグがあっても、データ漏洩は起きない。
デプロイメント更新
既存のCI/CDパイプラインとDockerコンテナにダッシュボードを統合し、本番環境で即座にアクセス可能にする。
- Dockerfile.web: ダッシュボードのHTMLファイルをコンテナに追加
- nginx.conf:
/dashboard/パスへのSPAルーティング設定 - LP更新: CTAボタンのリンク先をダッシュボードに変更
- 動作検証: ローカルDocker環境で全パスの疎通確認
Agent 3の役割は地味だが極めて重要だ。Agent 1とAgent 2の成果物が「本番で動く」状態にするのはインフラの仕事であり、ここが遅れると全体が止まる。
3. 成果と数字
Cycle 1 の実行結果を定量的に振り返る。
具体的な成果を列挙する。
/dashboard/でログイン・ダッシュボード表示: メールアドレスとパスワードでサインアップ・ログインし、即座にダッシュボード画面が表示される- Supabase PostgreSQLスキーマ完成: 6テーブル、3集計関数、2トリガーを含む本番レディなスキーマ
- RLSでマルチテナント対応: 全テーブルにRow Level Securityを適用。ユーザーは自分の店舗データのみ参照可能
- Chart.jsでリアルタイムチャート表示: 時間帯別来客数、日別推移、曜日比較の3種類のチャート
- モバイル対応レスポンシブUI: サイドバーがハンバーガーメニューに変化し、スマートフォンでも快適に操作可能
4. 次のサイクルで何をするか
Cycle 1 はダッシュボード・DB・認証の「ハコ」を作った。ここからは、ハコの中身を充実させていく。
各サイクルは1時間を基本単位とする。5サイクル = 5時間で、プロダクトはMVPとして「使える」状態になる計算だ。
1時間あれば、プロダクトは1歩進む。100時間あれば、100歩。完璧を待つな、サイクルを回せ。
次回の記事では、Cycle 2 の実装記録を公開する。Rustの推論エンジンとSupabase PostgreSQLをsqlxで接続し、カメラ映像から来客データをリアルタイムでDBに書き込むパイプラインを構築する。
1時間スプリントで生まれたダッシュボードを体験しませんか?
ミセバンAIは、この記事で紹介したスプリントサイクルで開発されています。
既存の防犯カメラがAI店長に変わる、小規模店舗のための次世代AI分析。