Prepare ERP source for Gitea deployment

This commit is contained in:
A R R R Associates
2026-06-20 15:01:44 +05:30
commit 5c75eb6bd9
450 changed files with 67698 additions and 0 deletions
+360
View File
@@ -0,0 +1,360 @@
from __future__ import annotations
from datetime import datetime, timezone
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.db.common import CommonBase
class EngagementDocument(CommonBase):
"""Logical document container linked to a client engagement.
The physical file is stored revision-wise in EngagementDocumentVersion.
DS1 keeps the file on the server/local project storage. DS3/DS4 can later
move the physical storage to branch local storage nodes without changing
the engagement-facing workflow.
"""
__tablename__ = "engagement_documents"
__table_args__ = (
UniqueConstraint("tenant_id", "engagement_id", "document_code", name="uq_engagement_documents_code"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, index=True)
engagement_id: Mapped[int] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="CASCADE"), nullable=False, index=True)
task_instance_id: Mapped[int | None] = mapped_column(ForeignKey("client_service_task_instances.id", ondelete="SET NULL"), nullable=True, index=True)
document_requirement_id: Mapped[int | None] = mapped_column(ForeignKey("firm_task_document_requirements.id", ondelete="SET NULL"), nullable=True, index=True)
financial_year: Mapped[str] = mapped_column(String(9), nullable=False, index=True)
assessment_year: Mapped[str | None] = mapped_column(String(9), nullable=True, index=True)
document_code: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
document_type: Mapped[str] = mapped_column(String(80), nullable=False, default="GENERAL", index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
current_version_no: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="active", index=True)
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
deleted_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
deleted_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)
client = relationship("Client")
engagement = relationship("ClientServiceSubscription")
task_instance = relationship("ClientServiceTaskInstance", foreign_keys=[task_instance_id])
document_requirement = relationship("FirmTaskDocumentRequirement", foreign_keys=[document_requirement_id])
versions = relationship(
"EngagementDocumentVersion",
back_populates="document",
cascade="all, delete-orphan",
passive_deletes=True,
order_by="EngagementDocumentVersion.version_no.desc()",
)
class EngagementDocumentVersion(CommonBase):
"""Physical revision of an engagement document."""
__tablename__ = "engagement_document_versions"
__table_args__ = (
UniqueConstraint("document_id", "version_no", name="uq_engagement_document_versions_no"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
document_id: Mapped[int] = mapped_column(ForeignKey("engagement_documents.id", ondelete="CASCADE"), nullable=False, index=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, index=True)
engagement_id: Mapped[int] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="CASCADE"), nullable=False, index=True)
version_no: Mapped[int] = mapped_column(Integer, nullable=False)
original_filename: Mapped[str] = mapped_column(String(255), nullable=False)
stored_filename: Mapped[str] = mapped_column(String(255), nullable=False)
content_type: Mapped[str | None] = mapped_column(String(150), nullable=True)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
file_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
storage_backend: Mapped[str] = mapped_column(String(40), nullable=False, default="LOCAL_YEAR_WISE", index=True)
local_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
storage_status: Mapped[str] = mapped_column(String(30), nullable=False, default="stored", index=True)
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
uploaded_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
uploaded_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
document = relationship("EngagementDocument", back_populates="versions")
class DocumentAccessLog(CommonBase):
"""Audit trail for document upload/download/delete activity."""
__tablename__ = "document_access_logs"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int | None] = mapped_column(ForeignKey("tenants.id", ondelete="SET NULL"), nullable=True, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int | None] = mapped_column(ForeignKey("clients.id", ondelete="SET NULL"), nullable=True, index=True)
engagement_id: Mapped[int | None] = mapped_column(ForeignKey("client_service_subscriptions.id", ondelete="SET NULL"), nullable=True, index=True)
document_id: Mapped[int | None] = mapped_column(ForeignKey("engagement_documents.id", ondelete="SET NULL"), nullable=True, index=True)
version_id: Mapped[int | None] = mapped_column(ForeignKey("engagement_document_versions.id", ondelete="SET NULL"), nullable=True, index=True)
action: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
result: Mapped[str] = mapped_column(String(40), nullable=False, default="success", index=True)
user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
ip_address: Mapped[str | None] = mapped_column(String(80), nullable=True)
user_agent: Mapped[str | None] = mapped_column(String(500), nullable=True)
message: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
class BranchStorageNode(CommonBase):
"""Branch-wise local storage connector registered with the cloud ERP.
DS3 stores only the hashed secret. The raw secret is generated once and must
be copied into the branch local storage app configuration.
"""
__tablename__ = "branch_storage_nodes"
__table_args__ = (
UniqueConstraint("tenant_id", "branch_id", "node_code", name="uq_branch_storage_node_code"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
node_code: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
node_name: Mapped[str] = mapped_column(String(200), nullable=False)
connector_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
secret_key_hash: Mapped[str] = mapped_column(String(64), nullable=False)
storage_root_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
storage_mode: Mapped[str] = mapped_column(String(40), nullable=False, default="pull_jobs", index=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="active", index=True)
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, index=True)
last_seen_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
last_seen_ip: Mapped[str | None] = mapped_column(String(80), nullable=True)
quota_limit_bytes: Mapped[int | None] = mapped_column(Integer, nullable=True)
used_storage_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
subscription_required: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)
class DocumentStorageJob(CommonBase):
"""Cloud-to-local branch storage transfer job.
The browser upload is first staged by ERP. The branch local app authenticates
with its node secret, pulls pending jobs, streams the staged file, stores it
in the branch year-wise folder, and acknowledges with the final hash.
"""
__tablename__ = "document_storage_jobs"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
storage_node_id: Mapped[int] = mapped_column(ForeignKey("branch_storage_nodes.id", ondelete="CASCADE"), nullable=False, index=True)
document_id: Mapped[int] = mapped_column(ForeignKey("engagement_documents.id", ondelete="CASCADE"), nullable=False, index=True)
version_id: Mapped[int] = mapped_column(ForeignKey("engagement_document_versions.id", ondelete="CASCADE"), nullable=False, index=True)
job_type: Mapped[str] = mapped_column(String(40), nullable=False, default="store_version", index=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="pending", index=True)
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=5, index=True)
staging_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
target_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
expected_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
picked_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
completed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
acknowledged_hash_sha256: Mapped[str | None] = mapped_column(String(64), nullable=True)
local_final_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
node = relationship("BranchStorageNode")
document = relationship("EngagementDocument")
version = relationship("EngagementDocumentVersion")
class DocumentDownloadRequest(CommonBase):
"""Secure local-to-cloud document retrieval request.
DS5 keeps user downloads permission-controlled in ERP while allowing the
branch local storage app to upload/stream the requested file back to ERP
through the existing zero-trust agent channel.
"""
__tablename__ = "document_download_requests"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
storage_node_id: Mapped[int] = mapped_column(ForeignKey("branch_storage_nodes.id", ondelete="CASCADE"), nullable=False, index=True)
document_id: Mapped[int] = mapped_column(ForeignKey("engagement_documents.id", ondelete="CASCADE"), nullable=False, index=True)
version_id: Mapped[int] = mapped_column(ForeignKey("engagement_document_versions.id", ondelete="CASCADE"), nullable=False, index=True)
request_status: Mapped[str] = mapped_column(String(30), nullable=False, default="pending", index=True)
local_relative_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
expected_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
cached_relative_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
cached_hash_sha256: Mapped[str | None] = mapped_column(String(64), nullable=True)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
requested_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
requested_ip: Mapped[str | None] = mapped_column(String(80), nullable=True)
requested_user_agent: Mapped[str | None] = mapped_column(String(500), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
fulfilled_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
failed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
node = relationship("BranchStorageNode")
document = relationship("EngagementDocument")
version = relationship("EngagementDocumentVersion")
class PermanentClientDocument(CommonBase):
"""Permanent client document container not linked to a financial year or engagement.
Examples: incorporation certificate, GST registration, PAN/TAN, bank/KYC,
agreements, DSC and other standing records used across years.
"""
__tablename__ = "permanent_client_documents"
__table_args__ = (
UniqueConstraint("tenant_id", "client_id", "document_code", name="uq_permanent_client_documents_code"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, index=True)
document_code: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
category: Mapped[str] = mapped_column(String(120), nullable=False, default="Other Permanent Documents", index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
current_version_no: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="active", index=True)
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
deleted_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
deleted_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)
client = relationship("Client")
versions = relationship(
"PermanentClientDocumentVersion",
back_populates="document",
cascade="all, delete-orphan",
passive_deletes=True,
order_by="PermanentClientDocumentVersion.version_no.desc()",
)
class PermanentClientDocumentVersion(CommonBase):
"""Physical revision of a permanent client document."""
__tablename__ = "permanent_client_document_versions"
__table_args__ = (
UniqueConstraint("document_id", "version_no", name="uq_permanent_client_document_versions_no"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
document_id: Mapped[int] = mapped_column(ForeignKey("permanent_client_documents.id", ondelete="CASCADE"), nullable=False, index=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
client_id: Mapped[int] = mapped_column(ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, index=True)
version_no: Mapped[int] = mapped_column(Integer, nullable=False)
original_filename: Mapped[str] = mapped_column(String(255), nullable=False)
stored_filename: Mapped[str] = mapped_column(String(255), nullable=False)
content_type: Mapped[str | None] = mapped_column(String(150), nullable=True)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
file_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
storage_backend: Mapped[str] = mapped_column(String(40), nullable=False, default="LOCAL_PERMANENT", index=True)
local_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
storage_status: Mapped[str] = mapped_column(String(30), nullable=False, default="stored", index=True)
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
uploaded_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
uploaded_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
document = relationship("PermanentClientDocument", back_populates="versions")
class PermanentDocumentStorageJob(CommonBase):
"""Cloud-to-local transfer job for permanent client document versions."""
__tablename__ = "permanent_document_storage_jobs"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
storage_node_id: Mapped[int] = mapped_column(ForeignKey("branch_storage_nodes.id", ondelete="CASCADE"), nullable=False, index=True)
document_id: Mapped[int] = mapped_column(ForeignKey("permanent_client_documents.id", ondelete="CASCADE"), nullable=False, index=True)
version_id: Mapped[int] = mapped_column(ForeignKey("permanent_client_document_versions.id", ondelete="CASCADE"), nullable=False, index=True)
job_type: Mapped[str] = mapped_column(String(40), nullable=False, default="store_permanent_version", index=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="pending", index=True)
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=5, index=True)
staging_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
target_relative_path: Mapped[str] = mapped_column(String(1000), nullable=False)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
expected_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
picked_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
completed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
acknowledged_hash_sha256: Mapped[str | None] = mapped_column(String(64), nullable=True)
local_final_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
node = relationship("BranchStorageNode")
document = relationship("PermanentClientDocument")
version = relationship("PermanentClientDocumentVersion")
class PermanentDocumentDownloadRequest(CommonBase):
"""Local-to-cloud retrieval request for permanent client documents."""
__tablename__ = "permanent_document_download_requests"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
storage_node_id: Mapped[int] = mapped_column(ForeignKey("branch_storage_nodes.id", ondelete="CASCADE"), nullable=False, index=True)
document_id: Mapped[int] = mapped_column(ForeignKey("permanent_client_documents.id", ondelete="CASCADE"), nullable=False, index=True)
version_id: Mapped[int] = mapped_column(ForeignKey("permanent_client_document_versions.id", ondelete="CASCADE"), nullable=False, index=True)
request_status: Mapped[str] = mapped_column(String(30), nullable=False, default="pending", index=True)
local_relative_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
expected_hash_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
cached_relative_path: Mapped[str | None] = mapped_column(String(1000), nullable=True)
cached_hash_sha256: Mapped[str | None] = mapped_column(String(64), nullable=True)
file_size_bytes: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
requested_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
requested_ip: Mapped[str | None] = mapped_column(String(80), nullable=True)
requested_user_agent: Mapped[str | None] = mapped_column(String(500), nullable=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
fulfilled_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
failed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
node = relationship("BranchStorageNode")
document = relationship("PermanentClientDocument")
version = relationship("PermanentClientDocumentVersion")