概要
リリース前会議で特定されたP1課題3件を対応しました。
| 対応内容 | 状態 |
|---|---|
| Tier別レート制限(インメモリ) | 完了 |
| フレーム入力バリデーション | 完了 |
| CORS本番ドメイン追加 | 完了 |
1. Tier別レート制限
以前は can_submit_frame() が常に true を返すスタブでした。今回、インメモリのトークンバケット方式でTier別レート制限を実装しました。
| Tier | 最小間隔 | 実効レート |
|---|---|---|
| Free | 10秒 | 0.1 fps |
| Starter | 2秒 | 0.5 fps |
| Pro | 500ms | 2 fps |
| Enterprise | 100ms | 10 fps |
実装アーキテクチャ
pub struct RateLimiter {
state: Arc<Mutex<HashMap<Uuid, Instant>>>,
}
impl RateLimiter {
pub async fn check(&self, store_id: &Uuid, tier: &str) -> bool {
let min_interval = min_interval_for_tier(tier);
let mut map = self.state.lock().await;
// 前回のフレーム送信からの経過時間を確認
if let Some(last) = map.get(store_id) {
if last.elapsed() < min_interval { return false; }
}
map.insert(*store_id, Instant::now());
true
}
}
レート制限超過時は 403 Forbidden を返し、エラーメッセージで待機を促します。
2. 入力バリデーション
フレーム受信エンドポイントに3つのバリデーションを追加:
camera_id: 空文字・128文字超を拒否jpeg_bytes: 空データを拒否jpeg_bytes: 10MB超を拒否
3. CORS本番ドメイン追加
CORS許可オリジンに本番ドメインを追加:
// Before: miseban-ai.fly.dev + localhost のみ
// After:
- https://misebanai.com ← NEW
- https://www.misebanai.com ← NEW
- https://miseban-ai.fly.dev
- http://localhost:3001
4. テスト結果
全13テスト合格。レート制限テスト3件を追加。
| テスト | 結果 |
|---|---|
test_rate_limiter_allows_first_request | PASS |
test_rate_limiter_blocks_rapid_requests | PASS |
test_rate_limiter_different_stores_independent | PASS |
| 既存テスト 10件 | ALL PASS |
P0/P1 課題ステータス
| 優先度 | 課題 | Sprint | 状態 |
|---|---|---|---|
| P0 | Stripe Webhook tier判定 | #12 | 完了 |
| P0 | Webhook署名検証 | #12 | 完了 |
| P1 | レート制限 | #13 | 完了 |
| P1 | 入力バリデーション | #13 | 完了 |
| P1 | CORS本番対応 | #13 | 完了 |
P0/P1課題が全て解消。ベータ公開の技術的要件を満たしました。残るP2課題(属性分析、ヒートマップ、データ保持ポリシー)はベータ運用中に順次対応予定。