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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -20,7 +20,7 @@ class VideoPresentationBase(BaseModel):
title: str title: str
slides: list[dict[str, Any]] | None = None slides: list[dict[str, Any]] | None = None
scene_codes: list[dict[str, Any]] | None = None scene_codes: list[dict[str, Any]] | None = None
search_space_id: int workspace_id: int
class VideoPresentationCreate(VideoPresentationBase): class VideoPresentationCreate(VideoPresentationBase):
@ -65,7 +65,7 @@ class VideoPresentationRead(VideoPresentationBase):
"title": obj.title, "title": obj.title,
"slides": slides, "slides": slides,
"scene_codes": obj.scene_codes, "scene_codes": obj.scene_codes,
"search_space_id": obj.search_space_id, "workspace_id": obj.workspace_id,
"status": obj.status, "status": obj.status,
"created_at": obj.created_at, "created_at": obj.created_at,
"slide_count": len(obj.slides) if obj.slides else None, "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 from .base import IDModel, TimestampModel
class SearchSpaceBase(BaseModel): class WorkspaceBase(BaseModel):
name: str name: str
description: str | None = None description: str | None = None
class SearchSpaceCreate(SearchSpaceBase): class WorkspaceCreate(WorkspaceBase):
citations_enabled: bool = True citations_enabled: bool = True
qna_custom_instructions: str | None = None qna_custom_instructions: str | None = None
class SearchSpaceUpdate(BaseModel): class WorkspaceUpdate(BaseModel):
name: str | None = None name: str | None = None
description: str | None = None description: str | None = None
citations_enabled: bool | None = None citations_enabled: bool | None = None
@ -24,11 +24,11 @@ class SearchSpaceUpdate(BaseModel):
ai_file_sort_enabled: bool | None = None ai_file_sort_enabled: bool | None = None
class SearchSpaceApiAccessUpdate(BaseModel): class WorkspaceApiAccessUpdate(BaseModel):
api_access_enabled: bool api_access_enabled: bool
class SearchSpaceRead(SearchSpaceBase, IDModel, TimestampModel): class WorkspaceRead(WorkspaceBase, IDModel, TimestampModel):
id: int id: int
created_at: datetime created_at: datetime
user_id: uuid.UUID user_id: uuid.UUID
@ -41,8 +41,8 @@ class SearchSpaceRead(SearchSpaceBase, IDModel, TimestampModel):
model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)
class SearchSpaceWithStats(SearchSpaceRead): class WorkspaceWithStats(WorkspaceRead):
"""Extended search space info with member count and ownership status.""" """Extended workspace info with member count and ownership status."""
member_count: int = 1 member_count: int = 1
is_owner: bool = False is_owner: bool = False