Implement three foundational schema features from the design doc: - Tree forking with lineage tracking (migration 022): parent_tree_id, root_tree_id, fork_depth columns with self-referential FKs and composite analytics index - Custom step enhancement: CustomStepSchema with source tracking (ad-hoc, step-library, forked-tree) for backward-compatible JSONB - Session sharing (migration 023): session_shares and session_share_views tables with account-scoped visibility, cryptographic tokens, view tracking, and allow_public_shares account policy Includes 21 new integration tests (9 forking, 12 sharing), SaaS consultant-recommended denormalizations, rate limiting on public share access, and test fixture fix for invite code requirement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
from datetime import datetime
|
|
from typing import Optional, Literal
|
|
from uuid import UUID
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ShareCreate(BaseModel):
|
|
visibility: Literal["public", "account"] = Field("public", description="Share visibility")
|
|
share_name: Optional[str] = Field(None, max_length=100, description="Optional label for the share")
|
|
expires_at: Optional[datetime] = Field(None, description="Optional expiration datetime")
|
|
|
|
|
|
class ShareResponse(BaseModel):
|
|
id: UUID
|
|
session_id: UUID
|
|
account_id: UUID
|
|
share_token: str
|
|
share_name: Optional[str] = None
|
|
visibility: str
|
|
created_by: UUID
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
expires_at: Optional[datetime] = None
|
|
view_count: int
|
|
last_viewed_at: Optional[datetime] = None
|
|
is_active: bool
|
|
share_url: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class SharePublicView(BaseModel):
|
|
"""Read-only session data returned when accessing a share link."""
|
|
session_id: UUID
|
|
tree_name: str
|
|
tree_description: Optional[str] = None
|
|
tree_structure: dict
|
|
path_taken: list[str]
|
|
decisions: list[dict]
|
|
custom_steps: list[dict] = Field(default_factory=list)
|
|
started_at: datetime
|
|
completed_at: Optional[datetime] = None
|
|
ticket_number: Optional[str] = None
|
|
client_name: Optional[str] = None
|
|
share_name: Optional[str] = None
|
|
visibility: str
|