From c4fa771dd89cb70d315b52f7febf11a8b2e8ed30 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Fri, 21 Aug 2026 00:31:48 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20I.4=20Performance=20=E2=80=94=20Redis?= =?UTF-8?q?=20cache=20for=20contact=20list=20queries=20(60s=20TTL,=20first?= =?UTF-8?q?=203=20pages,=20no=20search),=20connection=20pooling=20already?= =?UTF-8?q?=20exists=20(pool=5Fsize=3D20),=20selectinload=20already=20used?= =?UTF-8?q?,=203=20performance=20test=20files=20exist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/contact_service.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/services/contact_service.py b/app/services/contact_service.py index bc7fdad..e28c883 100644 --- a/app/services/contact_service.py +++ b/app/services/contact_service.py @@ -158,6 +158,16 @@ async def list_contacts( """ from app.core.visibility import apply_visibility_filter + # I.4 Performance: Cache simple list queries (no search, no cursor, first 3 pages) + use_cache = not search and not cursor and page <= 3 and not folder_id + cache_key = f"contacts:list:{tenant_id}:{page}:{page_size}:{contact_type or 'all'}:{sort_by}:{sort_order}:{user_id or 'admin'}:{is_system_admin}" + if use_cache: + from app.core.cache import cache_get + cached = await cache_get(cache_key) + if cached: + return cached + + base = select(Contact).where( Contact.tenant_id == tenant_id, Contact.deleted_at.is_(None), @@ -218,7 +228,7 @@ async def list_contacts( if use_keyset and len(contacts) == page_size and contacts: next_cursor = str(contacts[-1].id) - return { + result = { "items": [_serialize_contact(c) for c in contacts], "total": total, "page": page, @@ -226,6 +236,13 @@ async def list_contacts( "next_cursor": next_cursor, } + # I.4 Performance: Cache the result for simple queries + if use_cache: + from app.core.cache import cache_set + await cache_set(cache_key, result, ttl=60) # 60 second cache + + return result + async def get_contact(db: AsyncSession, tenant_id: uuid.UUID, contact_id: str, user_id: uuid.UUID | None = None, is_system_admin: bool = False) -> dict: