ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: blob-дедупликация файлов

This commit is contained in:
DCCONSTRUCTIONS
2026-04-27 09:45:16 +03:00
parent b945bc4d31
commit 490aa1bc04
18 changed files with 827 additions and 114 deletions
@@ -4,7 +4,7 @@
from .analytic import AnalyticView
from .api import APIActivityLog, APIToken
from .asset import FileAsset
from .asset import FileAsset, StoredBlob
from .base import BaseModel
from .cycle import Cycle, CycleIssue, CycleUserProperties
from .deploy_board import DeployBoard
@@ -60,6 +60,13 @@ class FileAsset(BaseModel):
size = models.FloatField(default=0)
is_uploaded = models.BooleanField(default=False)
storage_metadata = models.JSONField(default=dict, null=True, blank=True)
blob = models.ForeignKey(
"db.StoredBlob",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="assets",
)
class Meta:
verbose_name = "File Asset"
@@ -98,3 +105,43 @@ class FileAsset(BaseModel):
return f"/api/assets/v2/workspaces/{self.workspace.slug}/projects/{self.project_id}/{self.id}/"
return None
class StoredBlob(BaseModel):
"""
Canonical stored object shared by one or more FileAsset records.
"""
class Status(models.TextChoices):
ACTIVE = "active", "Active"
ORPHANED = "orphaned", "Orphaned"
MISSING = "missing", "Missing"
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="stored_blobs")
sha256 = models.CharField(max_length=64, db_index=True)
size = models.PositiveBigIntegerField(default=0)
mime_type = models.CharField(max_length=255, blank=True, default="")
canonical_object_key = models.CharField(max_length=800)
status = models.CharField(max_length=32, choices=Status.choices, default=Status.ACTIVE)
ref_count = models.PositiveIntegerField(default=0)
storage_metadata = models.JSONField(default=dict, null=True, blank=True)
class Meta:
verbose_name = "Stored Blob"
verbose_name_plural = "Stored Blobs"
db_table = "stored_blobs"
ordering = ("-created_at",)
indexes = [
models.Index(fields=["workspace", "sha256"], name="stored_blob_workspace_sha_idx"),
models.Index(fields=["status"], name="stored_blob_status_idx"),
]
constraints = [
models.UniqueConstraint(
fields=["workspace", "sha256", "size"],
condition=models.Q(deleted_at__isnull=True, status="active"),
name="stored_blob_unique_active_hash_size",
)
]
def __str__(self):
return self.canonical_object_key