dids: phone numbers, destinations, inbound dialplan, Phone numbers page
DIDs CRUD (any input format, normalized; 409 on duplicates; a number
that is an emergency or default caller ID can't be removed). Shared
destination service: assertDestinationExists, describeDestination
("Ring Dan Doe (101)") and findReferences over every destination
column in 02 §1 plus the unmatched-number setting; deleting an
extension a destination points at is now a 409 naming the places.
Generator: destApp (user, external, hangup for now), sp-from-trunk-*
per enabled trunk, sp-did-exists (left out when empty) and sp-inbound
with caller-name prefix. Golden case voipms-basic. Phone numbers page
with a minimal DestinationPicker (user, outside number, hang up).
trunk-test.ts: the fake provider calls the DID with a 10-digit
Request-URI like voip.ms; baresip 101 answers, caller ID arrives
normalized, 500 packets each way on both legs. scripts/e2e/m3-t2.mjs
checks the UI → Asterisk path. Still to do with real voip.ms: the
mobile-to-DID call and recording which header carries the DID (06 §3).
Task: M3-T2
This commit is contained in:
1 parent
1b7f60b5f2
commit
c117d8bb1d
28 files changed
+1371
-21
No files matched your search
@@ -6,6 +6,7 @@ import type { Db } from '../db/client.ts';
|
||||
import { dids, extensions, trunks, users } from '../db/schema.ts';
|
||||
import { decrypt } from '../crypto/secrets.ts';
|
||||
import { getAllSettings } from '../services/settings.ts';
|
||||
import type { Destination } from '@selfphoneng/shared';
|
||||
|
||||
export type SnapExtension = {
|
||||
id: string;
|
||||
@@ -26,7 +27,14 @@ export type SnapExtension = {
|
||||
isAdmin: boolean; // the extension's user is an admin (time-condition override codes)
|
||||
};
|
||||
|
||||
export type SnapDid = { id: string; number: string };
|
||||
export type SnapDid = {
|
||||
id: string;
|
||||
number: string;
|
||||
trunkId: string;
|
||||
label: string | null;
|
||||
destination: Destination;
|
||||
callerIdNamePrefix: string | null;
|
||||
};
|
||||
|
||||
export type SnapTrunk = {
|
||||
id: string;
|
||||
@@ -50,7 +58,7 @@ export type Snapshot = {
|
||||
today: string;
|
||||
settings: Awaited<ReturnType<typeof getAllSettings>>;
|
||||
extensions: SnapExtension[];
|
||||
dids: SnapDid[]; // M3 adds routing fields
|
||||
dids: SnapDid[];
|
||||
trunks: SnapTrunk[];
|
||||
};
|
||||
|
||||
@@ -75,12 +83,21 @@ export async function loadSnapshot(db: Db, now = new Date()): Promise<Snapshot>
|
||||
.leftJoin(outDid, eq(outDid.id, extensions.outboundCallerIdDidId))
|
||||
.leftJoin(e911Did, eq(e911Did.id, extensions.emergencyCallerIdDidId));
|
||||
|
||||
const didRows = await db.select({ id: dids.id, number: dids.number }).from(dids);
|
||||
const didRows = await db
|
||||
.select({
|
||||
id: dids.id,
|
||||
number: dids.number,
|
||||
trunkId: dids.trunkId,
|
||||
label: dids.label,
|
||||
destination: dids.destination,
|
||||
callerIdNamePrefix: dids.callerIdNamePrefix,
|
||||
})
|
||||
.from(dids);
|
||||
const trunkRows = await db.select().from(trunks);
|
||||
return {
|
||||
today: todayIn(settings['general.timezone'], now),
|
||||
settings,
|
||||
dids: didRows,
|
||||
dids: didRows.map((d) => ({ ...d, destination: d.destination as Destination })),
|
||||
trunks: trunkRows.map((t) => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
|
||||
Reference in new issue
Block a user