Skip to content

Commit e379a0c

Browse files
committed
refactor: add docstrings to test fixtures and perform comprehensive codebase-wide hardening and schema updates
1 parent c79b0e5 commit e379a0c

114 files changed

Lines changed: 3042 additions & 259 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

None

Whitespace-only changes.

app/core/admin/admin.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,71 @@
1919

2020

2121
class AdminAccessMixin(ModelView):
22+
"""
23+
Mixin that restricts access to admin model views to ADMIN users only.
24+
25+
Provides ``is_accessible`` and ``is_visible`` checks that ensure only
26+
users with the ``ADMIN`` role can view and interact with the model
27+
in the SQLAdmin panel.
28+
"""
29+
2230
def is_accessible(self, request: Request) -> bool:
31+
"""
32+
Check whether the current user has ADMIN role for access control.
33+
34+
Args:
35+
request: The incoming HTTP request with user information attached
36+
to ``request.state``.
37+
38+
Returns:
39+
``True`` if the authenticated user has the ``ADMIN`` role;
40+
``False`` otherwise.
41+
"""
2342
user = getattr(request.state, 'user', None)
2443
return user is not None and user.role == UserRole.ADMIN
2544

2645
def is_visible(self, request: Request) -> bool:
46+
"""
47+
Check whether the current user has ADMIN role for menu visibility.
48+
49+
Args:
50+
request: The incoming HTTP request with user information attached
51+
to ``request.state``.
52+
53+
Returns:
54+
``True`` if the authenticated user has the ``ADMIN`` role;
55+
``False`` otherwise.
56+
"""
2757
user = getattr(request.state, 'user', None)
2858
return user is not None and user.role == UserRole.ADMIN
2959

3060

