- Ya
- 3 Septemba 2026, 04:33 UTC
- Mwandishi
- Kamo
- Ahadi ya
- eabb41f
VOIPService's JustCall integration needs to land a customer's contacts in the right member's address book, and this is where contacts are written: a Contact maps only scalars, with its emails, phones, addresses, orgs, URLs, IMs and relationships in seven tables with no cascade, reachable only through ContactDetailStore. A caller writing those tables from another service would silently drop every phone number — the one field a phone integration exists to deliver — so the persistence stays here and the caller posts to it. Ownership is the load-bearing part. CONTACT.OWNER_ID is NOT NULL and points at users, and a ContactBook's owner IS its access control (an ownerless book belongs to nobody and 404s for everyone), so a batch must name the member its contacts belong to and is refused outright when it does not. Each source gets its own book behind a ContactIntegration row rather than being mixed into "My Contacts": synced rows and hand-typed rows have different lifecycles, and the member can hide or drop the imported ones without touching their own. Upserts match on uid, which the caller namespaces to its system. UID is unique per book, so that is also what makes a re-sync an update instead of a second copy of everything. Mounted under /api/internal, guarded whole by InternalAuthFilter — there is no member session behind these calls, so without that filter this would be an endpoint for writing arbitrary contacts into arbitrary members' books.