system: information panel and event log; about: download this build's source
ci / check (push) Successful in 1m20s
ci / images (push) Successful in 20s

System page laid out after 3CX's admin dashboard: a System information panel (version,
host name, company, public IP, LAN IPs, ports, telephony, restart needed, copy buttons,
how to restart) and an Event log panel (system_events, 90 days: trunk down/up, Asterisk
down/up, restart needed, config failed, 911, public IP changed, backups, disk) with Load
more and a CSV download.

About (/about, no sign-in, linked from the login page, My phone and System): AGPL-3.0
notice, credits, the repository link, and "Code v<version>", which downloads
selfphone.tar.gz: the api image now tars its own build context (no .env, data,
node_modules, build output or .git) before installing anything.

Task: M11-T7
This commit is contained in:
iamdoubz committed 2026-10-20 11:26:34 -05:00
1 parent a6ba61756c
commit 0ff0f9292b
29 files changed
+5035 -79

No files matched your search

+3 -1
View File
@@ -97,7 +97,9 @@ curl http://127.0.0.1:8080/healthz # 200 {"ok":true}, or 503 when the datab
From outside, monitor `https://pbx.example.com/healthz`.
**The dashboard** shows trunks, active calls, queues and warnings (emergency setup, certificate,
backups, restart needed) live.
backups, restart needed) live. **System** has the event log: trunks going down and back up,
Asterisk stopping and coming back, restarts needed, 911 calls, public IP changes, backups and a full
disk, kept 90 days (**Download** saves it as CSV).
### Keeping logs small
+12 -1
View File
@@ -8,7 +8,7 @@ Conventions:
- Primary keys: `uuid` with `default gen_random_uuid()` unless stated (built into PostgreSQL 18, so no pgcrypto extension is needed).
- Every table has `created_at timestamptz not null default now()` and
`updated_at timestamptz not null default now()` (left out below to save space,
**but add them**). Exceptions: `cdr`, `audit_log`, `webhook_deliveries`, `generator_runs` (append-only, `created_at` only).
**but add them**). Exceptions: `cdr`, `audit_log`, `system_events`, `webhook_deliveries`, `generator_runs` (append-only, `created_at` only).
- Columns ending in `_enc` hold secrets encrypted with AES-256-GCM using
`APP_SECRET` (format: `base64(iv[12] | tag[16] | ciphertext)`). Only
`crypto/secrets.ts` encrypts and decrypts. API responses never include `_enc`
@@ -504,6 +504,17 @@ create table audit_log (
diff jsonb -- secrets replaced with "********"
);
-- Added 2026-10-20 (owner follow-ups to M11-T7): the System page's event log (05 §2), kept 90 days.
create table system_events (
id bigserial primary key,
created_at timestamptz not null default now(),
severity text not null check (severity in ('info', 'warning', 'error')),
code text not null, -- 'trunk.down', 'telephony.restartNeeded', 'backup.failed', ...
source text not null, -- 'Trunk', 'Telephony', 'Backup', ...
message text not null
);
create index on system_events (created_at);
create table generator_runs (
id bigserial primary key,
created_at timestamptz not null default now(),
+1 -1
View File
@@ -48,7 +48,7 @@ Left sidebar navigation, in this order:
| SMS | `/admin/sms` | Same UI as the user one, with all DIDs |
| Blocked numbers | `/admin/blocked` | |
| Settings | `/admin/settings` | Tabs: General, Network (public IP detect, LAN IP, local nets, STUN/TURN), SIP (ports, TCP/TLS), Numbering ranges, Email (SMTP + test), Voicemail, Recording (retention, announcement sound + **legal notice text, 08 §5**), Emergency (default E911 caller ID, notify emails/extensions + a **test notification** button that does NOT dial 911), Backups (schedule, keep, include recordings, list + download + "Back up now"), Webhooks, API tokens |
| System | `/admin/system` | Status JSON pretty-printed, Asterisk version, generator runs list, "Apply config now", "Rollback", "Restart telephony", generated-files viewer (read-only, masked), allowlisted CLI dropdown (04 §7.3) with output panel, audit log. As built (owner follow-up to M11-T7, 2026-10-20): only telephony status (AMI connected, restart needed) and how to restart (`docker compose restart asterisk` on the server; no restart button). The dashboard's `restart_required` warning links here. The rest of this row isn't built; the admin guide's troubleshooting page covers it from the shell |
| System | `/admin/system` | Status JSON pretty-printed, Asterisk version, generator runs list, "Apply config now", "Rollback", "Restart telephony", generated-files viewer (read-only, masked), allowlisted CLI dropdown (04 §7.3) with output panel, audit log. As built (owner follow-ups to M11-T7, 2026-10-20), laid out after 3CX's admin dashboard (not copied): a **System information** panel (version, host name, company, public IP static/dynamic, LAN IPs, ports SIP/SIPS/media/HTTPS, telephony running, restart needed; copy buttons) with how to restart (`docker compose restart asterisk` on the server; no restart button), and an **Event log** panel (severity, event code, time, source, details; Load more; Download = `/api/system/events.csv`). Events (`system_events`, kept 90 days): `trunk.down`/`trunk.up` (registration changes), `telephony.down`/`telephony.up` (AMI), `telephony.restartNeeded`, `config.failed`, `emergency.call`/`emergency.test`, `network.publicIpChanged`, `backup.done`/`backup.failed`, `disk.low`. Admin edits stay in the audit log (not shown yet). The dashboard's `restart_required` warning links here. Generator runs, generated files and CLI views aren't built; the admin guide's troubleshooting page covers them from the shell |
### 2.1 First-run setup wizard (`/setup`)
+7
View File
@@ -111,6 +111,13 @@ how to use `/admin/system` CLI views and `pjsip set logger on` (via `docker comp
## 4. Licensing compliance
- Our code: AGPL-3.0-or-later. Add `LICENSE`, SPDX headers, and an About page (`/admin/system` → About) listing
the license and a link to the source repository (AGPL requires offering source to network users).
As built (owner, 2026-10-20): `/about` needs no sign-in (linked from the login page, My phone and System). The
api image carries the exact source it was built from: `apps/api/Dockerfile` tars the build context (minus
`.dockerignore`: no `.env`, `data/`, `node_modules`, build output or `.git`) into `/app/selfphone.tar.gz`
before installing anything, with `VERSION` from the root package.json. "Code v<version>" downloads it
(`GET /api/about/source`, `selfphone.tar.gz`, top folder `selfphoneng-<version>/`). Outside Docker there is
no archive and the page says so. The repository link is general context. The ringtone is synthesized
(WebAudio), so there's no sound file to credit.
- Asterisk: GPL-2.0, runs as a separate program. We don't link to it, so there's no license conflict.
- Asterisk core/extra sounds and opsound MOH: CC-BY-SA. Credit them on the About page.
- Ringtone: CC0, documented in `apps/web/public/sounds/SOUNDS-LICENSE.md`.