feat(kontakte): Vorbereich "Aus Mails" mit Dublettenabgleich
Der Postfachabgleich hat gefundene Personen bisher direkt in den Kontaktbestand geschrieben. Damit wächst eine gepflegte Liste ungefragt mit jeder Adresse aus jeder Mail - genau daran ist das Altsystem gescheitert. Funde landen jetzt in einem Vorbereich (crm_leads.mail_pool = 1), der als Unterpunkt "Aus Mails" unter dem Menüpunkt Kontakte aufklappt. Der Kontaktbestand bleibt unberührt, bis dort jemand entscheidet; in Opportunities, Kalender und Netzwerk tauchen die Funde nicht auf. Eine Spalte statt einer zweiten Tabelle, weil crm_mail_links und crm_mail_contact_candidates per Fremdschlüssel auf crm_leads zeigen - so behält der Vorbereich seine Mailbezüge. Übernehmen kennt zwei Wege: - neue Person: Kopie mit mail_pool = 0, die Mailverknüpfungen wandern mit - Dublette (Adresse, sonst voller Name): gold markiert, abweichende Felder mit altem und neuem Wert; die Feldauswahl schreibt sie in den vorhandenen Kontakt. Vorausgewählt sind nur Lücken - ein Wert aus einer alten Signatur soll nichts Gepflegtes stillschweigend ersetzen. db.js verschiebt beim ersten Start die vorhandenen Kontakte mit source = 'Mail' in den Vorbereich, einmalig über den Merker leads_mail_pool_migrated in crm_settings. Die Sidebar-Gruppe ist dabei generisch geworden (MenuGroup) - Kontakte und Scanner benutzen jetzt denselben Code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8090d0aae1
commit
ea55acdb5c
@@ -128,6 +128,28 @@ export const usersApi = {
|
||||
|
||||
export type LeadInput = Partial<Omit<Lead, 'id' | 'created_at' | 'updated_at'>>;
|
||||
|
||||
/**
|
||||
* Herkunft eines Eintrags im Vorbereich "Aus Mails": aus wie vielen Mails er
|
||||
* stammt, welche die letzte war und wie sicher der Fund ist.
|
||||
*/
|
||||
export interface MailPoolSource {
|
||||
message_count: number;
|
||||
last_received_at: string | null;
|
||||
last_subject: string | null;
|
||||
/** 0-100; null, wenn der Vorschlag inzwischen entfernt wurde. */
|
||||
confidence: number | null;
|
||||
origin: 'absender' | 'empfaenger' | 'signatur' | 'text' | null;
|
||||
}
|
||||
|
||||
export interface PromoteResult {
|
||||
/** true = vorhandener Kontakt ergaenzt, false = neuer Kontakt angelegt. */
|
||||
merged: boolean;
|
||||
/** Anzahl der uebertragenen Felder (nur beim Ergaenzen). */
|
||||
fields: number;
|
||||
removed_pool: boolean;
|
||||
lead: Lead;
|
||||
}
|
||||
|
||||
export const leadsApi = {
|
||||
list: () => request<Lead[]>('/leads'),
|
||||
create: (input: LeadInput) =>
|
||||
@@ -135,6 +157,26 @@ export const leadsApi = {
|
||||
update: (id: number, input: LeadInput) =>
|
||||
request<Lead>(`/leads/${id}`, { method: 'PATCH', body: JSON.stringify(input) }),
|
||||
remove: (id: number) => request<{ ok: true }>(`/leads/${id}`, { method: 'DELETE' }),
|
||||
|
||||
/** Herkunftsangaben aller Eintraege aus "Aus Mails", nach Lead-ID. */
|
||||
mailPoolSources: () => request<Record<string, MailPoolSource>>('/leads/mail-pool/sources'),
|
||||
|
||||
/**
|
||||
* Eintrag aus "Aus Mails" in die Kontakte holen. Ohne `target_lead_id`
|
||||
* entsteht ein neuer Kontakt; mit ihr werden die genannten Felder in den
|
||||
* vorhandenen Kontakt geschrieben. `keep_pool` behaelt den Eintrag im
|
||||
* Vorbereich.
|
||||
*/
|
||||
promote: (
|
||||
id: number,
|
||||
input: { target_lead_id?: number | null; fields?: string[]; keep_pool?: boolean; owner_id?: number } = {}
|
||||
) => request<PromoteResult>(`/leads/${id}/promote`, { method: 'POST', body: JSON.stringify(input) }),
|
||||
|
||||
promoteMany: (ids: number[], options: { keep_pool?: boolean } = {}) =>
|
||||
request<{ ok: true; created: number[]; skipped: number[] }>('/leads/mail-pool/promote', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ ids, ...options }),
|
||||
}),
|
||||
};
|
||||
|
||||
// ---------- Opportunities ----------
|
||||
|
||||
Reference in New Issue
Block a user