fix(contacts): stabilize contacts pagination and company enrichment
This commit is contained in:
parent
aa87285cab
commit
0ed450451d
19
RELEASE_NOTES_v2.3.1.md
Normal file
19
RELEASE_NOTES_v2.3.1.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# v2.3.1 — 16. maj 2026
|
||||||
|
|
||||||
|
## Fix: contacts pagination and company enrichment
|
||||||
|
|
||||||
|
- **Hotfix:** Contacts showing too few rows (contacts pagination bug)
|
||||||
|
- **Fix:** File `app/contacts/backend/router_simple.py` to stabilize pagination and company enrichment
|
||||||
|
|
||||||
|
## Contacts list
|
||||||
|
|
||||||
|
- Fixed bug where contacts list showed too few rows (pagination issue)
|
||||||
|
- Stabilized company enrichment data for contacts
|
||||||
|
|
||||||
|
## File changed
|
||||||
|
|
||||||
|
- `app/contacts/backend/router_simple.py`
|
||||||
|
|
||||||
|
## Affected versions
|
||||||
|
|
||||||
|
- v2.3.1
|
||||||
@ -119,32 +119,55 @@ async def get_contacts(
|
|||||||
if is_active is not None:
|
if is_active is not None:
|
||||||
where_clauses.append("c.is_active = %s")
|
where_clauses.append("c.is_active = %s")
|
||||||
params.append(is_active)
|
params.append(is_active)
|
||||||
|
|
||||||
|
if customer_id is not None:
|
||||||
|
where_clauses.append(
|
||||||
|
"EXISTS (SELECT 1 FROM contact_companies cc WHERE cc.contact_id = c.id AND cc.customer_id = %s)"
|
||||||
|
)
|
||||||
|
params.append(customer_id)
|
||||||
|
|
||||||
where_sql = "WHERE " + " AND ".join(where_clauses) if where_clauses else ""
|
where_sql = "WHERE " + " AND ".join(where_clauses) if where_clauses else ""
|
||||||
|
|
||||||
# Count total (needs alias c for consistency)
|
# Count total (distinct id for consistency with optional filters/joins)
|
||||||
count_query = f"SELECT COUNT(*) as count FROM contacts c {where_sql}"
|
count_query = f"SELECT COUNT(DISTINCT c.id) as count FROM contacts c {where_sql}"
|
||||||
count_result = execute_query(count_query, tuple(params))
|
count_result = execute_query(count_query, tuple(params))
|
||||||
total = count_result[0]['count'] if count_result else 0
|
total = count_result[0]['count'] if count_result else 0
|
||||||
|
|
||||||
# Get contacts with company info
|
# Step 1: Fetch contacts only (stable pagination)
|
||||||
query = f"""
|
contacts_query = f"""
|
||||||
SELECT
|
SELECT
|
||||||
c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
|
c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
|
||||||
c.title, c.department, c.user_company, c.is_active, c.created_at, c.updated_at,
|
c.title, c.department, c.user_company, c.is_active, c.created_at, c.updated_at
|
||||||
COUNT(DISTINCT cc.customer_id) as company_count,
|
|
||||||
ARRAY_AGG(DISTINCT cu.name ORDER BY cu.name) FILTER (WHERE cu.name IS NOT NULL) as company_names
|
|
||||||
FROM contacts c
|
FROM contacts c
|
||||||
LEFT JOIN contact_companies cc ON c.id = cc.contact_id
|
|
||||||
LEFT JOIN customers cu ON cc.customer_id = cu.id
|
|
||||||
{where_sql}
|
{where_sql}
|
||||||
GROUP BY c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
|
ORDER BY c.last_name, c.first_name, c.id
|
||||||
c.title, c.department, c.user_company, c.is_active, c.created_at, c.updated_at
|
|
||||||
ORDER BY company_count DESC, c.last_name, c.first_name, c.id
|
|
||||||
LIMIT %s OFFSET %s
|
LIMIT %s OFFSET %s
|
||||||
"""
|
"""
|
||||||
params.extend([limit, offset])
|
contacts_params = list(params)
|
||||||
contacts = execute_query(query, tuple(params))
|
contacts_params.extend([limit, offset])
|
||||||
|
contacts = execute_query(contacts_query, tuple(contacts_params)) or []
|
||||||
|
|
||||||
|
# Step 2: Enrich page contacts with aggregated company info
|
||||||
|
if contacts:
|
||||||
|
contact_ids = [row["id"] for row in contacts]
|
||||||
|
placeholders = ",".join(["%s"] * len(contact_ids))
|
||||||
|
companies_query = f"""
|
||||||
|
SELECT
|
||||||
|
cc.contact_id,
|
||||||
|
COUNT(DISTINCT cc.customer_id) AS company_count,
|
||||||
|
ARRAY_AGG(DISTINCT cu.name ORDER BY cu.name) FILTER (WHERE cu.name IS NOT NULL) AS company_names
|
||||||
|
FROM contact_companies cc
|
||||||
|
LEFT JOIN customers cu ON cc.customer_id = cu.id
|
||||||
|
WHERE cc.contact_id IN ({placeholders})
|
||||||
|
GROUP BY cc.contact_id
|
||||||
|
"""
|
||||||
|
company_rows = execute_query(companies_query, tuple(contact_ids)) or []
|
||||||
|
company_map = {row["contact_id"]: row for row in company_rows}
|
||||||
|
|
||||||
|
for contact in contacts:
|
||||||
|
info = company_map.get(contact["id"])
|
||||||
|
contact["company_count"] = int(info["company_count"]) if info and info.get("company_count") is not None else 0
|
||||||
|
contact["company_names"] = info.get("company_names") if info and info.get("company_names") else []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"total": total,
|
"total": total,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user