Coverage for src/cstlcore/admin/models.py: 100%
212 statements
« prev ^ index » next coverage.py v7.9.1, created at 2026-02-19 12:46 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2026-02-19 12:46 +0000
1"""
2Admin dashboard and management response models
3"""
5from datetime import datetime
6from typing import List, Optional, Literal
7from pydantic import BaseModel, Field
10# Dashboard Models
11class UserStats(BaseModel):
12 total: int
13 active: int
14 new_today: int = Field(alias="newToday")
15 growth: float # percentage
18class ConstellationStats(BaseModel):
19 total: int
20 public: int
21 new_today: int = Field(alias="newToday")
22 growth: float # percentage
25class EngagementStats(BaseModel):
26 total_views: int = Field(alias="totalViews")
27 total_likes: int = Field(alias="totalLikes")
28 views_today: int = Field(alias="viewsToday")
29 engagement_rate: float = Field(alias="engagementRate") # percentage
32class SystemStats(BaseModel):
33 storage_used: float = Field(alias="storageUsed") # GB
34 uptime: float # percentage
35 active_connections: int = Field(alias="activeConnections")
36 response_time: float = Field(alias="responseTime") # ms
39class DashboardStatsResponse(BaseModel):
40 users: UserStats
41 constellations: ConstellationStats
42 engagement: EngagementStats
43 system: SystemStats
46class ActivityItem(BaseModel):
47 id: str
48 type: Literal["user_registered", "constellation_created", "constellation_shared", "user_verified"]
49 description: str
50 timestamp: datetime
51 user: Optional[str] = None
54class DashboardActivityResponse(BaseModel):
55 activities: List[ActivityItem]
58class AlertItem(BaseModel):
59 id: str
60 type: Literal["warning", "error", "info"]
61 message: str
62 timestamp: datetime
65class DashboardAlertsResponse(BaseModel):
66 alerts: List[AlertItem]
69# User Management Models
70class AdminUserItem(BaseModel):
71 id: str
72 email: str
73 name: str
74 created_at: datetime = Field(alias="createdAt")
75 last_login_at: Optional[datetime] = Field(alias="lastLoginAt")
76 is_active: bool = Field(alias="isActive")
77 is_verified: bool = Field(alias="isVerified")
78 subscription_type: Literal["free", "pro", "enterprise"] = Field(alias="subscriptionType")
79 constellations_count: int = Field(alias="constellationsCount")
80 total_elements: int = Field(alias="totalElements")
81 total_links: int = Field(alias="totalLinks")
82 storage_used: float = Field(alias="storageUsed") # in MB
85class UsersListResponse(BaseModel):
86 users: List[AdminUserItem]
87 total: int
88 page: int
89 limit: int
92class UserToggleStatusResponse(BaseModel):
93 success: bool
94 message: str
95 user: dict
98class UserSendVerificationResponse(BaseModel):
99 success: bool
100 message: str
103class UserConstellationItem(BaseModel):
104 id: str
105 title: str
106 is_public: bool = Field(alias="isPublic")
107 elements_count: int = Field(alias="elementsCount")
108 links_count: int = Field(alias="linksCount")
109 created_at: datetime = Field(alias="createdAt")
112class UserDetailResponse(BaseModel):
113 user: dict
116# Constellation Management Models
117class AdminConstellationItem(BaseModel):
118 id: str
119 title: str
120 description: str
121 created_at: datetime = Field(alias="createdAt")
122 updated_at: datetime = Field(alias="updatedAt")
123 is_public: bool = Field(alias="isPublic")
124 owner_name: str = Field(alias="ownerName")
125 owner_email: str = Field(alias="ownerEmail")
126 collaborators_count: int = Field(alias="collaboratorsCount")
127 elements_count: int = Field(alias="elementsCount")
128 links_count: int = Field(alias="linksCount")
129 images_count: int = Field(alias="imagesCount")
130 views_count: int = Field(alias="viewsCount")
131 likes_count: int = Field(alias="likesCount")
132 storage_used: float = Field(alias="storageUsed") # in MB
133 last_activity: datetime = Field(alias="lastActivity")
134 tags: List[str]
137class ConstellationsListResponse(BaseModel):
138 constellations: List[AdminConstellationItem]
139 total: int
140 page: int
141 limit: int
144class ConstellationToggleVisibilityResponse(BaseModel):
145 success: bool
146 message: str
147 constellation: dict
150class ConstellationDeleteResponse(BaseModel):
151 success: bool
152 message: str
155class ConstellationDetailResponse(BaseModel):
156 constellation: dict
159# Permissions Management Models
160class PermissionItem(BaseModel):
161 id: str
162 user_id: str = Field(alias="userId")
163 user_name: str = Field(alias="userName")
164 user_email: str = Field(alias="userEmail")
165 constellation_id: str = Field(alias="constellationId")
166 constellation_title: str = Field(alias="constellationTitle")
167 role: Literal["owner", "admin", "editor", "viewer"]
168 granted_at: datetime = Field(alias="grantedAt")
169 granted_by: str = Field(alias="grantedBy")
170 last_accessed: Optional[datetime] = Field(alias="lastAccessed")
171 permissions: dict
174class PermissionsListResponse(BaseModel):
175 permissions: List[PermissionItem]
176 total: int
177 page: int
178 limit: int
181class UpdateRoleRequest(BaseModel):
182 role: Literal["admin", "editor", "viewer"]
185class UpdateRoleResponse(BaseModel):
186 success: bool
187 message: str
188 permission: dict
191class RevokePermissionResponse(BaseModel):
192 success: bool
193 message: str
196# Analytics Models
197class AnalyticsUserStats(BaseModel):
198 total_users: int = Field(alias="totalUsers")
199 active_users: int = Field(alias="activeUsers")
200 new_users_today: int = Field(alias="newUsersToday")
201 new_users_this_week: int = Field(alias="newUsersThisWeek")
202 new_users_this_month: int = Field(alias="newUsersThisMonth")
203 user_growth_rate: float = Field(alias="userGrowthRate") # percentage
204 average_session_duration: float = Field(alias="averageSessionDuration") # minutes
207class AnalyticsConstellationStats(BaseModel):
208 total_constellations: int = Field(alias="totalConstellations")
209 public_constellations: int = Field(alias="publicConstellations")
210 private_constellations: int = Field(alias="privateConstellations")
211 new_constellations_today: int = Field(alias="newConstellationsToday")
212 new_constellations_this_week: int = Field(alias="newConstellationsThisWeek")
213 new_constellations_this_month: int = Field(alias="newConstellationsThisMonth")
214 constellation_growth_rate: float = Field(alias="constellationGrowthRate") # percentage
215 average_elements_per_constellation: float = Field(alias="averageElementsPerConstellation")
216 average_links_per_constellation: float = Field(alias="averageLinksPerConstellation")
219class AnalyticsEngagementStats(BaseModel):
220 total_views: int = Field(alias="totalViews")
221 total_likes: int = Field(alias="totalLikes")
222 total_shares: int = Field(alias="totalShares")
223 total_comments: int = Field(alias="totalComments")
224 views_today: int = Field(alias="viewsToday")
225 views_this_week: int = Field(alias="viewsThisWeek")
226 views_this_month: int = Field(alias="viewsThisMonth")
227 engagement_rate: float = Field(alias="engagementRate") # percentage
230class AnalyticsSystemStats(BaseModel):
231 total_storage_used: float = Field(alias="totalStorageUsed") # in GB
232 average_storage_per_user: float = Field(alias="averageStoragePerUser") # in MB
233 total_images: int = Field(alias="totalImages")
234 total_elements: int = Field(alias="totalElements")
235 total_links: int = Field(alias="totalLinks")
236 database_size: float = Field(alias="databaseSize") # in GB
237 active_connections: int = Field(alias="activeConnections")
240class TopConstellationItem(BaseModel):
241 id: str
242 title: str
243 owner: str
244 views: int
245 likes: int
246 created_at: datetime = Field(alias="createdAt")
249class TopUserItem(BaseModel):
250 id: str
251 name: str
252 email: str
253 constellations_count: int = Field(alias="constellationsCount")
254 total_views: int = Field(alias="totalViews")
255 joined_at: datetime = Field(alias="joinedAt")
258class AnalyticsResponse(BaseModel):
259 user_stats: AnalyticsUserStats = Field(alias="userStats")
260 constellation_stats: AnalyticsConstellationStats = Field(alias="constellationStats")
261 engagement_stats: AnalyticsEngagementStats = Field(alias="engagementStats")
262 system_stats: AnalyticsSystemStats = Field(alias="systemStats")
263 top_constellations: List[TopConstellationItem] = Field(alias="topConstellations")
264 top_users: List[TopUserItem] = Field(alias="topUsers")
268class GraphMetricsResponse(BaseModel):
269 """Graph theory metrics for a constellation's narrative structure"""
271 constellation_id: str = Field(alias="constellationId")
272 element_count: int = Field(alias="elementCount", description="Number of nodes (N)")
273 relation_count: int = Field(
274 alias="relationCount", description="Number of unique undirected edges (M)"
275 )
276 graph_density: float = Field(
277 alias="graphDensity", description="Graph density D = 2M / N(N-1)"
278 )
279 average_degree: float = Field(
280 alias="averageDegree", description="Average degree k = 2M / N"
281 )
282 interpretation_level: str = Field(alias="interpretationLevel")
285class GraphMetricsSummaryItem(BaseModel):
286 """Summary metrics for a single constellation"""
288 constellation_id: str = Field(alias="constellationId")
289 constellation_name: str = Field(alias="constellationName")
290 element_count: int = Field(alias="elementCount")
291 relation_count: int = Field(alias="relationCount")
292 graph_density: float = Field(alias="graphDensity")
293 average_degree: float = Field(alias="averageDegree")
294 interpretation_level: str = Field(alias="interpretationLevel")
297class GraphMetricsBulkResponse(BaseModel):
298 """Bulk graph metrics for all constellations"""
300 constellations: List[GraphMetricsSummaryItem]
301 total: int
302 average_density: float = Field(alias="averageDensity")
303 average_elements: float = Field(alias="averageElements")
304 average_relations: float = Field(alias="averageRelations")