Coverage for api/roles/schema.py: 100.00%
54 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-03 15:30 +0000
1from pydantic import BaseModel, Field
3from core.config import settings
6class RoleResponse(BaseModel):
7 id: str = Field(..., description="Role ID")
8 name: str = Field(..., description="Role name")
9 description: str | None = Field(None, description="Role description")
10 level: int = Field(..., description="Role privilege level (higher is more privileged)")
13class RolesListResponse(BaseModel):
14 roles: list[RoleResponse] = Field(..., description="List of roles")
15 actor_level: int = Field(..., description="Current user's role level")
16 actor_role_id: str | None = Field(
17 None, description="Current user's primary role ID (cannot self-edit/delete)"
18 )
21class RoleCreate(BaseModel):
22 name: str = Field(..., min_length=1, max_length=100, description="Role name")
23 description: str | None = Field(None, max_length=500, description="Role description")
24 level: int = Field(
25 ...,
26 ge=1,
27 le=settings.MAX_CUSTOM_ROLE_LEVEL,
28 description="Role privilege level (must be lower than the actor's level)",
29 )
32class RoleUpdate(BaseModel):
33 name: str | None = Field(None, min_length=1, max_length=100, description="Role name")
34 description: str | None = Field(None, max_length=500, description="Role description")
35 level: int | None = Field(
36 None,
37 ge=1,
38 le=settings.MAX_CUSTOM_ROLE_LEVEL,
39 description="Role privilege level (must be lower than the actor's level)",
40 )
43class RoleAttributesMapping(BaseModel):
44 attributes: dict[str, bool] = Field(
45 ...,
46 description="Role attributes mapping (attribute_name: value)",
47 example={"view-users": True, "manage-users": False, "view-roles": True},
48 )
50 @classmethod
51 def get_example_response(cls):
52 return {
53 "code": 200,
54 "message": "Role attributes mapping example",
55 "data": {"attributes": {"view-users": True, "manage-users": False, "view-roles": True}},
56 }
59class RoleAttributeDetail(BaseModel):
60 name: str = Field(..., description="Attribute name", example="view-users")
61 value: bool = Field(..., description="Whether the role has this attribute", example=True)
64class RoleAttributesGroup(BaseModel):
65 group: str = Field(..., description="Top-level group key", example="user-role-management")
66 categories: dict[str, list[RoleAttributeDetail]] = Field(
67 ..., description="Categories inside this group (category -> attributes)"
68 )
71class RoleAttributesGroupedResponse(BaseModel):
72 groups: list[RoleAttributesGroup] = Field(
73 ..., description="Role attributes grouped by group and category"
74 )
76 @classmethod
77 def get_example_response(cls):
78 return {
79 "code": 200,
80 "message": "Successfully retrieved role attributes mapping",
81 "data": {
82 "groups": [
83 {
84 "group": "user-role-management",
85 "categories": {
86 "user": [
87 {"name": "view-users", "value": True},
88 {"name": "manage-users", "value": False},
89 ],
90 "role": [{"name": "view-roles", "value": True}],
91 },
92 }
93 ]
94 },
95 }
98class AttributeMappingResult(BaseModel):
99 attribute_id: str = Field(..., description="Attribute ID")
100 status: str = Field(
101 ..., description="Processing status: success, failed", pattern="^(success|failed)$"
102 )
103 message: str = Field(..., description="Result message")
106class RoleAttributeMappingBatchResponse(BaseModel):
107 results: list[AttributeMappingResult] = Field(
108 ..., description="Individual attribute mapping results"
109 )
110 total_attributes: int = Field(..., description="Total number of attributes processed")
111 success_count: int = Field(..., description="Number of successfully processed attributes")
112 failed_count: int = Field(..., description="Number of failed attributes")
115class PermissionCheckRequest(BaseModel):
116 attributes: list[str] | None = Field(
117 None,
118 min_items=1,
119 description=(
120 "List of permission attributes to check. If not provided, returns all user permissions."
121 ),
122 example=["view-users", "manage-roles"],
123 )
126class PermissionCheckResponse(BaseModel):
127 permissions: dict[str, bool] = Field(
128 ...,
129 description="Permission check results (attribute_name: has_permission)",
130 example={
131 "view-users": True,
132 "manage-users": False,
133 "view-roles": True,
134 "manage-roles": False,
135 },
136 )
138 @classmethod
139 def get_example_response(cls):
140 return {
141 "code": 200,
142 "message": "User permissions retrieved",
143 "data": {
144 "permissions": {
145 "view-users": True,
146 "manage-users": False,
147 "view-roles": True,
148 "manage-roles": False,
149 }
150 },
151 }
154role_attributes_success_response_example = {
155 "code": 200,
156 "message": "All role attributes processed successfully",
157 "data": {
158 "results": [
159 {"attribute_id": "attr-001", "status": "success", "message": "Updated successfully"},
160 {"attribute_id": "attr-002", "status": "success", "message": "Updated successfully"},
161 ],
162 "total_attributes": 2,
163 "success_count": 2,
164 "failed_count": 0,
165 },
166}
168role_attributes_partial_response_example = {
169 "code": 207,
170 "message": "Role attributes processed with partial success",
171 "data": {
172 "results": [
173 {"attribute_id": "attr-001", "status": "success", "message": "Updated successfully"},
174 {"attribute_id": "attr-002", "status": "failed", "message": "Invalid attribute ID"},
175 ],
176 "total_attributes": 2,
177 "success_count": 1,
178 "failed_count": 1,
179 },
180}
182role_attributes_failed_response_example = {
183 "code": 400,
184 "message": "All role attributes failed to process",
185 "data": {
186 "results": [
187 {
188 "attribute_id": "invalid-attr-001",
189 "status": "failed",
190 "message": "Invalid attribute ID",
191 },
192 {
193 "attribute_id": "invalid-attr-002",
194 "status": "failed",
195 "message": "Invalid attribute ID",
196 },
197 ],
198 "total_attributes": 2,
199 "success_count": 0,
200 "failed_count": 2,
201 },
202}