feat: extract admin account management rework from PR 124 (#138)
* feat: reorganize admin panel around accounts * feat: expand admin customer account controls * feat: add admin account detail management * fix: remove unused admin account icon import * refactor: design critique fixes for account pages - Admin accounts: replace dense card grid with compact DataTable - Account settings: remove redundant hero card, stat grid, header pills - Fix bg-accent (orange) misuse on decorative elements across 7 files - Add ConfirmButton for destructive actions (deactivate, remove member) - Replace single-field modals with inline editing (plan, trial) - Add contextual help: display code tooltip, improved empty states - Non-owner aside explanation for hidden owner-only sections - Admin sidebar: group 11 items into 5 labeled sections - Rename UsersPage.tsx → AccountsPage.tsx to match route - Fix border radius consistency, hide zero-count badges Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use get_admin_db for all new admin account endpoints All admin endpoints query across tenants without a tenant context. get_db (app-role, subject to RLS) was never imported and would crash at runtime — replace all 6 occurrences with get_admin_db (BYPASSRLS). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #138.
This commit is contained in:
@@ -28,6 +28,110 @@ class ActivityEntry(BaseModel):
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# --- Admin Accounts & People Search ---
|
||||
|
||||
class AdminUserListItem(BaseModel):
|
||||
id: UUID
|
||||
email: EmailStr
|
||||
name: str
|
||||
role: str
|
||||
is_super_admin: bool = False
|
||||
is_active: bool = True
|
||||
account_id: Optional[UUID] = None
|
||||
account_role: Optional[str] = None
|
||||
account_name: Optional[str] = None
|
||||
account_display_code: Optional[str] = None
|
||||
created_at: datetime
|
||||
last_login: Optional[datetime] = None
|
||||
deleted_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class AdminUserListResponse(BaseModel):
|
||||
items: list[AdminUserListItem]
|
||||
total: int
|
||||
page: int
|
||||
per_page: int
|
||||
|
||||
|
||||
class AdminAccountMember(BaseModel):
|
||||
id: UUID
|
||||
email: EmailStr
|
||||
name: str
|
||||
role: str
|
||||
is_super_admin: bool = False
|
||||
is_active: bool = True
|
||||
account_role: Optional[str] = None
|
||||
created_at: datetime
|
||||
last_login: Optional[datetime] = None
|
||||
deleted_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class AdminAccountOwnerSummary(BaseModel):
|
||||
id: UUID
|
||||
name: str
|
||||
email: EmailStr
|
||||
|
||||
|
||||
class AdminAccountSubscriptionSummary(BaseModel):
|
||||
id: UUID
|
||||
plan: str
|
||||
status: str
|
||||
billing_interval: Optional[str] = None
|
||||
current_period_end: Optional[datetime] = None
|
||||
cancel_at_period_end: bool = False
|
||||
|
||||
|
||||
class AdminAccountUsageSummary(BaseModel):
|
||||
tree_count: int = 0
|
||||
session_count_this_month: int = 0
|
||||
|
||||
|
||||
class AdminAccountInviteSummary(BaseModel):
|
||||
id: UUID
|
||||
email: EmailStr
|
||||
role: str
|
||||
expires_at: Optional[datetime] = None
|
||||
created_at: datetime
|
||||
used_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class AdminAccountListItem(BaseModel):
|
||||
id: UUID
|
||||
name: str
|
||||
display_code: str
|
||||
created_at: datetime
|
||||
owner_id: Optional[UUID] = None
|
||||
owner: Optional[AdminAccountOwnerSummary] = None
|
||||
subscription: Optional[AdminAccountSubscriptionSummary] = None
|
||||
usage: AdminAccountUsageSummary = Field(default_factory=AdminAccountUsageSummary)
|
||||
member_count: int = 0
|
||||
active_member_count: int = 0
|
||||
pending_invite_count: int = 0
|
||||
sso_enabled: bool = False
|
||||
branding_company_name: Optional[str] = None
|
||||
members: list[AdminAccountMember] = Field(default_factory=list)
|
||||
|
||||
|
||||
class AdminAccountListResponse(BaseModel):
|
||||
items: list[AdminAccountListItem]
|
||||
total: int
|
||||
page: int
|
||||
per_page: int
|
||||
|
||||
|
||||
class AdminAccountDetailResponse(AdminAccountListItem):
|
||||
invites: list[AdminAccountInviteSummary] = Field(default_factory=list)
|
||||
|
||||
|
||||
class AdminAccountCreate(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=255)
|
||||
plan: Literal["free", "pro", "team"] = "free"
|
||||
|
||||
|
||||
class AdminAccountUpdate(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=255)
|
||||
|
||||
|
||||
# --- Audit Logs ---
|
||||
|
||||
class AuditLogEntry(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user