fix: code review fixes — date calc, input validation, rate limits, shared components
- Fix monthly_reset_at crash when billing anchor day exceeds next month's length
- Add environment_tags sanitization (max 20 tags, 100 chars each) to prevent prompt injection
- Add @limiter.limit("10/minute") rate limiting to all AI endpoints
- Use getTreeNavigatePath() routing helper instead of hardcoded paths
- Extract shared CreateFlowDropdown component from QuickStartPage and TreeLibraryPage
- Clear useCachedQuota on logout to prevent stale data across user sessions
- Add useRef guard to scaffold useEffect to prevent potential double-fire
- Use node.id as React key instead of array index in BranchDetailView
- Remove redundant dead logic in ai_tree_validator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,9 +11,11 @@ import logging
|
||||
from typing import Annotated
|
||||
|
||||
import anthropic
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.rate_limit import limiter
|
||||
|
||||
from app.api.deps import get_current_active_user, get_db, require_engineer_or_admin
|
||||
from app.core.config import settings
|
||||
from app.core.ai_conversation_store import (
|
||||
@@ -86,7 +88,9 @@ async def get_quota(
|
||||
|
||||
|
||||
@router.post("/start", response_model=AIStartResponse, status_code=201)
|
||||
@limiter.limit("10/minute")
|
||||
async def start_conversation(
|
||||
request: Request,
|
||||
data: AIStartRequest,
|
||||
current_user: Annotated[User, Depends(get_current_active_user)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
@@ -140,7 +144,9 @@ async def start_conversation(
|
||||
|
||||
|
||||
@router.post("/scaffold", response_model=AIScaffoldResponse)
|
||||
@limiter.limit("10/minute")
|
||||
async def scaffold(
|
||||
request: Request,
|
||||
data: AIScaffoldRequest,
|
||||
current_user: Annotated[User, Depends(get_current_active_user)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
@@ -249,7 +255,9 @@ async def scaffold(
|
||||
|
||||
|
||||
@router.post("/branch-detail", response_model=AIBranchDetailResponse)
|
||||
@limiter.limit("10/minute")
|
||||
async def branch_detail(
|
||||
request: Request,
|
||||
data: AIBranchDetailRequest,
|
||||
current_user: Annotated[User, Depends(get_current_active_user)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
@@ -364,7 +372,9 @@ async def branch_detail(
|
||||
|
||||
|
||||
@router.post("/assemble", response_model=AIAssembleResponse)
|
||||
@limiter.limit("10/minute")
|
||||
async def assemble(
|
||||
request: Request,
|
||||
data: AIAssembleRequest,
|
||||
current_user: Annotated[User, Depends(get_current_active_user)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
|
||||
Reference in New Issue
Block a user