# my.voipsimplicity.com — Portal Requirements **Version:** 1.0 **Date:** 2026-07-24 **Status:** Pre-MVP documentation **Owner:** Germaine Brown (VoIPSimplicity LLC) **Platform:** RingLogix-powered, deployed on app3 (CloudPanel CE) **Design:** Light, mobile-first, single-file HTML SPA (see [voip-portal-development skill](#sources--methodology)) --- ## Table of Contents 1. [Sources & Methodology](#sources--methodology) 2. [Source of Truth & Data Architecture](#source-of-truth--data-architecture) 3. [RBAC, Tenant Isolation & Security](#rbac-tenant-isolation--security) 4. [Audit & Compliance](#audit--compliance) 5. [Phased MVP Sequence](#phased-mvp-sequence) 6. [Requirement Areas](#requirement-areas) - [1. My Dashboard](#1-my-dashboard) - [2. Call History](#2-call-history) - [3. Marketplace](#3-marketplace) - [4. Billing](#4-billing) - [5. My Info](#5-my-info) - [6. Site Login](#6-site-login) - [7. Screenshot-Informed Requirements](#7-screenshot-informed-requirements) 7. [Nav Organization (Expanded Canonical)](#nav-organization-expanded-canonical) 8. [Acceptance Criteria by Phase](#acceptance-criteria-by-phase) 9. [Unknowns & Caveats](#unknowns--caveats) 10. [Out of Scope (Deferred to Post-MVP)](#out-of-scope-deferred-to-post-mvp) --- ## Sources & Methodology ### Owner-Provided Materials - **Owner screenshots:** ViiBE seller-side views (Accounts, Quotes, Products, LNP, Number Orders, CNAM, Mobile Connect, Reports) and NetSapiens customer/manager views (Home/Statistics, Domains, SIP Trunks, Phone Inventory, E911 Inventory, Call History, Contacts, Answer Rules, Time Frames, User Voicemail/Settings, Music/Messages, Call-Center Queues/Statistics, Auto Attendants). - **Owner Obsidian notes:** Captured preferences, design constraints, competitive feature wishlist, and operational requirements from Germaine Brown. - **Owner business records:** [ENTITY.md](./ENTITY.md) — verified phone assets and legal entity. ### Existing Portal Artifacts - **Deployed portal:** `/home/myvoip/htdocs/my.voipsimplicity.com/index.html` on app3 (533 lines production, 1,471 enhanced reference). - **Skill documentation:** `voip-portal-development` skill in `~/.hermes/skills/devops/voip-portal-development/` with 13 reference files covering API integration, call patterns, marketplace flows, and deployment. - **Domain roster:** 14 customer domains, 189 subscribers, 17 DIDs, 30 call queues, 19 auto attendants, 16 time frames — all on RingLogix. --- ## Source of Truth & Data Architecture | Data Domain | Primary Source | API/Object | Notes | |---|---|---|---| | Subscribers/Extensions | RingLogix | `subscriber/read` | `domain` param required; filter to 100–399 for real users | | DIDs/Phone Numbers | RingLogix | `phonenumber/read` | Ignores domain filter — filter client-side by `dialrule_domain` | | Call Queues | RingLogix | `callqueue/read` | `domain` param required | | Auto Attendants | RingLogix | `attendant/read` | NOT `autoattendant` (returns 404) | | Time Frames | RingLogix | `timeframe/read` | `domain` param required | | Music on Hold | RingLogix | **Unknown** — no confirmed endpoint | Screenshots show MOH config; API availability TBD | | Call History / CDRs | RingLogix | **NOT AVAILABLE** — `cdr`, `call_detail_record`, `callhistory` all return 404 | Must use alternative source or NetSapiens CDR export | | Call Recordings | RingLogix → Wasabi S3 | `s3:*` bucket policy for RingLogix IPs (192.92.8.0/24, 64.52.82.0/24, 64.52.83.0/24) | Portal would proxy through signed URLs | | Billing / Invoices | RingLogix | **Unknown** — no confirmed billing API endpoint | Likely via RingLogix admin panel export or Stripe integration | | Plans & Features | RingLogix / Manual | **Unknown** — no confirmed catalog API | Marketplace catalog maintained manually or via RingLogix reseller API | | User Auth / RBAC | Custom (portal-local) | N/A — built in portal JS | No RingLogix customer-auth API; staff `info@voipsimplicity.com` hardcoded | | E911 Inventory | RingLogix | **Unknown** — no confirmed endpoint | NetSapiens screenshots reference; API path TBD | | SIP Trunks | RingLogix | **Unknown** — no confirmed endpoint | NetSapiens screenshots reference; API path TBD | | Answer Rules | RingLogix | **Unknown** — no confirmed endpoint | NetSapiens screenshots reference; API path TBD | | CNAM | RingLogix / ViiBE | **Unknown** — ViiBE screenshots show CNAM tab | API path and data model TBD | **API base URL:** `https://api.ringlogix.com/pbx/v1/` (all calls POST with `object` and `action` in body — NOT RESTful GET). **CRITICAL:** CDR/call-history, billing, and E911 endpoints are NOT available via the current RingLogix API. See [Unknowns & Caveats](#unknowns--caveats). --- ## RBAC, Tenant Isolation & Security ### Role Definitions | Role | Access Scope | Auth Mechanism | Login Identifier | |---|---|---|---| | **IT Staff** | All 14 domains, all views, admin panel, audit log, domain selector | Hardcoded credentials: `info@voipsimplicity.com` + password | Email | | **Customer Admin** | Single domain, all customer views, billing, add/remove authorized users | Domain ID or registered email + password | Domain ID, account email, or authorized-user email | | **Authorized User** | Single domain, subset of views (no billing, no user management) — configurable by Customer Admin | Email + password, invited by Customer Admin | Authorized-user email | | **View-Only User** | Single domain, read-only dashboard + call history | Email + password, invited by Customer Admin | Authorized-user email | ### Tenant Isolation Rules - Every data query is scoped to `currentDomain` (customer) or selected domain (staff). - Staff domain selector changes `currentDomain` and re-renders the active view — never leaks cross-domain data. - Customer sessions are locked to a single domain ID returned on login. - Staff audit log entries include `performedBy` (staff email), `domain` (affected domain), and `impersonated` flag if acting as customer. ### Security Constraints - **Card data:** Never stored in browser session storage, `localStorage`, or cookies. Card updates go through a separate, secure payment-gateway path (Stripe Elements or equivalent hosted iframe). - **Session tokens:** `sessionStorage` only — cleared on logout (`sessionStorage.clear() + location.reload()`). - **No JWTs in URL:** Auth state never appears in query strings or URL fragments. - **MFA recovery codes:** Generated server-side, shown once, never stored in browser. - **Rate limiting:** Login attempts, MFA token requests, and password-reset requests rate-limited per IP and per account (5 attempts / 15 min window). - **Password reset tokens:** Single-use, time-limited (15 min), delivered via email only (SMS fallback TBD per provider availability). --- ## Audit & Compliance ### Audit Trail Requirements All state-changing operations produce immutable audit log entries: | Operation | Audit Fields | |---|---| | Login/logout | `ts`, `user`, `role`, `domain`, `action`, `ip` (if available) | | Marketplace add-on request | `ts`, `user`, `action:'addon_request'`, `domain`, `detail` (item name, extension, choice) | | Plan change / upgrade | `ts`, `user`, `action:'plan_change'`, `domain`, `detail` (from → to plan) | | Authorized user add/remove | `ts`, `user`, `action:'user_add'|'user_remove'`, `domain`, `detail` (affected user email + role) | | Contact info update | `ts`, `user`, `action:'contact_update'`, `domain`, `detail` (changed fields, not values) | | Payment method change | `ts`, `user`, `action:'payment_update'`, `domain` (no card details logged) | | Password reset | `ts`, `user`, `action:'password_reset'`, `domain` | | Staff domain switch | `ts`, `user`, `action:'domain_switch'`, `detail` (from → to domain) | ### Notification Rules - All marketplace orders produce a notification (ticket-like) visible to staff. - Authorized-user invitation emails are sent with a time-limited registration link. - Password reset and MFA token delivery produce notifications with delivery method noted. --- ## Phased MVP Sequence ### Phase 1: Foundation (MVP Launch) - Site login (split-half page, domain ID / email auth, password reset) - My Dashboard (per-customer stats + lists, no topology graph) - Call History (searchable, exportable — mock/placeholder data if CDR API unavailable) - Nav: Dashboard, Call History, Billing (read-only), My Info (read-only) ### Phase 2: Self-Service - My Info: editable contact info + payment method update (secure, separate path) - Marketplace: catalog browsing, cart, per-extension vs per-account selection, immediate provisioning vs request-discussion choice - Billing: invoice viewer, download, prior invoices list - Authorized user management: add/remove with RBAC ### Phase 3: Advanced - Graphical phone-system topology in Dashboard - MFA / one-time token delivery (email/SMS) - Recording playback in Call History (only if enabled) - Voicemail inline in Call History - Music on Hold, Time Frames displays - Order-services contact form on login page ### Phase 4: Feature Parity - E911 inventory display - SIP trunk status - Answer rules viewer - CNAM management (if API available) - Staff-only reports, LNP, number orders (ViiBE integration) --- ## Requirement Areas ### 1. My Dashboard #### 1.1 Per-Customer Aggregate View **Customer sees:** | Metric | Data Source | Format | |---|---|---| | Total extensions | `subscriber/read` filtered to 100–399 | Large stat card: "12 Extensions" | | Call queues | `callqueue/read` count | Stat card: "3 Queues" | | DID inventory | `phonenumber/read` filtered by `dialrule_domain` | Stat card: "5 Phone Numbers" | | Auto attendants | `attendant/read` count | Stat card: "2 Attendants" | | Subscribed plan | Manual / RingLogix catalog (TBD) | Badge: "Business Pro" | **Staff sees (domain selector active):** - Same metrics for the selected domain. - Aggregate "All Domains" stats: total subscribers, DIDs, queues, attendants across all 14 domains. #### 1.2 Detail Lists (Expandable Under Stats) | List | Columns | Notes | |---|---|---| | Extensions | Name, Email, Extension #, Voicemail (badge) | Filtered to 100–399. System routes hidden by toggle. | | DIDs | Phone Number (formatted), Domain, Assigned Extension | Full DID list for domain. | | Call Queues | Queue Name, Extension, Strategy (Linear Hunt, etc.), Members count | From `callqueue/read`. | | Auto Attendants | Extension, Name, Schedule, Prompt Type | From `attendant/read`. Menu options NOT available via API — show note to use RingLogix admin. | #### 1.3 Music on Hold - **Data source:** Unknown endpoint. Screenshots (NetSapiens) show MOH configuration per domain. - **Fallback:** Display "Configured via RingLogix Admin Panel" with a note until API endpoint is confirmed. #### 1.4 Time Frames - **Data source:** `timeframe/read` per domain. - **Display:** Table of time frame names, schedules, and associated objects (attendants, routes). - **Staff view:** Full edit capability (if API supports write), otherwise read-only with admin-panel link. #### 1.5 Graphical Phone-System Topology (Phase 3) - **Requirement:** Visual graph/flowchart showing: - Inbound DID → Time Frame → Auto Attendant → Call Queue → Extensions - Nodes color-coded by type (DID=gold, Attendant=blue, Queue=teal, Extension=green) - Connected edges show full routing path - **Rendering:** Canvas or SVG-based, mobile-responsive (scrollable on small screens). - **Data:** Built from `phonenumber/read` (matchrule, dialrule_domain), `attendant/read` (timeframes, menus), `callqueue/read` (connect_to), `subscriber/read` relationships. - **Note:** Menu-level routing (specific attendant option → extension) is NOT available via current API. Graph shows attendant → connected queues/extensions at the object level, not per-menu-option. --- ### 2. Call History #### 2.1 Unified View Single page merging incoming and outgoing calls — NOT separate "Call Logs" + "Recordings" tabs. Customers see one searchable list. #### 2.2 Search - **Searchable fields:** Caller name AND phone number. - **Behavior:** `oninput` handler with no submit button. Real-time filtering across both inbound and outbound calls. - **Implementation:** Single search box with `data-search` attribute on rows containing lowercase concatenation of caller name + phone number. #### 2.3 Table Columns | # | Column | Content | Notes | |---|---|---|---| | 1 | Date/Time | `YYYY-MM-DD HH:MM AM/PM` | Sortable | | 2 | Direction | `↓ Incoming` (teal) or `↑ Outgoing` (gold) | Text label + arrow | | 3 | Caller Name | Avatar circle + name | Unknown callers: gray "?" avatar + "Unknown" | | 4 | Caller Phone | Formatted `(XXX) XXX-XXXX` | Muted secondary text | | 5 | Destination | Extension number or queue name | Who handled the call | | 6 | Status | Badge: Answered (teal), Missed (red), Voicemail (gray) | Color-coded | | 7 | Voicemail | `📝 View Transcript` button or `—` | Opens modal with transcript text; only shown if call was missed → voicemail left | | 8 | Recording | `▶ MM:SS` play button or `—` | **Only shown if recording is enabled for this domain/extension.** Inline playback. | | 9 | Duration | `MM:SS` | Call duration | #### 2.4 Recording Playback - **Conditional:** Recording play button appears ONLY when recording is enabled. RingLogix recording toggle is per-domain or per-extension — portal must check this. - **Playback:** Inline HTML5 `