ultisuite-backend/migrations/000022_contact_discovery.up.sql
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

92 lines
3.8 KiB
SQL

-- Contact discovery from mail messages: pseudo-contacts, signatures, enrichment suggestions.
CREATE TABLE contact_discovery_scans (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status TEXT NOT NULL DEFAULT 'pending',
messages_scanned INT NOT NULL DEFAULT 0,
profiles_found INT NOT NULL DEFAULT 0,
error_message TEXT,
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ
);
CREATE INDEX idx_contact_discovery_scans_user ON contact_discovery_scans(user_id, started_at DESC);
CREATE TABLE contact_discovered_profiles (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
scan_id UUID REFERENCES contact_discovery_scans(id) ON DELETE SET NULL,
person_group_id UUID,
display_name TEXT NOT NULL DEFAULT '',
primary_email TEXT NOT NULL,
all_emails JSONB NOT NULL DEFAULT '[]',
message_count INT NOT NULL DEFAULT 0,
sent_count INT NOT NULL DEFAULT 0,
received_count INT NOT NULL DEFAULT 0,
spam_count INT NOT NULL DEFAULT 0,
forwarded_count INT NOT NULL DEFAULT 0,
is_mailing_list BOOLEAN NOT NULL DEFAULT false,
is_disposable BOOLEAN NOT NULL DEFAULT false,
is_spam_heavy BOOLEAN NOT NULL DEFAULT false,
classification_reason TEXT,
linked_contact_uid TEXT,
enrichment_status TEXT NOT NULL DEFAULT 'pending',
enriched_data JSONB,
enriched_at TIMESTAMPTZ,
status TEXT NOT NULL DEFAULT 'suggested',
rejected_at TIMESTAMPTZ,
accepted_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_message_at TIMESTAMPTZ,
UNIQUE(user_id, primary_email)
);
CREATE INDEX idx_contact_discovered_profiles_user_status ON contact_discovered_profiles(user_id, status);
CREATE INDEX idx_contact_discovered_profiles_user_email ON contact_discovered_profiles(user_id, lower(primary_email));
CREATE TABLE contact_discovered_signatures (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
profile_id UUID NOT NULL REFERENCES contact_discovered_profiles(id) ON DELETE CASCADE,
message_id UUID REFERENCES messages(id) ON DELETE SET NULL,
signature_text TEXT NOT NULL DEFAULT '',
signature_html TEXT,
message_date TIMESTAMPTZ NOT NULL,
confidence REAL NOT NULL DEFAULT 0.5,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_contact_discovered_signatures_profile ON contact_discovered_signatures(profile_id, message_date DESC);
CREATE TABLE contact_enrichment_suggestions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
profile_id UUID REFERENCES contact_discovered_profiles(id) ON DELETE CASCADE,
target_contact_uid TEXT,
suggestion_type TEXT NOT NULL,
field_path TEXT NOT NULL,
suggested_value TEXT NOT NULL,
suggested_label TEXT NOT NULL DEFAULT '',
confidence REAL NOT NULL DEFAULT 0.5,
source_signature_id UUID REFERENCES contact_discovered_signatures(id) ON DELETE SET NULL,
status TEXT NOT NULL DEFAULT 'pending',
rejected_at TIMESTAMPTZ,
accepted_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id, profile_id, field_path, suggested_value)
);
CREATE INDEX idx_contact_enrichment_suggestions_user ON contact_enrichment_suggestions(user_id, status);
CREATE TABLE contact_discovery_rejections (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
rejection_key TEXT NOT NULL,
rejection_type TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id, rejection_key, rejection_type)
);
CREATE INDEX idx_contact_discovery_rejections_user ON contact_discovery_rejections(user_id);