Reconcile orphaned Campaign artifacts

This commit is contained in:
2026-08-03 09:23:27 +02:00
parent d635f3a5fc
commit d9195a2d2b
12 changed files with 1320 additions and 14 deletions
+49
View File
@@ -680,6 +680,55 @@ class BuildCampaignRequest(BaseModel):
idempotency_key: str | None = Field(default=None, min_length=1, max_length=200)
class CampaignArtifactReconcileRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
apply: bool = False
idempotency_key: str | None = Field(default=None, min_length=1, max_length=200)
grace_period_hours: int = Field(default=24, ge=24, le=24 * 90)
cursor: str | None = Field(default=None, min_length=1, max_length=1000)
page_size: int = Field(default=250, ge=1, le=1000)
@model_validator(mode="after")
def require_apply_idempotency_key(self) -> "CampaignArtifactReconcileRequest":
if self.apply and not self.idempotency_key:
raise ValueError("Applied artifact cleanup requires an idempotency key")
return self
class CampaignArtifactCandidateResponse(BaseModel):
key: str
size_bytes: int
modified_at: datetime
age_seconds: int
reason: str
disposition: str
failure_type: str | None = None
class CampaignArtifactReconcileResponse(BaseModel):
apply: bool
status: str
recovery_operation_id: str | None = None
tenant_prefix: str
cursor: str | None = None
next_cursor: str | None = None
scanned_count: int
scanned_bytes: int
referenced_count: int
active_build_count: int
young_count: int
unknown_age_count: int
invalid_shape_count: int
candidate_count: int
candidate_bytes: int
deleted_count: int
deleted_bytes: int
failure_count: int
manifest_sha256: str | None = None
candidates: list[CampaignArtifactCandidateResponse] = Field(default_factory=list)
class ApiKeyCreateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")