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:
1 parent
f87d4d47dd
commit
15624f7b77
35 files changed
+1730
-16
No files matched your search
@@ -18,6 +18,7 @@ export function loadCase(name: string): Snapshot {
|
||||
trunks?: Partial<Snapshot['trunks'][number]>[];
|
||||
routes?: Partial<Snapshot['routes'][number]>[];
|
||||
ringGroups?: Partial<Snapshot['ringGroups'][number]>[];
|
||||
ivrs?: Partial<Snapshot['ivrs'][number]>[];
|
||||
};
|
||||
const settings = Object.fromEntries(
|
||||
(Object.keys(SettingsSchemas) as SettingKey[])
|
||||
@@ -36,6 +37,20 @@ export function loadCase(name: string): Snapshot {
|
||||
id: d.id!,
|
||||
number: d.number!,
|
||||
})),
|
||||
ivrs: (raw.ivrs ?? []).map((r, i) => ({
|
||||
name: `Menu ${i + 1}`,
|
||||
greeting: 'custom/greeting',
|
||||
invalidSound: null,
|
||||
timeoutSeconds: 5,
|
||||
maxRetries: 3,
|
||||
allowDirectDial: true,
|
||||
options: [],
|
||||
timeoutDestination: { type: 'hangup' as const },
|
||||
invalidDestination: { type: 'hangup' as const },
|
||||
...r,
|
||||
id: r.id!,
|
||||
number: r.number!,
|
||||
})),
|
||||
ringGroups: (raw.ringGroups ?? []).map((g, i) => ({
|
||||
name: `Group ${i + 1}`,
|
||||
strategy: 'ringall',
|
||||
|
||||
Reference in new issue
Block a user