Add comprehensive tests for session cleanup and async CRUD operations; improve error handling and validation across schemas and API routes

- Introduced extensive tests for session cleanup, async session CRUD methods, and concurrent cleanup to ensure reliability and efficiency.
- Enhanced `schemas/users.py` with reusable password strength validation logic.
- Improved error handling in `admin.py` routes by replacing `detail` with `message` for consistency and readability.
This commit is contained in:
Felipe Cardoso
2025-11-01 05:22:45 +01:00
parent c79b76be41
commit 035e6af446
11 changed files with 3644 additions and 88 deletions

View File

@@ -0,0 +1,78 @@
"""add_performance_indexes
Revision ID: 1174fffbe3e4
Revises: fbf6318a8a36
Create Date: 2025-11-01 04:15:25.367010
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = '1174fffbe3e4'
down_revision: Union[str, None] = 'fbf6318a8a36'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Add performance indexes for optimized queries."""
# Index for session cleanup queries
# Optimizes: DELETE WHERE is_active = FALSE AND expires_at < now AND created_at < cutoff
op.create_index(
'ix_user_sessions_cleanup',
'user_sessions',
['is_active', 'expires_at', 'created_at'],
unique=False,
postgresql_where=sa.text('is_active = false')
)
# Index for user search queries (basic trigram support without pg_trgm extension)
# Optimizes: WHERE email ILIKE '%search%' OR first_name ILIKE '%search%'
# Note: For better performance, consider enabling pg_trgm extension
op.create_index(
'ix_users_email_lower',
'users',
[sa.text('LOWER(email)')],
unique=False,
postgresql_where=sa.text('deleted_at IS NULL')
)
op.create_index(
'ix_users_first_name_lower',
'users',
[sa.text('LOWER(first_name)')],
unique=False,
postgresql_where=sa.text('deleted_at IS NULL')
)
op.create_index(
'ix_users_last_name_lower',
'users',
[sa.text('LOWER(last_name)')],
unique=False,
postgresql_where=sa.text('deleted_at IS NULL')
)
# Index for organization search
op.create_index(
'ix_organizations_name_lower',
'organizations',
[sa.text('LOWER(name)')],
unique=False
)
def downgrade() -> None:
"""Remove performance indexes."""
# Drop indexes in reverse order
op.drop_index('ix_organizations_name_lower', table_name='organizations')
op.drop_index('ix_users_last_name_lower', table_name='users')
op.drop_index('ix_users_first_name_lower', table_name='users')
op.drop_index('ix_users_email_lower', table_name='users')
op.drop_index('ix_user_sessions_cleanup', table_name='user_sessions')