feat: Extract hardcoded configs to environment variables

- Add environment variable configuration for backend and frontend
- Backend: DB_POOL_SIZE, JWT_EXPIRE_HOURS, timeout configs, directory paths
- Frontend: VITE_API_BASE_URL, VITE_UPLOAD_TIMEOUT, Whisper configs
- Create deployment script (scripts/deploy-backend.sh)
- Create 1Panel deployment guide (docs/1panel-deployment.md)
- Update DEPLOYMENT.md with env var documentation
- Create README.md with project overview
- Remove obsolete PRD.md, SDD.md, TDD.md (replaced by OpenSpec)
- Keep CORS allow_origins=["*"] for Electron EXE distribution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-14 14:31:55 +08:00
parent 43c413c5ce
commit 01aee1fd0d
19 changed files with 1460 additions and 311 deletions

View File

@@ -13,10 +13,6 @@ from ..config import settings
from ..models import SummarizeRequest, SummarizeResponse, ActionItemCreate, TokenPayload
from .auth import get_current_user
# Supported audio formats
SUPPORTED_AUDIO_FORMATS = {".mp3", ".wav", ".m4a", ".webm", ".ogg", ".flac", ".aac"}
MAX_FILE_SIZE = 500 * 1024 * 1024 # 500MB
router = APIRouter()
@@ -45,7 +41,7 @@ async def summarize_transcript(
"response_mode": "blocking",
"user": current_user.email,
},
timeout=120.0, # Long timeout for LLM processing
timeout=settings.llm_timeout_seconds,
)
if response.status_code != 200:
@@ -135,10 +131,10 @@ async def transcribe_audio(
# Validate file extension
file_ext = os.path.splitext(file.filename or "")[1].lower()
if file_ext not in SUPPORTED_AUDIO_FORMATS:
if file_ext not in settings.supported_audio_formats_set:
raise HTTPException(
status_code=400,
detail=f"Unsupported audio format. Supported: {', '.join(SUPPORTED_AUDIO_FORMATS)}"
detail=f"Unsupported audio format. Supported: {settings.SUPPORTED_AUDIO_FORMATS}"
)
# Create temp directory for processing
@@ -151,10 +147,10 @@ async def transcribe_audio(
with open(temp_file_path, "wb") as f:
while chunk := await file.read(1024 * 1024): # 1MB chunks
file_size += len(chunk)
if file_size > MAX_FILE_SIZE:
if file_size > settings.MAX_FILE_SIZE:
raise HTTPException(
status_code=413,
detail=f"File too large. Maximum size: {MAX_FILE_SIZE // (1024*1024)}MB"
detail=f"File too large. Maximum size: {settings.MAX_FILE_SIZE // (1024*1024)}MB"
)
f.write(chunk)
@@ -245,18 +241,18 @@ async def transcribe_audio_stream(
# Validate file extension
file_ext = os.path.splitext(file.filename or "")[1].lower()
if file_ext not in SUPPORTED_AUDIO_FORMATS:
if file_ext not in settings.supported_audio_formats_set:
raise HTTPException(
status_code=400,
detail=f"Unsupported audio format. Supported: {', '.join(SUPPORTED_AUDIO_FORMATS)}"
detail=f"Unsupported audio format. Supported: {settings.SUPPORTED_AUDIO_FORMATS}"
)
# Read file into memory for streaming
file_content = await file.read()
if len(file_content) > MAX_FILE_SIZE:
if len(file_content) > settings.MAX_FILE_SIZE:
raise HTTPException(
status_code=413,
detail=f"File too large. Maximum size: {MAX_FILE_SIZE // (1024*1024)}MB"
detail=f"File too large. Maximum size: {settings.MAX_FILE_SIZE // (1024*1024)}MB"
)
async def generate_progress() -> AsyncGenerator[str, None]:
@@ -366,7 +362,7 @@ async def segment_audio_with_sidecar(audio_path: str, output_dir: str) -> dict:
# Send command and wait for response
stdout, stderr = await asyncio.wait_for(
process.communicate(input=f"{cmd_input}\n{{\"action\": \"quit\"}}\n".encode()),
timeout=600 # 10 minutes timeout for large files
timeout=settings.upload_timeout_seconds
)
# Parse response (skip status messages, find the segment result)
@@ -490,7 +486,7 @@ async def transcribe_chunk_with_dify(
}
]
},
timeout=300.0, # 5 minutes per chunk (increased for longer segments)
timeout=settings.dify_stt_timeout_seconds,
)
print(f"[Dify] Chat response: {response.status_code}")