Skip to content

Astradial Editor — Project Plan & Status

What We're Building

A complete PBX management frontend + AI voice bot platform for Astradial's 20+ client organizations. Built as a Next.js app extending the Pipecat flow editor at editor.astradial.com.

Three pillars: 1. AI Voice Bot Editor — Visual flow editor to design and deploy Gemini Live voice bots (IVR, ticketing, FAQ) 2. PBX Admin Panel — Manage users, extensions, DIDs, trunks, queues, call routing 3. Call Center Dashboard — Live calls, call logs, tickets, leads, monitoring/whisper/barge


Architecture

Component Location Port Purpose
Editor (Next.js) VPS /opt/pipecat-flow-editor 3001 Frontend UI
Gateway (Python/FastAPI) VPS /opt/pipecat-flow 7860 Bot management, WebSocket relay
AstraPBX (Node.js) VPS /opt/astrapbx 8000 PBX API, Asterisk management
Asterisk VPS 5060/5080 PBX engine
LogsUpdate GCP Cloud Run - Webhook handler, Firebase writes
Firebase GCP - Call logs, tickets, phonebook
MySQL VPS localhost:3306 - Shared DB (pbx_api_db)

Domains: - editor.astradial.com — Admin panel + flow editor - gateway.astradial.com — Bot gateway API + WebSocket - devpbx.astradial.com — AstraPBX API - devsip.astradial.com:5080 — SIP registration

GitHub: https://github.com/astradial/astradial-editor (private)


What's Working

AI Voice Bots

  • [x] Grand Estancia IVR bot (ext 1012) — department routing with queue transfer
  • [x] Grand Estancia Ticketing bot (ext 1013) — collects details, creates Firestore ticket, FAQ answers
  • [x] Gemini Live integration with function calling
  • [x] Webhook actions on functions (ticket creation to LogsUpdate)
  • [x] Idle detection (8s silence → prompt → hangup)
  • [x] Template engine for state_mappings and value_maps
  • [x] Flow editor with visual node editor
  • [x] Live bot logs streaming (SSE)
  • [x] Load Example: Grand Estancia Ticketing flow

Admin Panel

  • [x] Login page (shadcn auth style, split screen)
  • [x] Dashboard with stat cards, call volume chart, recent calls
  • [x] Left sidebar with grouped navigation (Configure/Monitor/Deploy)
  • [x] Blue theme from shadcn, dark/light mode toggle
  • [x] Users page — CRUD, routing config (SIP/AI Bot/Phone), SIP QR code (UDP fields for Zoiper-class softphones, plus wss_port / wss_path extension for the Astradial mobile app — see Astradial Softphone App)
  • [x] Queues page — CRUD with strategy selector
  • [x] DIDs page — CRUD with routing type selector
  • [x] Trunks page — CRUD with registration status
  • [x] Bots page — CRUD, API keys, Gemini config
  • [x] Settings page — org info, deploy/reload config, logout

Call Center

  • [x] Call History — Firebase Firestore, paginated, direction filter
  • [x] Audio player — ElevenLabs audio-player component, auto-play, download
  • [x] Live Calls — polling /calls/live, auto-refresh, no flicker
  • [x] Transfer dialog — type selector (Extension/Queue/External), user search, phonebook
  • [x] Hangup from UI
  • [x] Monitoring/Whisper/Barge — ARI snoop channels (backend implemented)
  • [x] Tickets — real-time from Firestore, status workflow (Open → In Progress → Closed), remarks
  • [x] Phonebook — shared via Firestore, accessible during transfer
  • [x] Auto-deploy Asterisk config on user creation

Security

  • [x] UFW firewall — ports 7860, 3001, 8088, 19999 blocked (Nginx only)
  • [x] Rate limiting on admin API endpoints
  • [x] fail2ban — 4 jails (sshd, asterisk, nginx-401, nginx-ratelimit)
  • [x] SSH key-only, PermitRootLogin prohibit-password
  • [x] Security headers on all Nginx responses
  • [x] Internal auth (X-Internal-Key) for localhost service-to-service calls
  • [x] Journal retention: 200MB max, 7 days
  • [x] GCS CORS configured for audio playback

Known Bugs

  1. Live calls duplicates — AMI CoreShowChannels returns multiple channels per call. Backend dedup by linkedid helps but isn't perfect after transfers. Proper fix: full ARI event tracking.

  2. Transfer after call setup — After a call is transferred via UI, the new outbound leg shows as a separate "Outgoing" call. Original caller number is lost. Fix: ARI-based call lifecycle tracking (Phase 1 of monitoring plan, partially implemented).

  3. Direction shows "Unknown" — The /calls/live endpoint determines direction from Asterisk context names. Inbound calls via trunk may not always have context containing "inbound". Needs better heuristics.

  4. Agent shows "GrandEstancia" — After transfer to external number, the org trunk's CallerIDName appears as "agent". Fix: preserve original agent info through ARI tracking.

  5. React hydration error #418 — Server/client HTML mismatch from localStorage access during SSR. Harmless but noisy in console.

  6. Phonebook write — May fail silently if Firestore rules don't include /astrapbx/{orgId}/settings/{doc} write permission.

  7. Transfer 500 error — Fixed (was missing logger import in gateway proxy). Now deployed.


