feat(14.1-02): CloudItemDetailOut schema + resolve_owned_cloud_item_detail + GET detail route
- Add CloudItemDetailOut allowlist schema to backend/api/cloud/schemas.py
(excludes credentials_enc, object_key, version_key, raw provider URLs — T-14.1-03)
- Add CloudItemDetail dataclass and resolve_owned_cloud_item_detail service helper
to backend/services/cloud_items.py (owner-scoped, metadata-only, no byte hydration)
- Add GET /connections/{id}/items/{item_id:path}/detail route to operations.py
with get_regular_user (admin 403), ConnectionNotFound → 404, CloudItemNotFound → 404
- All 8 test_cloud_detail_parity tests now pass (D-05, D-07, D-16, T-14.1-03/04/06)
This commit is contained in:
@@ -13,6 +13,10 @@ Phase 13 additions:
|
||||
Phase 14 additions:
|
||||
- CacheStatusOut: aggregate cache usage + settings response (T-14-02, T-14-08)
|
||||
- CacheSettingsUpdateRequest: PATCH body for updating analysis settings/cache limit
|
||||
|
||||
Phase 14.1 additions:
|
||||
- CloudItemDetailOut: owner-scoped cloud item detail with analysis fields (D-05)
|
||||
- force field on AnalysisEnqueueRequest: bypass already_current check (D-11)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -22,6 +26,66 @@ from typing import List, Optional
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
# ── Phase 14.1 cloud item detail schema ──────────────────────────────────────
|
||||
|
||||
class CloudItemDetailOut(BaseModel):
|
||||
"""Owner-scoped cloud item detail with analysis fields and source metadata.
|
||||
|
||||
Strict allowlist: object_key, credentials_enc, version_key, and raw provider
|
||||
URLs are absent by design (T-14.1-03, mirrors CacheStatusOut T-14-02 pattern).
|
||||
|
||||
Fields:
|
||||
id: DocuVault stable UUID (str).
|
||||
provider_item_id: Provider-side opaque item identifier.
|
||||
name: File or folder name.
|
||||
kind: "file" | "folder".
|
||||
parent_ref: Provider parent reference (opaque string, no URL).
|
||||
content_type: MIME type from provider metadata.
|
||||
size: Provider-reported byte count (provider_size).
|
||||
modified_at: Provider-reported last modification timestamp.
|
||||
etag: Provider entity tag for version comparison.
|
||||
provider: Connection provider string (e.g. "google_drive").
|
||||
display_name: Human-readable connection display name.
|
||||
location: Human path (path_snapshot) or parent_ref — no provider URL.
|
||||
analysis_status: "pending" | "indexed" | "stale" | "failed" | ...
|
||||
semantic_index_status: "none" | "indexed" | ...
|
||||
extracted_text: Text extracted during analysis (None when not yet analyzed).
|
||||
topics: List of topic names linked to this item (empty when not analyzed).
|
||||
capabilities: Per-action capability map (action → CloudCapabilityOut).
|
||||
unsupported_analysis_reason: Reason why analysis is unsupported (None when supported).
|
||||
is_stale: True when analysis_status == "stale" (D-07 convenience flag).
|
||||
"""
|
||||
|
||||
# Core identity (no object_key, credentials_enc, version_key — T-14.1-03)
|
||||
id: str
|
||||
provider_item_id: str
|
||||
name: str
|
||||
kind: str
|
||||
parent_ref: Optional[str] = None
|
||||
|
||||
# Provider metadata
|
||||
content_type: Optional[str] = None
|
||||
size: Optional[int] = None
|
||||
modified_at: Optional[datetime] = None
|
||||
etag: Optional[str] = None
|
||||
|
||||
# Connection source metadata (D-04) — no raw provider URLs
|
||||
provider: str
|
||||
display_name: str
|
||||
location: Optional[str] = None # path_snapshot or parent_ref, never a provider URL
|
||||
|
||||
# Analysis fields (D-05, D-07, D-08)
|
||||
analysis_status: str = "pending"
|
||||
semantic_index_status: str = "none"
|
||||
extracted_text: Optional[str] = None
|
||||
topics: List[str] = []
|
||||
|
||||
# Action availability (D-05, D-16)
|
||||
capabilities: dict[str, CloudCapabilityOut] = {}
|
||||
unsupported_analysis_reason: Optional[str] = None # populated when analyze is unsupported
|
||||
is_stale: bool = False # True when analysis_status == "stale" (D-07)
|
||||
|
||||
|
||||
# ── Capability / item schemas ─────────────────────────────────────────────────
|
||||
|
||||
class CloudCapabilityOut(BaseModel):
|
||||
@@ -285,6 +349,7 @@ class AnalysisEnqueueRequest(BaseModel):
|
||||
provider_item_ids: Required for file/selection/folder scope.
|
||||
recursive: Expand folder subtree recursively.
|
||||
failure_behavior: "pause_batch" (default) | "continue_item" (D-11).
|
||||
force: When True, bypass already_current check and re-queue indexed items (D-11).
|
||||
"""
|
||||
|
||||
scope: str = Field(..., description="file | selection | folder | connection")
|
||||
@@ -294,6 +359,15 @@ class AnalysisEnqueueRequest(BaseModel):
|
||||
default="pause_batch",
|
||||
description="pause_batch | continue_item",
|
||||
)
|
||||
force: bool = Field(
|
||||
default=False,
|
||||
description=(
|
||||
"When True, bypass the already_current check and re-queue supported items "
|
||||
"even if their version_key matches a prior indexed run. "
|
||||
"Preserves existing idempotent behavior when False (default). "
|
||||
"No provider mutation is performed regardless of this flag (ANALYZE-07)."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# ── Phase 14 analysis response schemas ────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user