Skip to content

Commit ab81d2a

Browse files
authored
fix location type text instead of text[] (#2511)
* fix: formatting * refactor ImapEmailFetcher * add unit tests for extracting, decoding tex/plain * remove unused files * fix: formatting * fix: add missing check * add: signatures tables with detailed fields * fix: formatting & linting * fix: change location type to string instead of string[]
1 parent a101bd5 commit ab81d2a

File tree

3 files changed

+138
-6
lines changed

3 files changed

+138
-6
lines changed

backend/src/services/signature/llm/index.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const SignaturePrompt = {
4343
- "worksFor" : string
4444
- "email" : string
4545
- "telephone": string[]
46-
- "address": string[]
46+
- "address": string
4747
- "sameAs": string[]
4848
4949
### CHAIN OF THOUGHT
@@ -125,10 +125,7 @@ export const SignaturePrompt = {
125125
}
126126
},
127127
address: {
128-
type: 'array',
129-
items: {
130-
type: 'string'
131-
}
128+
type: 'string'
132129
},
133130
sameAs: {
134131
type: 'array',

backend/src/workers/email-signature/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface SignaturePayload {
1515
personEmail: string;
1616
messageId: string;
1717
rawSignature?: string | null;
18-
extractedSignature?: Record<string, string> | null;
18+
extractedSignature?: Record<string, unknown> | null;
1919
details?: Record<string, unknown> | null;
2020
}
2121

supabase/migrations/20251105175657_location_text.sql

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,139 @@ BEGIN
183183
WHERE
184184
rn = 1;
185185
END;
186+
$$;
187+
188+
189+
190+
CREATE OR REPLACE FUNCTION private.enrich_contacts(p_contacts_data jsonb[], p_update_empty_fields_only boolean DEFAULT true) RETURNS void
191+
LANGUAGE plpgsql
192+
SET search_path = ''
193+
AS $$
194+
DECLARE
195+
contact_record JSONB;
196+
organization_id UUID;
197+
works_for_name TEXT;
198+
new_name TEXT;
199+
new_alternate_name TEXT[];
200+
old_name TEXT;
201+
old_alternate_name TEXT[];
202+
203+
phone_number TEXT;
204+
new_telephone TEXT[];
205+
old_telephone TEXT[];
206+
merged_telephone TEXT[];
207+
208+
BEGIN
209+
-- Assert that all records have email and user_id
210+
IF EXISTS (
211+
SELECT 1
212+
FROM unnest(p_contacts_data) AS contact
213+
WHERE contact->>'email' IS NULL OR contact->>'user_id' IS NULL
214+
) THEN
215+
RAISE EXCEPTION 'All records in p_contacts_data must contain email and user_id fields';
216+
END IF;
217+
218+
FOREACH contact_record IN ARRAY p_contacts_data
219+
LOOP
220+
221+
222+
works_for_name := contact_record->>'works_for';
223+
IF works_for_name IS NOT NULL THEN
224+
SELECT id INTO organization_id
225+
FROM private.organizations
226+
WHERE name = works_for_name
227+
LIMIT 1;
228+
229+
IF NOT FOUND THEN
230+
INSERT INTO private.organizations (name)
231+
VALUES (works_for_name)
232+
RETURNING id INTO organization_id;
233+
END IF;
234+
ELSE
235+
organization_id := NULL;
236+
END IF;
237+
238+
-- Merge incoming phone numbers into telephone array
239+
new_telephone := string_to_array(NULLIF(contact_record->>'telephone', ''), ',');
240+
241+
IF new_telephone IS NOT NULL THEN
242+
SELECT p.telephone
243+
INTO old_telephone
244+
FROM private.persons p
245+
WHERE p.email = contact_record->>'email'
246+
AND p.user_id = (contact_record->>'user_id')::UUID
247+
LIMIT 1;
248+
249+
IF old_telephone IS NOT NULL THEN
250+
-- append only the truly new ones
251+
FOREACH phone_number IN ARRAY new_telephone LOOP
252+
IF NOT phone_number = ANY(old_telephone) THEN
253+
old_telephone := ARRAY_APPEND(old_telephone, phone_number);
254+
END IF;
255+
END LOOP;
256+
merged_telephone := old_telephone;
257+
ELSE
258+
-- no existing array → just take new
259+
merged_telephone := new_telephone;
260+
END IF;
261+
END IF;
262+
263+
-- Add name into alternate_name if name is already filled
264+
new_name := contact_record->>'name';
265+
IF new_name IS NOT NULL THEN
266+
SELECT p.name, p.alternate_name
267+
INTO old_name, old_alternate_name
268+
FROM private.persons p
269+
WHERE p.email = contact_record->>'email' AND p.user_id = (contact_record->>'user_id')::UUID
270+
LIMIT 1;
271+
IF old_name IS NOT NULL THEN
272+
IF (old_name != new_name AND (old_alternate_name IS NULL OR NOT(new_name = ANY(old_alternate_name)))) THEN
273+
new_alternate_name := ARRAY_APPEND(old_alternate_name, new_name);
274+
END IF;
275+
new_name := old_name;
276+
END IF;
277+
END IF;
278+
279+
IF p_update_empty_fields_only THEN
280+
UPDATE private.persons pp
281+
SET
282+
name = COALESCE(pp.name, new_name::TEXT),
283+
url = COALESCE(pp.url, (contact_record->>'url')::TEXT),
284+
image = COALESCE(pp.image, (contact_record->>'image')::TEXT),
285+
location = COALESCE(pp.location, NULLIF(contact_record->>'location', '')),
286+
alternate_name = COALESCE(pp.alternate_name, (new_alternate_name)::TEXT[]),
287+
same_as = COALESCE(pp.same_as, string_to_array(NULLIF(contact_record->>'same_as', ''), ',')::TEXT[]),
288+
given_name = COALESCE(pp.given_name, (contact_record->>'given_name')::TEXT),
289+
family_name = COALESCE(pp.family_name, (contact_record->>'family_name')::TEXT),
290+
job_title = COALESCE(pp.job_title, (contact_record->>'job_title')::TEXT),
291+
works_for = COALESCE(pp.works_for, organization_id),
292+
identifiers = COALESCE(pp.identifiers, string_to_array(NULLIF(contact_record->>'identifiers', ''), ',')::TEXT[]),
293+
status = COALESCE(pp.status, (contact_record->>'status')::TEXT),
294+
telephone = COALESCE(pp.telephone, (merged_telephone)::TEXT[])
295+
WHERE
296+
email = (contact_record->>'email')::TEXT AND
297+
user_id = (contact_record->>'user_id')::UUID;
298+
ELSE
299+
UPDATE private.persons pp
300+
SET
301+
name = COALESCE(new_name::TEXT, pp.name),
302+
url = COALESCE((contact_record->>'url')::TEXT, pp.url),
303+
image = COALESCE((contact_record->>'image')::TEXT, pp.image),
304+
location = COALESCE(pp.location, NULLIF(contact_record->>'location', '')),
305+
alternate_name = COALESCE((new_alternate_name)::TEXT[], pp.alternate_name),
306+
same_as = COALESCE(string_to_array(NULLIF(contact_record->>'same_as', ''), ',')::TEXT[], pp.same_as),
307+
given_name = COALESCE((contact_record->>'given_name')::TEXT, pp.given_name),
308+
family_name = COALESCE((contact_record->>'family_name')::TEXT, pp.family_name),
309+
job_title = COALESCE((contact_record->>'job_title')::TEXT, pp.job_title),
310+
works_for = COALESCE(organization_id, pp.works_for),
311+
identifiers = COALESCE(string_to_array(NULLIF(contact_record->>'identifiers', ''), ',')::TEXT[], pp.identifiers),
312+
status = COALESCE((contact_record->>'status')::TEXT, pp.status),
313+
telephone = COALESCE((merged_telephone)::TEXT[], pp.telephone)
314+
315+
WHERE
316+
email = (contact_record->>'email')::TEXT AND
317+
user_id = (contact_record->>'user_id')::UUID;
318+
END IF;
319+
END LOOP;
320+
END;
186321
$$;

0 commit comments

Comments
 (0)