feat: implement workspace management and member invitations
- Added tenant API for managing workspaces, including listing, creating, and inviting members. - Introduced new models for organizations, workspaces, and workspace memberships in the backend. - Created frontend components for workspace administration, allowing users to manage workspaces and invite members. - Updated document listing to support workspace-specific filtering. - Implemented account settings page for user profile management and password changes. - Added end-to-end tests for workspace administration and dashboard functionalities.
This commit is contained in:
parent
809235e962
commit
bf5cd44dc1
20 changed files with 928 additions and 27 deletions
|
|
@ -22,6 +22,7 @@ class DocumentCreate(BaseModel):
|
|||
template_id: str | None = None
|
||||
stead_id: str | None = None
|
||||
parent_page_id: str | None = None
|
||||
workspace_id: int | None = None
|
||||
|
||||
|
||||
class DocumentUpdate(BaseModel):
|
||||
|
|
@ -30,6 +31,7 @@ class DocumentUpdate(BaseModel):
|
|||
starred: bool | None = None
|
||||
stead_id: str | None = None
|
||||
parent_page_id: str | None = None
|
||||
workspace_id: int | None = None
|
||||
|
||||
|
||||
class ShareRequest(BaseModel):
|
||||
|
|
@ -53,6 +55,7 @@ class DocumentResponse(BaseModel):
|
|||
owner_id: int | None = None
|
||||
visibility: Visibility = "private"
|
||||
members: list[DocumentMember] = Field(default_factory=list)
|
||||
workspace_id: int | None = None
|
||||
|
||||
|
||||
class DocumentVersionResponse(BaseModel):
|
||||
|
|
|
|||
58
backend/app/schemas/tenant.py
Normal file
58
backend/app/schemas/tenant.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, EmailStr, Field
|
||||
|
||||
TenantRole = Literal["owner", "admin", "member", "viewer"]
|
||||
|
||||
|
||||
class WorkspaceCreate(BaseModel):
|
||||
organization_name: str = Field(min_length=2, max_length=160)
|
||||
workspace_name: str = Field(min_length=2, max_length=160)
|
||||
|
||||
|
||||
class WorkspaceResponse(BaseModel):
|
||||
id: int
|
||||
organization_id: int
|
||||
organization_name: str
|
||||
name: str
|
||||
slug: str
|
||||
role: TenantRole
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class MemberResponse(BaseModel):
|
||||
user_id: int
|
||||
email: EmailStr
|
||||
full_name: str
|
||||
username: str
|
||||
role: TenantRole
|
||||
joined_at: datetime
|
||||
|
||||
|
||||
class InvitationCreate(BaseModel):
|
||||
email: EmailStr
|
||||
role: Literal["admin", "member", "viewer"] = "member"
|
||||
|
||||
|
||||
class InvitationResponse(BaseModel):
|
||||
id: int
|
||||
workspace_id: int
|
||||
email: EmailStr
|
||||
role: TenantRole
|
||||
expires_at: datetime
|
||||
accepted: bool
|
||||
token: str | None = None
|
||||
invite_url: str | None = None
|
||||
|
||||
|
||||
class AuditEventResponse(BaseModel):
|
||||
id: int
|
||||
action: str
|
||||
target: str
|
||||
actor_id: int
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class RoleUpdate(BaseModel):
|
||||
role: Literal["admin", "member", "viewer"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue