contacts: my book, the company book, vCard/CSV import, sharing with Accept/Deny
C1 (spec 11): /api/me/contacts and /api/contacts (admin), our own vCard 2.1/3.0/4.0 and CSV readers with a preview, contact_shares (migration 0009) for offers, and contact names in call history, voicemail, Home, the softphone and the call report email. Admin → Contacts.
This commit is contained in:
1 parent
32f4590369
commit
a754974a90
26 files changed
+6103
-23
No files matched your search
@@ -449,6 +449,17 @@ create table voicemail_messages ( -- index of files Asterisk
|
||||
transcript text -- speech to text (10), when it's on
|
||||
);
|
||||
|
||||
create table contact_shares ( -- a contact offered to a colleague (11 §2.1)
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
from_user_id uuid references users(id) on delete set null,
|
||||
to_user_id uuid not null references users(id) on delete cascade,
|
||||
source_id text not null, -- the contact's id in the sender's book
|
||||
contact jsonb not null, -- a copy: { name, company, email, numbers, notes }
|
||||
status text not null default 'pending' check (status in ('pending', 'accepted', 'denied')),
|
||||
decided_at timestamptz
|
||||
);
|
||||
create index on contact_shares (to_user_id) where status = 'pending';
|
||||
|
||||
create table contacts (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
owner_user_id uuid references users(id) on delete cascade, -- null = company phonebook
|
||||
|
||||
@@ -377,7 +377,7 @@ Auth & self:
|
||||
| GET | `/api/me/greetings/:kind/audio` | user | the wav |
|
||||
| PUT/DELETE | `/api/me/greetings/:kind` | user | PUT body is the raw audio (a MediaRecorder Blob or a picked File, any `Content-Type`, max 20 MB), not multipart: no extra dependency. ffmpeg converts it (§6) |
|
||||
| GET | `/api/me/voicemail/:id/audio?download=1` | user | same, as an attachment |
|
||||
| GET/POST/PATCH/DELETE | `/api/me/contacts[/:id]` | user | personal contacts |
|
||||
| GET/POST/PATCH/DELETE | `/api/me/contacts[/:id]` | user | my contacts; GET lists the company's too (11 §3). `POST /import`, `POST /share`, `GET /shares`, `POST /shares/accept\|deny` (11 §2.1, §3.1) |
|
||||
| POST | `/api/me/queues/:id/pause`, `/unpause` | user | log out of / in to a queue I'm an agent of (Home, 05 §4), same as `*45<queue>` |
|
||||
| POST | `/api/me/click-to-call` | user | `{number}` → AMI `Originate Channel: PJSIP/<ext>, Context: sp-from-ext, Exten: <normalized>, Priority: 1, CallerID: "<number>" <<ext>>, Async: true`. The user's phone rings first, then the call goes out |
|
||||
|
||||
@@ -401,7 +401,7 @@ Admin resources (all `requireAdmin`; standard CRUD = `GET /x`, `POST /x`, `GET /
|
||||
| `/api/moh-classes` | `POST {name}` (slug, not `default`), `DELETE /:id` (409 with `usedBy` while an extension or queue uses it), `POST /:id/files?name=&filename=` (raw file body, like sounds), `GET /:id/files/:fileId/audio`, `DELETE /:id/files/:fileId`. No rename: the name is the folder and is stored on extensions and queues. Extensions and queues may only pick `default` or an existing class (400) |
|
||||
| `/api/devices` | `GET /:id/config-preview` (rendered provisioning file, passwords masked). As built (M10-T1): body `{mac (any format), vendor, model, label, extensionId}`; the DTO carries `provisioningUrl` and the `provisioningPassword` (admins type it into the phone); MAC taken → 409; preview of a generic phone → 400 |
|
||||
| `/api/blocked-numbers` | |
|
||||
| `/api/contacts` | company phonebook; `POST /import` CSV (`name,company,email,label1,number1,...`) |
|
||||
| `/api/contacts` | company phonebook; `POST /import` CSV (`name,company,email,label1,number1,...`) or vCard (11 §3.1) |
|
||||
| `/api/webhooks` | `POST /:id/test`, `GET /:id/deliveries` |
|
||||
| `/api/api-tokens` | POST returns the token once |
|
||||
|
||||
|
||||
Reference in new issue
Block a user