文件版本管理-初步优化

This commit is contained in:
Cheng Zhou
2026-01-14 11:35:37 +08:00
parent ef1e67218c
commit f9ef5c109f
46 changed files with 4603 additions and 30 deletions
+36
View File
@@ -0,0 +1,36 @@
import uuid
from typing import Sequence
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.acknowledgement import Acknowledgement, AcknowledgementType
async def create(db: AsyncSession, ack: Acknowledgement, *, commit: bool = True) -> Acknowledgement:
db.add(ack)
if commit:
await db.commit()
await db.refresh(ack)
return ack
async def get_existing(
db: AsyncSession,
distribution_id: uuid.UUID,
user_id: uuid.UUID,
ack_type: AcknowledgementType,
) -> Acknowledgement | None:
result = await db.execute(
select(Acknowledgement).where(
Acknowledgement.distribution_id == distribution_id,
Acknowledgement.user_id == user_id,
Acknowledgement.ack_type == ack_type,
)
)
return result.scalar_one_or_none()
async def list_by_distribution(db: AsyncSession, distribution_id: uuid.UUID) -> Sequence[Acknowledgement]:
result = await db.execute(select(Acknowledgement).where(Acknowledgement.distribution_id == distribution_id))
return result.scalars().all()
+25
View File
@@ -0,0 +1,25 @@
import uuid
from typing import Sequence
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.distribution import Distribution
async def create(db: AsyncSession, distribution: Distribution, *, commit: bool = True) -> Distribution:
db.add(distribution)
if commit:
await db.commit()
await db.refresh(distribution)
return distribution
async def list_by_version(db: AsyncSession, version_id: uuid.UUID) -> Sequence[Distribution]:
result = await db.execute(select(Distribution).where(Distribution.version_id == version_id))
return result.scalars().all()
async def get(db: AsyncSession, distribution_id: uuid.UUID) -> Distribution | None:
result = await db.execute(select(Distribution).where(Distribution.id == distribution_id))
return result.scalar_one_or_none()
+61
View File
@@ -0,0 +1,61 @@
import uuid
from typing import Sequence
from sqlalchemy import select, update as sa_update
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.document import Document
async def create(db: AsyncSession, doc: Document, *, commit: bool = True) -> Document:
db.add(doc)
if commit:
await db.commit()
await db.refresh(doc)
return doc
async def get(db: AsyncSession, document_id: uuid.UUID) -> Document | None:
result = await db.execute(select(Document).where(Document.id == document_id))
return result.scalar_one_or_none()
async def get_by_trial_doc_no(db: AsyncSession, trial_id: uuid.UUID, doc_no: str) -> Document | None:
result = await db.execute(select(Document).where(Document.trial_id == trial_id, Document.doc_no == doc_no))
return result.scalar_one_or_none()
async def list_documents(
db: AsyncSession,
*,
trial_id: uuid.UUID,
site_id: uuid.UUID | None = None,
doc_type: str | None = None,
status: str | None = None,
scope_type: str | None = None,
skip: int = 0,
limit: int = 100,
) -> Sequence[Document]:
stmt = select(Document).where(Document.trial_id == trial_id)
if scope_type:
stmt = stmt.where(Document.scope_type == scope_type)
if doc_type:
stmt = stmt.where(Document.doc_type == doc_type)
if status:
stmt = stmt.where(Document.status == status)
if site_id:
stmt = stmt.where(Document.site_id == site_id)
stmt = stmt.order_by(Document.updated_at.desc()).offset(skip).limit(limit)
result = await db.execute(stmt)
return result.scalars().all()
async def update(db: AsyncSession, document_id: uuid.UUID, values: dict, *, commit: bool = True) -> None:
if values:
await db.execute(
sa_update(Document)
.where(Document.id == document_id)
.values(**values)
)
if commit:
await db.commit()
+76
View File
@@ -0,0 +1,76 @@
import uuid
from typing import Sequence
from sqlalchemy import select, update as sa_update
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.document_version import DocumentVersion, DocumentVersionStatus
async def create(db: AsyncSession, version: DocumentVersion, *, commit: bool = True) -> DocumentVersion:
db.add(version)
if commit:
await db.commit()
await db.refresh(version)
return version
async def get(db: AsyncSession, version_id: uuid.UUID) -> DocumentVersion | None:
result = await db.execute(select(DocumentVersion).where(DocumentVersion.id == version_id))
return result.scalar_one_or_none()
async def get_by_document_version_no(
db: AsyncSession,
document_id: uuid.UUID,
version_no: str,
) -> DocumentVersion | None:
result = await db.execute(
select(DocumentVersion).where(
DocumentVersion.document_id == document_id,
DocumentVersion.version_no == version_no,
)
)
return result.scalar_one_or_none()
async def list_by_document(
db: AsyncSession,
document_id: uuid.UUID,
skip: int = 0,
limit: int = 200,
) -> Sequence[DocumentVersion]:
result = await db.execute(
select(DocumentVersion)
.where(DocumentVersion.document_id == document_id)
.order_by(DocumentVersion.created_at.desc())
.offset(skip)
.limit(limit)
)
return result.scalars().all()
async def list_pending_versions(db: AsyncSession, document_id: uuid.UUID) -> Sequence[DocumentVersion]:
result = await db.execute(
select(DocumentVersion).where(
DocumentVersion.document_id == document_id,
DocumentVersion.status.in_(
[
DocumentVersionStatus.SUBMITTED,
DocumentVersionStatus.APPROVED,
]
),
)
)
return result.scalars().all()
async def update(db: AsyncSession, version_id: uuid.UUID, values: dict, *, commit: bool = True) -> None:
if values:
await db.execute(
sa_update(DocumentVersion)
.where(DocumentVersion.id == version_id)
.values(**values)
)
if commit:
await db.commit()
+30
View File
@@ -0,0 +1,30 @@
import uuid
from typing import Sequence
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.version_workflow import VersionWorkflow
async def create(db: AsyncSession, workflow: VersionWorkflow, *, commit: bool = True) -> VersionWorkflow:
db.add(workflow)
if commit:
await db.commit()
await db.refresh(workflow)
return workflow
async def get(db: AsyncSession, workflow_id: uuid.UUID) -> VersionWorkflow | None:
result = await db.execute(select(VersionWorkflow).where(VersionWorkflow.id == workflow_id))
return result.scalar_one_or_none()
async def get_by_version(db: AsyncSession, version_id: uuid.UUID) -> VersionWorkflow | None:
result = await db.execute(select(VersionWorkflow).where(VersionWorkflow.version_id == version_id))
return result.scalar_one_or_none()
async def list_by_document(db: AsyncSession, document_id: uuid.UUID) -> Sequence[VersionWorkflow]:
result = await db.execute(select(VersionWorkflow).where(VersionWorkflow.document_id == document_id))
return result.scalars().all()
+11
View File
@@ -0,0 +1,11 @@
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.workflow_action import WorkflowAction
async def create(db: AsyncSession, action: WorkflowAction, *, commit: bool = True) -> WorkflowAction:
db.add(action)
if commit:
await db.commit()
await db.refresh(action)
return action
+26
View File
@@ -0,0 +1,26 @@
import uuid
from typing import Sequence
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.workflow_template import WorkflowTemplate
async def get(db: AsyncSession, template_id: uuid.UUID) -> WorkflowTemplate | None:
result = await db.execute(select(WorkflowTemplate).where(WorkflowTemplate.id == template_id))
return result.scalar_one_or_none()
async def list_active(db: AsyncSession, trial_id: uuid.UUID | None = None) -> Sequence[WorkflowTemplate]:
stmt = (
select(WorkflowTemplate)
.where(WorkflowTemplate.is_active.is_(True))
.options(selectinload(WorkflowTemplate.nodes))
)
if trial_id:
stmt = stmt.where(WorkflowTemplate.trial_id == trial_id)
result = await db.execute(stmt)
return result.scalars().all()