from __future__ import annotations import re from datetime import datetime from uuid import uuid4 from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models import CvDocument, CvVersion, PublicAsset, Submission async def publish_version( session: AsyncSession, *, owner_id: str, version_id: str | None, submission_id: str | None, slug: str | None, ) -> PublicAsset | None: target_version: CvVersion | None = None target_submission: Submission | None = None if submission_id: stmt = ( select(Submission) .join(CvVersion) .join(CvDocument) .where(Submission.id == submission_id, CvDocument.owner_id == owner_id) ) result = await session.execute(stmt) target_submission = result.scalars().one_or_none() target_version = target_submission.version if target_submission else None elif version_id: stmt = ( select(CvVersion) .join(CvDocument) .where(CvVersion.id == version_id, CvDocument.owner_id == owner_id) ) result = await session.execute(stmt) target_version = result.scalars().one_or_none() else: return None if not target_version or not target_version.artifact_docx_key: return None resolved_slug = slugify(slug or target_version.version_label or "cv") if not resolved_slug: resolved_slug = f"cv-{uuid4().hex[:6]}" asset = PublicAsset( submission_id=target_submission.id if target_submission else None, version_id=target_version.id, slug=resolved_slug, artifact_key=target_version.artifact_docx_key, is_public=True, expires_at=None, ) session.add(asset) await session.commit() await session.refresh(asset) return asset def slugify(value: str) -> str: safe = re.sub(r"[^a-zA-Z0-9-]+", "-", value.strip().lower()) safe = re.sub(r"-+", "-", safe).strip("-") return safe[:120]