mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-31 14:43:35 +00:00
fix: address second round of code review feedback
Backend improvements: - Create shared validation utility for project name validation - Add asyncio.Lock to prevent concurrent _query_claude calls - Fix _create_features_bulk: use flush() for IDs, add rollback on error - Use unique temp settings file instead of overwriting .claude_settings.json - Remove exception details from error messages (security) Frontend improvements: - Memoize onError callback in ExpandProjectChat for stable dependencies - Add timeout to start() checkAndSend loop to prevent infinite retries - Add manuallyDisconnectedRef to prevent reconnection after explicit disconnect - Clear pending reconnect timeout in disconnect() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,6 @@ Allows adding multiple features to existing projects via natural language.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
@@ -23,6 +22,7 @@ from ..services.expand_chat_session import (
|
||||
list_expand_sessions,
|
||||
remove_expand_session,
|
||||
)
|
||||
from ..utils.validation import validate_project_name
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,9 +43,6 @@ def _get_project_path(project_name: str) -> Path:
|
||||
return get_project_path(project_name)
|
||||
|
||||
|
||||
def validate_project_name(name: str) -> bool:
|
||||
"""Validate project name to prevent path traversal."""
|
||||
return bool(re.match(r'^[a-zA-Z0-9_-]{1,50}$', name))
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -70,8 +67,7 @@ async def list_expand_sessions_endpoint():
|
||||
@router.get("/sessions/{project_name}", response_model=ExpandSessionStatus)
|
||||
async def get_expand_session_status(project_name: str):
|
||||
"""Get status of an expansion session."""
|
||||
if not validate_project_name(project_name):
|
||||
raise HTTPException(status_code=400, detail="Invalid project name")
|
||||
project_name = validate_project_name(project_name)
|
||||
|
||||
session = get_expand_session(project_name)
|
||||
if not session:
|
||||
@@ -89,8 +85,7 @@ async def get_expand_session_status(project_name: str):
|
||||
@router.delete("/sessions/{project_name}")
|
||||
async def cancel_expand_session(project_name: str):
|
||||
"""Cancel and remove an expansion session."""
|
||||
if not validate_project_name(project_name):
|
||||
raise HTTPException(status_code=400, detail="Invalid project name")
|
||||
project_name = validate_project_name(project_name)
|
||||
|
||||
session = get_expand_session(project_name)
|
||||
if not session:
|
||||
@@ -124,7 +119,9 @@ async def expand_project_websocket(websocket: WebSocket, project_name: str):
|
||||
- {"type": "error", "content": "..."} - Error message
|
||||
- {"type": "pong"} - Keep-alive pong
|
||||
"""
|
||||
if not validate_project_name(project_name):
|
||||
try:
|
||||
project_name = validate_project_name(project_name)
|
||||
except HTTPException:
|
||||
await websocket.close(code=4000, reason="Invalid project name")
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user