ultisuite-backend/internal/contacts/discovery/profile_sql.go
R3D347HR4Y 556d5f416d Enhance API and configuration for contact discovery and public sharing
- Introduced new endpoints for contact discovery, including scanning, listing, and managing discovered contacts.
- Implemented retry logic for handling missing DAV credentials during contact operations.
- Added public share functionality for drive API, allowing users to manage public shares, including upload, delete, and rename operations.
- Updated Nextcloud configuration to support public share links and improved error handling for public share permissions.
- Enhanced logging and validation across contact and drive APIs for better error tracking and user feedback.
- Added tests for new contact matching and ranking functionalities to ensure accuracy and reliability.
2026-06-06 20:27:02 +02:00

78 lines
2.4 KiB
Go

package discovery
const noReplyProfilesSQL = `
AND NOT (p.primary_email ILIKE '%noreply%' OR p.primary_email ILIKE '%no-reply%' OR p.primary_email ILIKE '%no_reply%')
AND NOT EXISTS (
SELECT 1
FROM jsonb_array_elements(COALESCE(p.all_emails, '[]'::jsonb)) AS e
WHERE COALESCE(e->>'email', '') ILIKE '%noreply%'
OR COALESCE(e->>'email', '') ILIKE '%no-reply%'
OR COALESCE(e->>'email', '') ILIKE '%no_reply%'
)`
const profileSelectColumns = `
p.id::text, p.display_name, p.primary_email, p.all_emails,
p.message_count, p.sent_count, p.received_count, p.spam_count, p.forwarded_count,
p.outbound_count, p.inbound_from_cc_count, p.copresence_cc_bcc_count,
p.is_mailing_list, p.is_disposable, p.is_spam_heavy, COALESCE(p.classification_reason, ''),
COALESCE(p.linked_contact_uid, ''), p.enrichment_status, p.enriched_data,
p.status, p.last_message_at, p.detected_in_accounts`
const profileInteractionOrderBy = `
p.outbound_count DESC,
p.inbound_from_cc_count DESC,
p.copresence_cc_bcc_count DESC,
p.message_count DESC,
p.last_message_at DESC NULLS LAST`
const groupInteractionOrderBy = `
total_outbound DESC,
total_inbound DESC,
total_copresence DESC,
total_messages DESC,
last_message_at DESC NULLS LAST`
func compareProfilesByInteraction(a, b Profile) bool {
if a.OutboundCount != b.OutboundCount {
return a.OutboundCount > b.OutboundCount
}
if a.InboundFromCCCount != b.InboundFromCCCount {
return a.InboundFromCCCount > b.InboundFromCCCount
}
if a.CopresenceCCBCCCount != b.CopresenceCCBCCCount {
return a.CopresenceCCBCCCount > b.CopresenceCCBCCCount
}
if a.MessageCount != b.MessageCount {
return a.MessageCount > b.MessageCount
}
return a.DisplayName < b.DisplayName
}
func compareProfileGroupsByInteraction(a, b ProfileGroup) bool {
ao, ai, ac, am := groupInteractionTotals(a.Profiles)
bo, bi, bc, bm := groupInteractionTotals(b.Profiles)
if ao != bo {
return ao > bo
}
if ai != bi {
return ai > bi
}
if ac != bc {
return ac > bc
}
if am != bm {
return am > bm
}
return a.DisplayName < b.DisplayName
}
func groupInteractionTotals(profiles []Profile) (outbound, inbound, copresence, messages int) {
for _, p := range profiles {
outbound += p.OutboundCount
inbound += p.InboundFromCCCount
copresence += p.CopresenceCCBCCCount
messages += p.MessageCount
}
return outbound, inbound, copresence, messages
}