Prepare ERP source for Gitea deployment
This commit is contained in:
@@ -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")
|
||||
Reference in New Issue
Block a user