# #region preview_session_ops [C:3] [TYPE Module] [SEMANTICS preview, session, accept, get] # @BRIEF Preview session lifecycle operations: accept and query preview sessions. # @RELATION DEPENDS_ON -> [TranslationPreviewSession] # @RELATION DEPENDS_ON -> [TranslationPreviewRecord] # @RELATION DEPENDS_ON -> [preview_session_serializer] from typing import Any from sqlalchemy.orm import Session from ...models.translate import ( TranslationJob, TranslationPreviewRecord, TranslationPreviewSession, ) from .preview_session_serializer import ( apply_language_action, # noqa: F401 — re-export for preview_review.py apply_record_action, # noqa: F401 — re-export for preview_review.py serialize_preview_record as _serialize_preview_record, ) # #region accept_preview_session [C:2] [TYPE Function] [SEMANTICS preview, session, accept] # @BRIEF Mark a preview session as accepted, which gates full execution. # @SIDE_EFFECT DB writes on session status. def accept_preview_session(db: Session, job_id: str, _current_user: str | None = None) -> dict[str, Any]: """Mark a preview session as accepted and return the session data with records.""" session = ( db.query(TranslationPreviewSession) .filter(TranslationPreviewSession.job_id == job_id, TranslationPreviewSession.status == "ACTIVE") .order_by(TranslationPreviewSession.created_at.desc()) .first() ) if not session: raise ValueError(f"No active preview session for job '{job_id}'") session.status = "APPLIED" db.commit() db.refresh(session) records = ( db.query(TranslationPreviewRecord) .filter(TranslationPreviewRecord.session_id == session.id) .all() ) job = db.query(TranslationJob).filter(TranslationJob.id == job_id).first() target_languages = job.target_languages or [job.target_dialect or "en"] if job else ["en"] if not isinstance(target_languages, list): target_languages = [str(target_languages)] return { "id": session.id, "job_id": job_id, "status": "APPLIED", "created_by": session.created_by, "created_at": session.created_at.isoformat(), "expires_at": session.expires_at.isoformat() if session.expires_at else None, "target_languages": target_languages, "records": [_serialize_preview_record(r) for r in records], } # #endregion accept_preview_session # #region get_preview_session [C:2] [TYPE Function] [SEMANTICS preview, session, query] # @BRIEF Get the latest preview session for a job with its records. def get_preview_session(db: Session, job_id: str) -> dict[str, Any]: """Get the latest preview session for a job with its records.""" session = ( db.query(TranslationPreviewSession) .filter(TranslationPreviewSession.job_id == job_id) .order_by(TranslationPreviewSession.created_at.desc()) .first() ) if not session: raise ValueError(f"No preview session found for job '{job_id}'") records = ( db.query(TranslationPreviewRecord) .filter(TranslationPreviewRecord.session_id == session.id) .all() ) job = db.query(TranslationJob).filter(TranslationJob.id == job_id).first() target_languages = job.target_languages or [job.target_dialect or "en"] if job else ["en"] if not isinstance(target_languages, list): target_languages = [str(target_languages)] return { "id": session.id, "job_id": job_id, "status": session.status, "created_by": session.created_by, "created_at": session.created_at.isoformat(), "expires_at": session.expires_at.isoformat() if session.expires_at else None, "target_languages": target_languages, "records": [_serialize_preview_record(r) for r in records], } # #endregion get_preview_session # #endregion preview_session_ops