ivrs: digital receptionist with keypad grid, SoundPicker, golden case

/api/ivrs CRUD: greeting and wrong-key sounds must be prompts, every
option destination must exist (an option may point at its own menu),
keys unique; delete drops the menu's own options before checking
references, inside a transaction so a refused delete keeps them. The
generator renders sp-ivr-{id} per 03 §6.9 (Background greeting,
WaitExten, keys sorted, i/t retry then give up, include sp-local-numbers
for direct dial), adds the number to sp-local-numbers, and destApp sends
ivr destinations there. Golden case ivr (incl. # and self-reference).

Web: Digital receptionist page with a 3x4 keypad grid (pick a key, then
its destination or "unused"), SoundPicker (pick, play, upload new right
in the form), DestinationPicker gains "Digital receptionist" and a shared
target source; useDescribeDestination labels unsaved keys.

e2e m6-t3: menu built in the UI, the greeting plays, keys 1/2 ring the
right phones, a wrong key plays pbx-invalid and repeats the greeting.

Task: M6-T3
This commit is contained in:
iamdoubz committed 2026-10-18 10:39:13 -05:00
1 parent f87d4d47dd
commit 15624f7b77
35 files changed
+1730 -16

No files matched your search

+1
View File
@@ -65,6 +65,7 @@ function snapshot(): Snapshot {
trunks: [],
routes: [],
ringGroups: [],
ivrs: [],
extensions: [ext('101', 'Alice'), ext('102', 'Bob')],
};
}
+1
View File
@@ -101,6 +101,7 @@ function snapshot(): Snapshot {
],
trunks: [trunk(GOOD, 'voip.ms', SUB.pass), trunk(BAD, 'wrong password', 'NotThePassword1')],
ringGroups: [],
ivrs: [],
routes: [
{
id: 'aaaaaaaa-0000-4000-8000-000000000001',
+1
View File
@@ -60,6 +60,7 @@ function snapshot(): Snapshot {
trunks: [],
routes: [],
ringGroups: [],
ivrs: [],
extensions: [ext('101', 'Alice'), ext('102', 'Bob')],
};
}