feat(12.1-02): centralize listing freshness gate — apply_listing_and_finalize

- Add ListingResult dataclass to cloud_items.py
- Add apply_listing_and_finalize() — single shared gate for complete/incomplete semantics
- complete=True: upserts, soft-deletes unseen children, marks fresh, advances last_refreshed_at
- complete=False: upserts seen items only, never deletes unseen, preserves prior timestamp, warns
- browse.py: replace unconditional update_folder_state('fresh') with apply_listing_and_finalize
- cloud_tasks.py: replace unconditional fresh transition with apply_listing_and_finalize
- Celery task returns structured warning status on incomplete (no credentials/provider item names)
- Fix timezone naive/aware comparison in test (SQLite strips tzinfo)
This commit is contained in:
curo1305
2026-06-22 08:29:41 +02:00
parent fe08afd740
commit bfa4dc502a
4 changed files with 118 additions and 22 deletions
+5 -9
View File
@@ -31,6 +31,7 @@ from deps.db import get_db
from deps.utils import parse_uuid
from services.cloud_items import (
ConnectionNotFound,
apply_listing_and_finalize,
list_cloud_children,
get_or_create_folder_state,
reconcile_cloud_listing,
@@ -259,7 +260,9 @@ async def browse_connection_items(
or _is_stale
)
if should_refresh and not cached_items:
# First visit: do a synchronous bounded fetch so user sees content
# First visit: do a synchronous bounded fetch so user sees content.
# apply_listing_and_finalize is the single shared gate — it handles
# complete vs. incomplete semantics without unconditional fresh state.
try:
credentials = _decrypt_connection(conn, current_user.id)
adapter = build_cloud_resource_adapter(conn.provider, credentials)
@@ -268,20 +271,13 @@ async def browse_connection_items(
current_user.id,
parent_ref=parent_ref,
)
await reconcile_cloud_listing(
await apply_listing_and_finalize(
session,
user_id=uid_str,
connection_id=cid_str,
parent_ref=parent_ref,
listing=listing,
)
await update_folder_state(
session,
user_id=uid_str,
connection_id=cid_str,
parent_ref=parent_ref or "",
refresh_state="fresh",
)
await session.commit()
# Re-read items after reconciliation
cached_items = await list_cloud_children(