Files
cvfs/apps/backend/fastapi/app/services/publication.py

70 lines
2.0 KiB
Python

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(Submission.version)
.join(CvVersion.document)
.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(CvVersion.document)
.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]