Keep only the latest file of a Document Type in each property's folder 🟥

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-08 09:04:19 +00:00
parent 6d001d650e
commit 28b7b43372
4 changed files with 114 additions and 0 deletions

View file

@ -0,0 +1,66 @@
"""The Download Package plan (ADR-0060).
Pure logic: given the documents resolved for a set of properties, decide what
goes where in the ZIP one folder per property, the latest file of each
Document Type and which rows are skipped and reported. No I/O: the
orchestrator does the S3/DB work; this module only lays out the archive.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from typing import Optional, Sequence
@dataclass(frozen=True)
class ResolvedDocument:
"""One `uploaded_files` row resolved for packaging: its property identity
(matched by `landlord_property_id`, ADR-0060), the display address enriched
from the hubspot deals data, its Document Type (`file_type`, nullable), the
S3 location to read it from, and when it was uploaded (for latest-per-type).
"""
landlord_property_id: str
address: str
document_type: Optional[str]
s3_bucket: str
s3_key: str
uploaded_at: datetime
@dataclass(frozen=True)
class PackageEntry:
"""One file to place in the Download Package: where it lands in the ZIP and
the S3 object to stream in from."""
zip_path: str
s3_bucket: str
s3_key: str
@dataclass(frozen=True)
class SkippedDocument:
"""A resolved row left out of the package, with the reason (surfaced in the
run's `sub_task.outputs`, ADR-0060)."""
landlord_property_id: str
s3_key: str
reason: str
@dataclass(frozen=True)
class DownloadPackagePlan:
"""The laid-out archive: the files to include and the rows skipped."""
entries: tuple[PackageEntry, ...]
skipped: tuple[SkippedDocument, ...]
def plan_download_package(
documents: Sequence[ResolvedDocument],
) -> DownloadPackagePlan:
"""Lay out a Download Package from resolved documents (ADR-0060): one folder
per property, the latest file of each Document Type, null-Document-Type rows
skipped and reported."""
raise NotImplementedError

View file

@ -0,0 +1,48 @@
"""The Download Package plan (ADR-0060) — pure layout of the ZIP from resolved
documents: one folder per property, latest file of each Document Type,
null-Document-Type rows skipped and reported."""
from datetime import datetime, timezone
from domain.bulk_document_download.package_plan import (
ResolvedDocument,
plan_download_package,
)
def _doc(
*,
landlord_property_id: str = "LP1",
address: str = "12 Oak Street",
document_type: str = "site_note",
s3_key: str = "a.pdf",
uploaded_at: datetime = datetime(2026, 1, 1, tzinfo=timezone.utc),
) -> ResolvedDocument:
return ResolvedDocument(
landlord_property_id=landlord_property_id,
address=address,
document_type=document_type,
s3_bucket="src-bucket",
s3_key=s3_key,
uploaded_at=uploaded_at,
)
def test_keeps_only_the_latest_file_of_a_document_type_in_the_property_folder() -> None:
# Arrange — two site_note files for the same property, uploaded at
# different times; only the newest should be packaged.
older = _doc(
s3_key="old.pdf", uploaded_at=datetime(2026, 1, 1, tzinfo=timezone.utc)
)
newer = _doc(
s3_key="new.pdf", uploaded_at=datetime(2026, 6, 1, tzinfo=timezone.utc)
)
# Act
plan = plan_download_package([older, newer])
# Assert — one entry, the newer file, foldered under the property.
assert len(plan.entries) == 1
entry = plan.entries[0]
assert entry.s3_key == "new.pdf"
assert entry.zip_path.startswith("12 Oak Street (LP1)/")