Update dependencies and enhance project structure. Upgraded Tailwind CSS to version 4.1.0, removed obsolete configuration files, and added a comprehensive CURRENT_STATE.md file detailing project features, architecture, and future plans. Improved history management in the backend with new response models and optimized API endpoints for better data handling.

This commit is contained in:
Jamie Pine
2026-01-25 02:54:31 -08:00
parent 01e3065692
commit ca3409ebef
14 changed files with 636 additions and 237 deletions
+31 -10
View File
@@ -10,8 +10,8 @@ from pathlib import Path
from sqlalchemy.orm import Session
from sqlalchemy import or_
from .models import GenerationRequest, GenerationResponse, HistoryQuery
from .database import Generation as DBGeneration
from .models import GenerationRequest, GenerationResponse, HistoryQuery, HistoryResponse, HistoryListResponse
from .database import Generation as DBGeneration, VoiceProfile as DBVoiceProfile
# Generations storage directory
@@ -85,7 +85,7 @@ async def get_generation(
async def list_generations(
query: HistoryQuery,
db: Session,
) -> Tuple[List[GenerationResponse], int]:
) -> HistoryListResponse:
"""
List generations with optional filters.
@@ -94,10 +94,16 @@ async def list_generations(
db: Database session
Returns:
Tuple of (generations, total_count)
HistoryListResponse with items and total count
"""
# Build base query
q = db.query(DBGeneration)
# Build base query with join to get profile name
q = db.query(
DBGeneration,
DBVoiceProfile.name.label('profile_name')
).join(
DBVoiceProfile,
DBGeneration.profile_id == DBVoiceProfile.id
)
# Apply profile filter
if query.profile_id:
@@ -118,11 +124,26 @@ async def list_generations(
q = q.offset(query.offset).limit(query.limit)
# Execute query
generations = q.all()
results = q.all()
return (
[GenerationResponse.model_validate(g) for g in generations],
total_count,
# Convert to HistoryResponse with profile_name
items = []
for generation, profile_name in results:
items.append(HistoryResponse(
id=generation.id,
profile_id=generation.profile_id,
profile_name=profile_name,
text=generation.text,
language=generation.language,
audio_path=generation.audio_path,
duration=generation.duration,
seed=generation.seed,
created_at=generation.created_at,
))
return HistoryListResponse(
items=items,
total=total_count,
)
+29 -8
View File
@@ -18,7 +18,7 @@ from pathlib import Path
import uuid
from . import database, models, profiles, history, tts, transcribe
from .database import get_db, init_db
from .database import get_db, init_db, Generation as DBGeneration, VoiceProfile as DBVoiceProfile
# Initialize database
init_db()
@@ -240,7 +240,7 @@ async def generate_speech(
# HISTORY ENDPOINTS
# ============================================
@app.get("/history", response_model=List[models.GenerationResponse])
@app.get("/history", response_model=models.HistoryListResponse)
async def list_history(
profile_id: Optional[str] = None,
search: Optional[str] = None,
@@ -255,20 +255,41 @@ async def list_history(
limit=limit,
offset=offset,
)
generations, total = await history.list_generations(query, db)
return generations
return await history.list_generations(query, db)
@app.get("/history/{generation_id}", response_model=models.GenerationResponse)
@app.get("/history/{generation_id}", response_model=models.HistoryResponse)
async def get_generation(
generation_id: str,
db: Session = Depends(get_db),
):
"""Get a generation by ID."""
generation = await history.get_generation(generation_id, db)
if not generation:
# Get generation with profile name
result = db.query(
DBGeneration,
DBVoiceProfile.name.label('profile_name')
).join(
DBVoiceProfile,
DBGeneration.profile_id == DBVoiceProfile.id
).filter(
DBGeneration.id == generation_id
).first()
if not result:
raise HTTPException(status_code=404, detail="Generation not found")
return generation
gen, profile_name = result
return models.HistoryResponse(
id=gen.id,
profile_id=gen.profile_id,
profile_name=profile_name,
text=gen.text,
language=gen.language,
audio_path=gen.audio_path,
duration=gen.duration,
seed=gen.seed,
created_at=gen.created_at,
)
@app.delete("/history/{generation_id}")
+22
View File
@@ -74,6 +74,28 @@ class HistoryQuery(BaseModel):
offset: int = Field(default=0, ge=0)
class HistoryResponse(BaseModel):
"""Response model for history entry (includes profile name)."""
id: str
profile_id: str
profile_name: str
text: str
language: str
audio_path: str
duration: float
seed: Optional[int]
created_at: datetime
class Config:
from_attributes = True
class HistoryListResponse(BaseModel):
"""Response model for history list."""
items: List[HistoryResponse]
total: int
class TranscriptionRequest(BaseModel):
"""Request model for audio transcription."""
language: Optional[str] = Field(None, pattern="^(en|zh)$")