3161
class AdminPanelFormatter:
62+
"""
63+
Utility class providing formatter methods for displaying data in the admin panel.
64+
65+
Each static method produces HTML markup (via ``Markup``) suitable for
66+
use as a SQLAdmin column formatter, rendering badges, links, and
67+
styled status indicators.
68+
"""
69+
3270
@staticmethod
3371
def status_formatter(model: Any, name: Any) -> Any:
72+
"""
73+
Render a status field value as a colored Bootstrap badge.
74+
75+
Maps common status and role values to appropriate Bootstrap badge
76+
colors (e.g., ``ACTIVE`` to green, ``CANCELLED`` to red).
77+
78+
Args:
79+
model: The SQLAlchemy model instance being formatted.
80+
name: The attribute name to read from the model (e.g., ``status``,
81+
``role``, ``target_role``).
82+
83+
Returns:
84+
A ``Markup`` string containing the HTML badge, or the raw
85+
attribute value if the name is not a recognized status field.
86+
"""
3487
status_colors = {
3588
'ACTIVE': 'success',
3689
'PENDING': 'warning',
@@ -56,27 +109,76 @@ def status_formatter(model: Any, name: Any) -> Any:
56109

57110
@staticmethod
58111
def user_link_formatter(model: Any, name: Any) -> Any:
112+
"""
113+
Render a user ID as a clickable link to the user detail page.
114+
115+
Args:
116+
model: The SQLAlchemy model instance being formatted.
117+
name: The attribute name holding the user ID.
118+
119+
Returns:
120+
A ``Markup`` anchor tag linking to ``/admin/user/details/<id>``,
121+
or ``'N/A'`` if the user ID is empty.
122+
"""
59123
user_id = getattr(model, name)
60124
if not user_id:
61125
return 'N/A'
62126
return Markup(f'<a href="/admin/user/details/{user_id}">{user_id}</a>')
63127

64128
@staticmethod
65129
def product_link_formatter(model: Any, name: Any) -> Any:
130+
"""
131+
Render a product ID as a clickable link to the product detail page.
132+
133+
Args:
134+
model: The SQLAlchemy model instance being formatted.
135+
name: The attribute name holding the product ID.
136+
137+
Returns:
138+
A ``Markup`` anchor tag linking to ``/admin/product/details/<id>``,
139+
or ``'N/A'`` if the product ID is empty.
140+
"""
66141
product_id = getattr(model, name)
67142
if not product_id:
68143
return 'N/A'
69144
return Markup(f'<a href="/admin/product/details/{product_id}">{product_id}</a>')
70145

71146
@staticmethod
72147
def order_link_formatter(model: Any, name: Any) -> Any:
148+
"""
149+
Render an order ID as a clickable link to the order detail page.
150+
151+
Args:
152+
model: The SQLAlchemy model instance being formatted.
153+
name: The attribute name holding the order ID.
154+
155+
Returns:
156+
A ``Markup`` anchor tag linking to ``/admin/order/details/<id>``,
157+
or ``'N/A'`` if the order ID is empty.
158+
"""
73159
order_id = getattr(model, name)
74160
if not order_id:
75161
return 'N/A'
76162
return Markup(f'<a href="/admin/order/details/{order_id}">{order_id}</a>')
77163

78164
@staticmethod
79165
def docs_link_formatter(model: Any, name: Any) -> Any:
166+
"""
167+
Render verification document keys as clickable links for viewing.
168+
169+
Generates a comma-separated list of anchor tags, each linking to
170+
a verification document endpoint keyed by document type.
171+
172+
Args:
173+
model: The SQLAlchemy model instance being formatted (must have
174+
an ``id`` attribute).
175+
name: The attribute name holding the document data as a dict
176+
mapping document types to URLs or values.
177+
178+
Returns:
179+
A ``Markup`` string of comma-separated links, or ``'No docs'``
180+
if the document data is empty.
181+
"""
80182
docs = getattr(model, name)
81183
if not docs:
82184
return 'No docs'
@@ -91,6 +193,14 @@ def docs_link_formatter(model: Any, name: Any) -> Any:
91193

92194

93195
class VerificationRequestAdmin(AdminAccessMixin, model=VerificationRequest):
196+
"""
197+
Admin panel view for managing user verification requests.
198+
199+
Allows admins with ``ADMIN`` role to view, approve, or reject user
200+
verification requests. Approving a request automatically upgrades
201+
the user's role to the requested target role.
202+
"""
203+
94204
column_list = [
95205
VerificationRequest.id,
96206
VerificationRequest.user_id,
@@ -121,6 +231,20 @@ class VerificationRequestAdmin(AdminAccessMixin, model=VerificationRequest):
121231
async def on_model_change(
122232
self, data: dict, model: Any, is_created: bool, request: Request
123233
) -> None:
234+
"""
235+
Handle post-save logic for verification request updates.
236+
237+
When a verification request status is changed to ``APPROVED``, this
238+
hook automatically updates the associated user's role to the
239+
requested target role and marks the user as verified.
240+
241+
Args:
242+
data: Dictionary of form field values being saved.
243+
model: The ``VerificationRequest`` model instance being updated.
244+
is_created: ``True`` if this is a new record creation; ``False``
245+
for updates.
246+
request: The incoming HTTP request.
247+
"""
124248
if not is_created and data.get('status') == VerificationStatus.APPROVED:
125249
async with async_session_factory() as session:
126250
result = await session.execute(
@@ -133,6 +257,13 @@ async def on_model_change(
133257

134258

135259
class UserAdmin(ModelView, model=User):
260+
"""
261+
Admin panel view for managing user accounts.
262+
263+
Supports both ``ADMIN`` and ``MODERATOR`` roles. Moderators can view
264+
users but cannot create, edit, or delete records.
265+
"""
266+
136267
column_list = [User.id, User.email, User.role, User.is_active]
137268
column_searchable_list = [User.id, User.email]
138269
can_delete = False
@@ -142,6 +273,20 @@ class UserAdmin(ModelView, model=User):
142273
column_default_sort = [('created_at', True)]
143274

144275
def is_accessible(self, request: Request) -> bool:
276+
"""
277+
Check whether the requesting user can access this admin view.
278+
279+
Allows both ``ADMIN`` and ``MODERATOR`` roles. Moderators are
280+
restricted from create, edit, and delete operations.
281+
282+
Args:
283+
request: The incoming HTTP request with user information and
284+
route details.
285+
286+
Returns:
287+
``True`` if the user has an allowed role and the requested
288+
operation is permitted; ``False`` otherwise.
289+
"""
145290
user = getattr(request.state, 'user', None)
146291
if not user:
147292
return False
@@ -163,6 +308,14 @@ def is_accessible(self, request: Request) -> bool:
163308

164309

165310
class ProductAdmin(ModelView, model=Product):
311+
"""
312+
Admin panel view for managing product listings.
313+
314+
Allows admins to view product details, update moderation status,
315+
assign moderators, and add moderation comments. Creation and
316+
deletion are disabled.
317+
"""
318+
166319
column_list = [
167320
Product.id,
168321
Product.name,
@@ -199,6 +352,13 @@ class ProductAdmin(ModelView, model=Product):
199352

200353

201354
class OrderAdmin(ModelView, model=Order):
355+
"""
356+
Admin panel view for viewing customer orders.
357+
358+
Provides read-only access to order records with formatted status
359+
badges and user links. Creation, editing, and deletion are disabled.
360+
"""
361+
202362
column_list = [
203363
Order.id,
204364
Order.user_id,
@@ -220,6 +380,13 @@ class OrderAdmin(ModelView, model=Order):
220380

221381

222382
class ReservationAdmin(ModelView, model=Reservation):
383+
"""
384+
Admin panel view for viewing product reservations.
385+
386+
Displays reservation details including product, user, quantity, and
387+
expiration time. All mutations (create, edit, delete) are disabled.
388+
"""
389+
223390
column_list = [
224391
Reservation.id,
225392
Reservation.product_id,
@@ -246,6 +413,13 @@ class ReservationAdmin(ModelView, model=Reservation):
246413

247414

248415
class AuditLogAdmin(AdminAccessMixin, model=AuditLog):
416+
"""
417+
Admin panel view for viewing audit log entries.
418+
419+
Provides read-only access to the audit trail, showing all recorded
420+
actions, target objects, and actors. Restricted to ``ADMIN`` role.
421+
"""
422+
249423
column_list = [
250424
AuditLog.id,
251425
AuditLog.target_type,
@@ -269,6 +443,13 @@ class AuditLogAdmin(AdminAccessMixin, model=AuditLog):
269443

270444

271445
class APIKeyB2BPartnerAdmin(AdminAccessMixin, model=APIKeyB2BPartner):
446+
"""
447+
Admin panel view for managing B2B partner API keys.
448+
449+
Displays API key records with user associations, key names, and
450+
prefixes. Restricted to ``ADMIN`` role. Deletion is disabled.
451+
"""
452+
272453
column_list = [
273454
APIKeyB2BPartner.id,
274455
APIKeyB2BPartner.user_id,
@@ -289,6 +470,16 @@ class APIKeyB2BPartnerAdmin(AdminAccessMixin, model=APIKeyB2BPartner):
289470

290471

291472
def register_admin_views(admin: Any) -> None:
473+
"""
474+
Register all admin model views with the SQLAdmin instance.
475+
476+
Adds each admin view class (users, products, orders, reservations,
477+
audit logs, API keys, and verification requests) to the provided
478+
admin object.
479+
480+
Args:
481+
admin: The SQLAdmin ``Admin`` instance to register views with.
482+
"""
292483
admin.add_view(UserAdmin)
293484
admin.add_view(ProductAdmin)
294485
admin.add_view(OrderAdmin)

app/core/admin/admin_auth.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,30 @@
1111

1212

1313
class AdminAuth(AuthenticationBackend):
14+
"""
15+
Authentication backend for the SQLAdmin panel using session-based login.
16+
17+
Handles login, logout, and authentication for admin panel users. Only
18+
users with the ADMIN or MODERATOR role are granted access.
19+
"""
20+
1421
async def login(self, request: Request) -> bool:
22+
"""
23+
Authenticate an admin user via email and password from a form.
24+
25+
Extracts the username (email) and password fields from the
26+
submitted form, validates the credentials, and checks that the user
27+
has an admin or moderator role. On success, stores the user ID in
28+
the session.
29+
30+
Args:
31+
request: The incoming Starlette request containing form data with
32+
username and password fields.
33+
34+
Returns:
35+
True if authentication succeeds and the user has the
36+
required role; False otherwise.
37+
"""
1538
user_data = await request.form()
1639
email = user_data.get('username')
1740
password = user_data.get('password')
@@ -32,10 +55,34 @@ async def login(self, request: Request) -> bool:
3255
return False
3356

3457
async def logout(self, request: Request) -> bool:
58+
"""
59+
Log out the current admin user by clearing the session.
60+
61+
Args:
62+
request: The incoming Starlette request with an active session.
63+
64+
Returns:
65+
Always returns True after clearing the session.
66+
"""
3567
request.session.clear()
3668
return True
3769

3870
async def authenticate(self, request: Request) -> bool:
71+
"""
72+
Verify that the current session holds a valid admin or moderator user.
73+
74+
Looks up the user ID stored in the session under the token key
75+
and checks that the corresponding user exists and has either the
76+
ADMIN or MODERATOR role. The authenticated user is attached
77+
to request.state for downstream use.
78+
79+
Args:
80+
request: The incoming Starlette request with a session.
81+
82+
Returns:
83+
True if a valid admin/moderator user is authenticated;
84+
False if the session is empty or the user is invalid.
85+
"""
3986
token = request.session.get('token')
4087
if not token:
4188
return False

0 commit comments

Comments
 (0)