refactor(schemas): rename SearchSpace -> Workspace in Pydantic schemas (Phase 2 Wave C)

Rename schemas/search_space.py -> schemas/workspace.py, the SearchSpace* classes
-> Workspace* (incl. UserSearchSpaceAccess -> UserWorkspaceAccess), and the
search_space_id / search_space_name fields -> workspace_id / workspace_name across
all schema modules. Under hard cutover the serialized JSON keys change outright
(no alias). Re-exports in schemas/__init__.py updated.
This commit is contained in:
CREDO23 2026-06-26 18:23:43 +02:00
parent d948b769ba
commit 0c53d884eb
16 changed files with 70 additions and 70 deletions

View file

@ -84,7 +84,7 @@ from .rbac_schemas import (
RoleCreate,
RoleRead,
RoleUpdate,
UserSearchSpaceAccess,
UserWorkspaceAccess,
)
from .reports import (
ReportBase,
@ -103,13 +103,13 @@ from .search_source_connector import (
SearchSourceConnectorRead,
SearchSourceConnectorUpdate,
)
from .search_space import (
SearchSpaceApiAccessUpdate,
SearchSpaceBase,
SearchSpaceCreate,
SearchSpaceRead,
SearchSpaceUpdate,
SearchSpaceWithStats,
from .workspace import (
WorkspaceApiAccessUpdate,
WorkspaceBase,
WorkspaceCreate,
WorkspaceRead,
WorkspaceUpdate,
WorkspaceWithStats,
)
from .stripe import (
CreateCreditCheckoutSessionRequest,
@ -242,13 +242,13 @@ __all__ = [
"SearchSourceConnectorCreate",
"SearchSourceConnectorRead",
"SearchSourceConnectorUpdate",
"SearchSpaceApiAccessUpdate",
# Search space schemas
"SearchSpaceBase",
"SearchSpaceCreate",
"SearchSpaceRead",
"SearchSpaceUpdate",
"SearchSpaceWithStats",
"WorkspaceApiAccessUpdate",
# Workspace schemas
"WorkspaceBase",
"WorkspaceCreate",
"WorkspaceRead",
"WorkspaceUpdate",
"WorkspaceWithStats",
"StripeWebhookResponse",
"ThreadHistoryLoadResponse",
"ThreadListItem",
@ -257,7 +257,7 @@ __all__ = [
# User schemas
"UserCreate",
"UserRead",
"UserSearchSpaceAccess",
"UserWorkspaceAccess",
"UserUpdate",
"VerifyConnectionResponse",
# Video Presentation schemas

View file

@ -110,8 +110,8 @@ class MentionContextResponse(BaseModel):
thread_id: int
thread_title: str
message_id: int
search_space_id: int
search_space_name: str
workspace_id: int
workspace_name: str
class MentionCommentResponse(BaseModel):

View file

@ -30,7 +30,7 @@ class DocumentBase(BaseModel):
content: (
list[ExtensionDocumentContent] | list[str] | str
) # Updated to allow string content
search_space_id: int
workspace_id: int
class DocumentsCreate(DocumentBase):
@ -59,7 +59,7 @@ class DocumentRead(BaseModel):
unique_identifier_hash: str | None
created_at: datetime
updated_at: datetime | None
search_space_id: int
workspace_id: int
folder_id: int | None = None
created_by_id: UUID | None = None
created_by_name: str | None = None

View file

@ -10,7 +10,7 @@ from pydantic import BaseModel, ConfigDict, Field
class FolderCreate(BaseModel):
name: str = Field(max_length=255, min_length=1)
parent_id: int | None = None
search_space_id: int
workspace_id: int
class FolderUpdate(BaseModel):
@ -31,7 +31,7 @@ class FolderRead(BaseModel):
name: str
position: str
parent_id: int | None
search_space_id: int
workspace_id: int
created_by_id: UUID | None
created_at: datetime
updated_at: datetime

View file

@ -34,15 +34,15 @@ class ImageGenerationCreate(BaseModel):
size: str | None = Field(None, max_length=50)
style: str | None = Field(None, max_length=50)
response_format: str | None = Field(None, max_length=50)
search_space_id: int = Field(
..., description="Search space ID to associate the generation with"
workspace_id: int = Field(
..., description="Workspace ID to associate the generation with"
)
image_gen_model_id: int | None = Field(
None,
description=(
"Image generation model ID. "
"0 = Auto mode, negative = GLOBAL model, positive = BYOK Model row. "
"If not provided, uses the search space's image_gen_model_id preference."
"If not provided, uses the workspace's image_gen_model_id preference."
),
)
@ -61,7 +61,7 @@ class ImageGenerationRead(BaseModel):
image_gen_model_id: int | None = None
response_data: dict[str, Any] | None = None
error_message: str | None = None
search_space_id: int
workspace_id: int
created_at: datetime
model_config = ConfigDict(from_attributes=True)
@ -76,7 +76,7 @@ class ImageGenerationListRead(BaseModel):
n: int | None = None
quality: str | None = None
size: str | None = None
search_space_id: int
workspace_id: int
created_at: datetime
is_success: bool
image_count: int | None = None
@ -99,7 +99,7 @@ class ImageGenerationListRead(BaseModel):
n=obj.n,
quality=obj.quality,
size=obj.size,
search_space_id=obj.search_space_id,
workspace_id=obj.workspace_id,
created_at=obj.created_at,
is_success=obj.response_data is not None,
image_count=image_count,

View file

@ -22,7 +22,7 @@ class LogCreate(BaseModel):
message: str
source: str | None = None
log_metadata: dict[str, Any] | None = None
search_space_id: int
workspace_id: int
class LogUpdate(BaseModel):
@ -36,7 +36,7 @@ class LogUpdate(BaseModel):
class LogRead(LogBase, IDModel, TimestampModel):
id: int
created_at: datetime
search_space_id: int
workspace_id: int
model_config = ConfigDict(from_attributes=True)
@ -45,7 +45,7 @@ class LogFilter(BaseModel):
level: LogLevel | None = None
status: LogStatus | None = None
source: str | None = None
search_space_id: int | None = None
workspace_id: int | None = None
start_date: datetime | None = None
end_date: datetime | None = None

View file

@ -34,7 +34,7 @@ class ConnectionRead(BaseModel):
api_key: str | None = None
extra: dict[str, Any] = Field(default_factory=dict)
scope: ConnectionScope | str
search_space_id: int | None = None
workspace_id: int | None = None
user_id: uuid.UUID | None = None
enabled: bool
has_api_key: bool
@ -76,7 +76,7 @@ class ConnectionCreate(BaseModel):
api_key: str | None = None
extra: dict[str, Any] = Field(default_factory=dict)
scope: ConnectionScope = ConnectionScope.SEARCH_SPACE
search_space_id: int | None = None
workspace_id: int | None = None
enabled: bool = True
models: list[ModelSelection] = Field(default_factory=list)

View file

@ -85,7 +85,7 @@ class NewChatThreadBase(BaseModel):
class NewChatThreadCreate(NewChatThreadBase):
"""Schema for creating a new thread."""
search_space_id: int
workspace_id: int
# Visibility defaults to PRIVATE, but can be set on creation
visibility: ChatVisibility = ChatVisibility.PRIVATE
@ -108,7 +108,7 @@ class NewChatThreadRead(NewChatThreadBase, IDModel):
Schema for reading a thread (matches assistant-ui ThreadRecord).
"""
search_space_id: int
workspace_id: int
visibility: ChatVisibility
created_by_id: UUID | None = None
created_at: datetime
@ -236,7 +236,7 @@ class NewChatRequest(BaseModel):
chat_id: int
user_query: str
search_space_id: int
workspace_id: int
messages: list[ChatMessage] | None = None # Optional chat history from frontend
mentioned_document_ids: list[int] | None = (
None # Optional document IDs mentioned with @ in the chat
@ -279,7 +279,7 @@ class NewChatRequest(BaseModel):
default=None,
description=(
"Other chat thread IDs the user @-mentioned. Each is "
"resolved (access-checked, same search space) into a "
"resolved (access-checked, same workspace) into a "
"read-only ``<referenced_chat_context>`` block prepended to "
"the agent query. Display chips persist via the "
"``mentioned_documents`` list (kind=``thread``)."
@ -330,7 +330,7 @@ class RegenerateRequest(BaseModel):
``data-revert-results`` and do not abort the regeneration.
"""
search_space_id: int
workspace_id: int
user_query: str | None = (
None # New user query (for edit). None = reload with same query
)
@ -428,7 +428,7 @@ class ResumeDecision(BaseModel):
class ResumeRequest(BaseModel):
search_space_id: int
workspace_id: int
decisions: list[ResumeDecision]
# Mirrors ``NewChatRequest.disabled_tools`` so the resumed run sees the
# same tool surface as the originating turn.
@ -520,7 +520,7 @@ class PublicChatSnapshotDetail(BaseModel):
class PublicChatSnapshotsBySpaceResponse(BaseModel):
"""List of public chat snapshots for a search space."""
"""List of public chat snapshots for a workspace."""
snapshots: list[PublicChatSnapshotDetail]
@ -556,4 +556,4 @@ class CloneResponse(BaseModel):
"""Response after cloning a public snapshot."""
thread_id: int
search_space_id: int
workspace_id: int

View file

@ -150,7 +150,7 @@ class ConnectRequest(_PluginBase):
vault_id: str
vault_name: str
search_space_id: int
workspace_id: int
vault_fingerprint: str = Field(
...,
description=(
@ -167,7 +167,7 @@ class ConnectResponse(_PluginBase):
connector_id: int
vault_id: str
search_space_id: int
workspace_id: int
capabilities: list[str]
server_time_utc: datetime

View file

@ -7,7 +7,7 @@ class PromptCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
prompt: str = Field(..., min_length=1)
mode: str = Field(..., pattern="^(transform|explore)$")
search_space_id: int | None = None
workspace_id: int | None = None
is_public: bool = False
@ -23,7 +23,7 @@ class PromptRead(BaseModel):
name: str
prompt: str
mode: str
search_space_id: int | None
workspace_id: int | None
is_public: bool
version: int
created_at: datetime

View file

@ -38,7 +38,7 @@ class RoleRead(RoleBase):
"""Schema for reading a role."""
id: int
search_space_id: int
workspace_id: int
is_system_role: bool
created_at: datetime
@ -66,7 +66,7 @@ class MembershipRead(BaseModel):
id: int
user_id: UUID
search_space_id: int
workspace_id: int
role_id: int | None
is_owner: bool
joined_at: datetime
@ -123,7 +123,7 @@ class InviteRead(InviteBase):
id: int
invite_code: str
search_space_id: int
workspace_id: int
created_by_id: UUID | None
uses_count: int
is_active: bool
@ -145,15 +145,15 @@ class InviteAcceptResponse(BaseModel):
"""Response schema for accepting an invite."""
message: str
search_space_id: int
search_space_name: str
workspace_id: int
workspace_name: str
role_name: str | None
class InviteInfoResponse(BaseModel):
"""Response schema for getting invite info (public endpoint)."""
search_space_name: str
workspace_name: str
role_name: str | None
is_valid: bool
message: str | None = None
@ -180,11 +180,11 @@ class PermissionsListResponse(BaseModel):
# ============ User Access Info ============
class UserSearchSpaceAccess(BaseModel):
"""Schema for user's access info in a search space."""
class UserWorkspaceAccess(BaseModel):
"""Schema for user's access info in a workspace."""
search_space_id: int
search_space_name: str
workspace_id: int
workspace_name: str
is_owner: bool
role_name: str | None
permissions: list[str]

View file

@ -12,7 +12,7 @@ class ReportBase(BaseModel):
title: str
content: str | None = None
report_style: str | None = None
search_space_id: int
workspace_id: int
class ReportRead(BaseModel):

View file

@ -73,7 +73,7 @@ class SearchSourceConnectorUpdate(BaseModel):
class SearchSourceConnectorRead(SearchSourceConnectorBase, IDModel, TimestampModel):
search_space_id: int
workspace_id: int
user_id: uuid.UUID
model_config = ConfigDict(from_attributes=True)
@ -129,7 +129,7 @@ class MCPConnectorRead(BaseModel):
name: str
connector_type: SearchSourceConnectorType
server_config: MCPServerConfig
search_space_id: int
workspace_id: int
user_id: uuid.UUID
created_at: datetime
updated_at: datetime
@ -148,7 +148,7 @@ class MCPConnectorRead(BaseModel):
name=connector.name,
connector_type=connector.connector_type,
server_config=server_config,
search_space_id=connector.search_space_id,
workspace_id=connector.workspace_id,
user_id=connector.user_id,
created_at=connector.created_at,
updated_at=connector.updated_at,

View file

@ -12,7 +12,7 @@ class CreateCreditCheckoutSessionRequest(BaseModel):
"""Request body for creating a credit-purchase checkout session."""
quantity: int = Field(ge=1, le=10_000)
search_space_id: int = Field(ge=1)
workspace_id: int = Field(ge=1)
class CreateCreditCheckoutSessionResponse(BaseModel):
@ -114,7 +114,7 @@ class UpdateAutoReloadSettingsRequest(BaseModel):
class CreateAutoReloadSetupSessionRequest(BaseModel):
"""Request body for starting the save-a-card (SetupIntent) checkout."""
search_space_id: int = Field(ge=1)
workspace_id: int = Field(ge=1)
class CreateAutoReloadSetupSessionResponse(BaseModel):

View file

@ -20,7 +20,7 @@ class VideoPresentationBase(BaseModel):
title: str
slides: list[dict[str, Any]] | None = None
scene_codes: list[dict[str, Any]] | None = None
search_space_id: int
workspace_id: int
class VideoPresentationCreate(VideoPresentationBase):
@ -65,7 +65,7 @@ class VideoPresentationRead(VideoPresentationBase):
"title": obj.title,
"slides": slides,
"scene_codes": obj.scene_codes,
"search_space_id": obj.search_space_id,
"workspace_id": obj.workspace_id,
"status": obj.status,
"created_at": obj.created_at,
"slide_count": len(obj.slides) if obj.slides else None,

View file

@ -6,17 +6,17 @@ from pydantic import BaseModel, ConfigDict
from .base import IDModel, TimestampModel
class SearchSpaceBase(BaseModel):
class WorkspaceBase(BaseModel):
name: str
description: str | None = None
class SearchSpaceCreate(SearchSpaceBase):
class WorkspaceCreate(WorkspaceBase):
citations_enabled: bool = True
qna_custom_instructions: str | None = None
class SearchSpaceUpdate(BaseModel):
class WorkspaceUpdate(BaseModel):
name: str | None = None
description: str | None = None
citations_enabled: bool | None = None
@ -24,11 +24,11 @@ class SearchSpaceUpdate(BaseModel):
ai_file_sort_enabled: bool | None = None
class SearchSpaceApiAccessUpdate(BaseModel):
class WorkspaceApiAccessUpdate(BaseModel):
api_access_enabled: bool
class SearchSpaceRead(SearchSpaceBase, IDModel, TimestampModel):
class WorkspaceRead(WorkspaceBase, IDModel, TimestampModel):
id: int
created_at: datetime
user_id: uuid.UUID
@ -41,8 +41,8 @@ class SearchSpaceRead(SearchSpaceBase, IDModel, TimestampModel):
model_config = ConfigDict(from_attributes=True)
class SearchSpaceWithStats(SearchSpaceRead):
"""Extended search space info with member count and ownership status."""
class WorkspaceWithStats(WorkspaceRead):
"""Extended workspace info with member count and ownership status."""
member_count: int = 1
is_owner: bool = False