Future Plans

Immediate (Next Session)

  • [ ] Fix React #418 hydration error — wrap localStorage access in useEffect
  • [ ] Test transfer to extension (now that gateway logger is fixed)
  • [ ] Test transfer to external number
  • [ ] Wire up dashboard stats from Firebase (currently uses placeholder chart data)

Short Term

  • [ ] Leads page — group call logs by phone number, show latest call on top, tags, detailed history
  • [ ] Firebase Auth login — replace admin key login with Firebase email/password + Google sign-in
  • [ ] Org user roles — admin, supervisor, agent with different permissions
  • [ ] Channel monitoring snapshots — periodic writes to Firestore for daily aggregation
  • [ ] Edit user dialog — currently can only create/delete, need edit in-place

Medium Term

  • [ ] Full ARI call tracking — preserve caller info through transfers, proper agent tracking
  • [ ] Monitor/Whisper/Barge testing — verify ARI snoop channels work with live calls
  • [ ] Queue member management — add/remove agents from queues, drag-to-reorder
  • [ ] Audio upload for queues — hold music, welcome TTS
  • [ ] Webhook configuration page — CRUD for webhook endpoints with test button
  • [ ] Outbound routes management — dial patterns, caller ID override

Long Term

  • [ ] Multi-tenant login — each org gets their own login, sees only their data
  • [ ] Impersonation — admin can switch to any org's view
  • [ ] Real-time WebSocket — replace polling with WebSocket for live calls
  • [ ] Call recording management — search, download, delete, retention policies
  • [ ] Reports & Analytics — call volume trends, agent performance, queue wait times
  • [ ] Mobile responsive — sidebar collapse, touch-friendly controls
  • [ ] Bot analytics — function call stats, ticket resolution rates, FAQ hit rates

Gemini Live Constraints (Important)

When building voice bots with Gemini Live + pipecat-flows:

  1. Same tools on every node — Gemini Live reconnects when tools change, breaking function calling
  2. System instruction set once — runtime updates to system_instruction NOT supported
  3. respond_immediately: false on end nodes — prevents end_conversation from firing before bot speaks
  4. TTSSpeakFrame doesn't work — use send_realtime_input(text=...) for idle detection prompts
  5. Single-node design — keep all functions available from the start, use next_node_id: "main" to loop

Key Credentials & Config

All stored in VPS .env files (not in code): - Gateway admin key: /opt/pipecat-flow/.envGATEWAY_ADMIN_KEY - Internal API key: shared between AstraPBX and pipecat-flow → INTERNAL_API_KEY - Firebase config: /opt/pipecat-flow-editor/.env.localNEXT_PUBLIC_FIREBASE_* - Firebase auth: .env.localNEXT_PUBLIC_FB_AUTH_EMAIL/PASS - MySQL: /opt/pipecat-flow/.envDB_* (user: pipecat, db: pbx_api_db)


File Structure

astradial-editor/
├── app/
│   ├── dashboard/
│   │   ├── page.tsx                    # Login + org list
│   │   └── [orgId]/
│   │       ├── layout.tsx              # Sidebar layout
│   │       ├── page.tsx                # Redirect to /overview
│   │       ├── overview/page.tsx       # Dashboard stats + chart
│   │       ├── users/page.tsx          # Users & extensions
│   │       ├── bots/page.tsx           # AI bot management
│   │       ├── bots/[botId]/page.tsx   # Flow editor
│   │       ├── queues/page.tsx         # Queue management
│   │       ├── calls/page.tsx          # Live calls + history
│   │       ├── leads/page.tsx          # Lead management (TODO)
│   │       ├── tickets/page.tsx        # Bot tickets
│   │       ├── dids/page.tsx           # DID numbers
│   │       ├── trunks/page.tsx         # SIP trunks
│   │       └── settings/page.tsx       # Org settings + logout
│   ├── editor/page.tsx                 # Standalone flow editor
│   └── page.tsx                        # Landing page
├── components/
│   ├── layout/Sidebar.tsx              # Left navigation sidebar
│   ├── users/SipQrDialog.tsx           # SIP QR code dialog
│   ├── LogsPanel.tsx                   # Bot live logs (SSE)
│   ├── ui/                             # shadcn + ElevenLabs components
│   └── ...
├── lib/
│   ├── pbx/client.ts                   # AstraPBX API client
│   ├── gateway/client.ts               # Pipecat gateway API client
│   ├── firebase/config.ts              # Firebase init + auth
│   ├── firebase/firestore.ts           # Firestore queries (paginated)
│   ├── auth/authStore.ts               # Zustand auth state
│   └── ...
└── styles/globals.css                  # Blue theme (shadcn)