599 lines
32 KiB
Markdown
599 lines
32 KiB
Markdown
# 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 `<audio>` or Web Audio API. Signed URLs from Wasabi S3 (proxy through portal or generate pre-signed URLs).
|
||
- **No download required:** Play in-page. Download button separate if needed.
|
||
|
||
#### 2.5 Export
|
||
|
||
- **"Export All":** Downloads entire call history dataset as CSV (all calls for the domain, unfiltered).
|
||
- **"Export Current View":** Downloads only the currently filtered/search-results as CSV.
|
||
- **Format:** Standard CSV with column headers matching table columns. Arrow characters cleaned: `↓` → `Incoming`, `↑` → `Outgoing`.
|
||
- **Implementation:** Build CSV string, create `Blob`, trigger download via temporary `<a>` element with `download` attribute.
|
||
|
||
#### 2.6 Data Source Caveat
|
||
|
||
**CDR endpoints all return 404** from RingLogix API (`cdr`, `call_detail_record`, `callhistory`). Until an alternative is found:
|
||
- **MVP fallback:** Placeholder/mock call data with clear labeling OR NetSapiens CDR export imported manually.
|
||
- **Target source:** NetSapiens CDR API (if RingLogix exposes it under a different object name), RingLogix reseller-level call reporting, or direct PBX CDR collection.
|
||
- **Recording source:** Wasabi S3 bucket (confirmed: RingLogix writes call recordings to Wasabi). Portal can list/stream recordings if bucket paths are structured by domain.
|
||
|
||
---
|
||
|
||
### 3. Marketplace
|
||
|
||
#### 3.1 Catalog & Cart
|
||
|
||
| Requirement | Detail |
|
||
|---|---|
|
||
| Plans/features browsing | Cards with plan name, price, included features, description |
|
||
| Cart metaphor | Add-on items collected in a running cart before submission |
|
||
| Per-extension vs per-account distinction | Each item tagged `perLine: true/false/'did'` |
|
||
| Per-extension selection | Modal with extension dropdown (100–399) — user selects ONE, MULTIPLE (checkboxes), or ALL extensions |
|
||
| Per-DID selection | SMS/Text Messaging shows DID dropdown instead of extensions |
|
||
| Per-account items | No selector — applies to entire domain |
|
||
|
||
#### 3.2 Provisioning Choice
|
||
|
||
After selecting extensions/DIDs, user chooses:
|
||
|
||
| Option | Behavior |
|
||
|---|---|
|
||
| **Apply Now** *(Immediate Provisioning)* | If the applicable provider API supports the requested write action and the item is eligible for automation, provision the add-on immediately. Confirmation + audit log. |
|
||
| **Discuss with VoIPSimplicity** *(Request Discussion)* | Creates a ticket/order for staff review. Audit log entry. Notification to staff. |
|
||
|
||
**Note:** Immediate provisioning requires RingLogix write API access (not yet confirmed). Until confirmed, ALL additions default to "Request Discussion" flow.
|
||
|
||
#### 3.3 Audit, Ticket & Notification
|
||
|
||
- Every add-on request (immediate or discussion) produces:
|
||
1. **Audit log entry** with full detail (item, domain, extensions, provisioning choice).
|
||
2. **Staff-visible ticket** in Admin Panel → Audit Log tab.
|
||
3. **Confirmation notification** to the customer (on-screen success modal: "Our team will contact you within 24 hours.").
|
||
- Staff can view, approve, or reject requests.
|
||
|
||
#### 3.4 Approval Boundaries
|
||
|
||
| Item Type | Auto-Provision? | Requires Approval? |
|
||
|---|---|---|
|
||
| Per-account add-on (SMS, Analytics, DID, Fax, Priority Support) | No (Phase 2 target) | Yes — staff review |
|
||
| Per-extension add-on (Call Recording, Voicemail Transcription) | No (Phase 2 target) | Yes — staff review |
|
||
| Plan upgrade/downgrade | No | Yes — billing + provisioning review |
|
||
| International calling enablement | No | Yes — fraud review |
|
||
|
||
**Caveat:** Approval automation depends on RingLogix write API availability. Until confirmed, ALL changes go through manual staff review. This document must not claim RingLogix supports write endpoints that are unverified.
|
||
|
||
#### 3.5 Data-Source Caveat
|
||
|
||
The marketplace catalog (plans, add-ons, pricing) has no confirmed RingLogix API endpoint. Current implementation uses:
|
||
- **Hardcoded catalog** in portal JS (10 items with name, price, description, perLine flag).
|
||
- **Manual sync** from RingLogix reseller panel pricing.
|
||
- **Target:** RingLogix reseller catalog API (to be confirmed) or Stripe product catalog.
|
||
|
||
---
|
||
|
||
### 4. Billing
|
||
|
||
#### 4.1 Current Plan Summary
|
||
|
||
| Field | Data Source | Notes |
|
||
|---|---|---|
|
||
| Plan name | Hardcoded / RingLogix catalog | e.g., "Business Pro" |
|
||
| Plan price | Hardcoded / RingLogix | Monthly or annual |
|
||
| Included features | Hardcoded list | Teal "Active" badges |
|
||
| Available but unsubscribed options | Hardcoded list | Gray "Available" badges with "Add in Marketplace" link |
|
||
|
||
#### 4.2 Prior Invoices
|
||
|
||
| Column | Notes |
|
||
|---|---|
|
||
| Date | `YYYY-MM-DD` |
|
||
| Invoice Number | Unique identifier |
|
||
| Amount | Formatted currency |
|
||
| Status | Paid (teal), Pending (gold), Overdue (red) |
|
||
|
||
#### 4.3 Invoice Viewer
|
||
|
||
- **Inline framed viewer:** Opens an iframe/modal overlay showing the invoice PDF.
|
||
- **Closeable:** Close button, backdrop click, Escape key dismiss.
|
||
- **Download options:**
|
||
- Download individual invoice
|
||
- Download multiple (selected via checkboxes)
|
||
- Download all invoices
|
||
- **Data source caveat:** No confirmed RingLogix billing API. Invoice data likely from RingLogix admin panel export, Stripe billing portal, or manual upload.
|
||
|
||
#### 4.4 Payment Method
|
||
|
||
- **Separate, secure update path:** Card update form isolated from the main billing view.
|
||
- **Never stored in browser:** Card number, CVV, expiry never touch `sessionStorage`, `localStorage`, or in-memory JS objects longer than the update transaction.
|
||
- **Integration:** Stripe Elements (hosted iframe) or equivalent PCI-compliant solution. Portal sends a token, never raw card data.
|
||
- **Current implementation** (demo): `sessionStorage`-backed card display (`voip_cc`, `voip_cc_expiry`) — **NOT production-grade.** Migration to Stripe Elements required before go-live.
|
||
|
||
---
|
||
|
||
### 5. My Info
|
||
|
||
#### 5.1 Contact Information
|
||
|
||
| Field | Editable | Validation |
|
||
|---|---|---|
|
||
| Name | Yes | Required |
|
||
| Email (account) | Yes | Required, valid email format |
|
||
| Phone | Yes | Optional, US format |
|
||
| Address | Yes | Optional, street/city/state/ZIP |
|
||
| Company Name | No | Read-only, set at account creation |
|
||
| Domain ID | No | Read-only, displayed for reference |
|
||
|
||
**Edit pattern:** All fields disabled by default. "Edit" button toggles to "Cancel"; editable fields get teal border. "Save Changes" button appears during edit mode. Save writes to `currentUser` + `sessionStorage`, redraws header badge.
|
||
|
||
#### 5.2 Payment Method (Separate from Billing)
|
||
|
||
- **Update payment method:** Button opens a modal/section with secure card form (Stripe Elements).
|
||
- **Separate from Contact Info card:** Payment update is its own card/section, not mixed with personal info fields.
|
||
- **Card display in view mode:** `•••• 4242` (last 4 only) + expiry.
|
||
|
||
#### 5.3 Authorized Users
|
||
|
||
| Requirement | Detail |
|
||
|---|---|
|
||
| Add user | Customer Admin enters name, email, role (Authorized User / View-Only). Invitation email sent. |
|
||
| Manage users | Table of current authorized users: Name, Email, Role, Status (Active/Invited/Revoked). Revoke button. |
|
||
| RBAC | Per-user role controls which views are accessible (see [RBAC](#rbac-tenant-isolation--security)). |
|
||
| Invitation flow | Email with time-limited registration link → user sets password → added to domain. |
|
||
| Audit trail | All add/remove/role-change operations logged in audit. |
|
||
|
||
---
|
||
|
||
### 6. Site Login
|
||
|
||
#### 6.1 Split-Half Login Page
|
||
|
||
**Layout:**
|
||
- **LEFT (60% desktop, 100% mobile):** Navy gradient background. Login form: "Email or Domain ID" field + "Password" field + "Sign In" button + "Forgot Password?" link.
|
||
- **RIGHT (40% desktop, 100% mobile):** White/light background. "Need Help?" section: "Submit a Ticket" button (mailto:support@voipsimplicity.com), phone (888.601.1173), email (support@voipsimplicity.com), and order-services contact form.
|
||
- **Mobile (<768px):** Stack vertically — login on top, help/contact below.
|
||
|
||
#### 6.2 Authentication Methods
|
||
|
||
| Method | Identifier | Use Case |
|
||
|---|---|---|
|
||
| Domain ID | 6-digit numeric (e.g., `287275`) | Customer authenticates with their RingLogix domain ID + password |
|
||
| Account email | Registered email (e.g., `admin@grandlakeclub.com`) | Customer authenticates with account-level email |
|
||
| Authorized-user email | Individual user email (e.g., `deborah@grandlakeclub.com`) | Authorized users sign in with their own email |
|
||
| Staff email | `info@voipsimplicity.com` | IT staff — full admin access to all domains |
|
||
|
||
**Customer→domain mapping:** Real-time API lookup against RingLogix `domain/read` or a local domain-to-email mapping cache.
|
||
|
||
#### 6.3 Password Reset
|
||
|
||
- **Trigger:** "Forgot Password?" link on login page.
|
||
- **Flow:** Enter email or domain ID → email sent with single-use, time-limited (15 min) reset link → user sets new password → confirmation.
|
||
- **Rate limiting:** 3 reset requests per email per hour.
|
||
|
||
#### 6.4 MFA / One-Time Token (Phase 3)
|
||
|
||
| Aspect | Requirement |
|
||
|---|---|
|
||
| Delivery methods | Email (primary) + SMS (secondary, if provider supports) |
|
||
| Token lifetime | 5 minutes |
|
||
| Rate limiting | 5 attempts per 15 minutes per account |
|
||
| Recovery | Recovery codes generated on MFA enrollment (shown once, stored by user) |
|
||
| Exploration scope | Evaluate Twilio Verify, email OTP, and TOTP authenticator apps |
|
||
| Caveat | SMS delivery depends on Twilio number provisioning and A2P 10DLC registration |
|
||
|
||
#### 6.5 Order-Services Contact Form
|
||
|
||
- **Location:** Right panel of login page (below "Need Help?" section).
|
||
- **Fields:** Name, Email, Phone, Company, Service Interest (dropdown: New Phone System, Add Features, Porting Numbers, Other), Message.
|
||
- **Submission:** Emailed to `info@voipsimplicity.com` (or CRM integration). Confirmation message displayed.
|
||
- **Spam protection:** reCAPTCHA or honeypot field.
|
||
|
||
---
|
||
|
||
### 7. Screenshot-Informed Requirements
|
||
|
||
The owner provided screenshot groups from two platforms. These inform the portal's feature surface and data expectations but do NOT imply all features are available via API.
|
||
|
||
#### 7.1 ViiBE Seller-Side Views (Staff-Only)
|
||
|
||
| Screenshot Group | Portal Equivalent | API Availability |
|
||
|---|---|---|
|
||
| **Accounts** | Admin Panel → Domains list (already built: 14-domain roster with stats) | `domain/read` ✅ |
|
||
| **Quotes** | Marketplace → Quote requests / orders (staff review tab) | ❌ Unknown — RingLogix quoting API not confirmed |
|
||
| **Products** | Marketplace → Catalog management (staff) | ❌ Unknown — manual catalog in portal |
|
||
| **LNP (Local Number Porting)** | Admin Panel → Porting Status (staff) | ❌ Unknown — ViiBE LNP integration not confirmed for RingLogix |
|
||
| **Number Orders** | Admin Panel → Number Orders (staff) | ❌ Unknown — RingLogix number ordering API not confirmed |
|
||
| **CNAM** | Admin Panel → CNAM Management (staff) | ❌ Unknown — ViiBE screenshots show CNAM tab |
|
||
| **Mobile Connect** | Future: Mobile app pairing / softphone config | ❌ Not available via RingLogix API |
|
||
| **Reports** | Admin Panel → Reports (staff) | ⚠️ Partial — domain/subscriber/queue stats available; CDR reports NOT available |
|
||
|
||
#### 7.2 NetSapiens Customer/Manager Views
|
||
|
||
| Screenshot Group | Portal Equivalent | API Availability | Customer or Staff? |
|
||
|---|---|---|---|
|
||
| **Home / Statistics** | My Dashboard (stats + lists) | ✅ `subscriber/read`, `callqueue/read`, etc. | Customer |
|
||
| **Domains** | Admin Panel (staff domain selector) | ✅ `domain/read` | Staff |
|
||
| **SIP Trunks** | Dashboard → SIP Trunks card (Phase 4) | ❌ Unknown — no confirmed RingLogix endpoint | Customer/Staff |
|
||
| **Phone Inventory** | Dashboard → DIDs list | ✅ `phonenumber/read` (filter client-side) | Customer |
|
||
| **E911 Inventory** | Dashboard → E911 card (Phase 4) | ❌ Unknown — no confirmed RingLogix endpoint | Customer/Staff |
|
||
| **Call History** | Call History view | ❌ CDR endpoints all return 404 | Customer |
|
||
| **Contacts** | Future: Personal/speed-dial contacts | ❌ Not available via RingLogix API | Customer |
|
||
| **Answer Rules** | Extensions → Answer Rules tab (Phase 4) | ❌ Unknown — no confirmed RingLogix endpoint | Customer |
|
||
| **Time Frames** | Dashboard → Time Frames list | ✅ `timeframe/read` | Customer |
|
||
| **User Voicemail / Settings** | Voicemail view | ✅ `subscriber/read` (vmail fields) | Customer |
|
||
| **Music / Messages** | Dashboard → Music on Hold (Phase 3) | ❌ Unknown — no confirmed endpoint | Customer/Staff |
|
||
| **Call-Center Queues / Statistics** | Call Queues view + Dashboard stats | ✅ `callqueue/read` (queue list; real-time stats unknown) | Customer/Staff |
|
||
| **Auto Attendants** | Auto Attendants view | ✅ `attendant/read` (object list; menu detail NOT available) | Customer |
|
||
|
||
**Key:** ✅ Available | ⚠️ Partial | ❌ Unknown/Unavailable | 🔮 Future
|
||
|
||
---
|
||
|
||
## Nav Organization (Expanded Canonical)
|
||
|
||
Based on the existing portal skill's nav structure, expanded for the full requirement set:
|
||
|
||
```
|
||
Main
|
||
Dashboard # Per-customer stats, lists, topology (Phase 3)
|
||
|
||
Phone System
|
||
Extensions # List + detail: 100-399 users, voicemail status
|
||
Call History # Unified incoming/outgoing, search, export, recordings
|
||
Call Queues # Queue list, members, strategy
|
||
Auto Attendants # Attendant list, schedules, prompts
|
||
Voicemail # Voicemail messages, settings, transcription
|
||
|
||
Account
|
||
Billing # Plan, invoices, invoice viewer, payment method
|
||
Marketplace # Plans catalog, cart, add-on requests
|
||
My Info # Contact info, payment method, authorized users
|
||
|
||
Administration (staff only — hidden for customers)
|
||
Admin Panel # Domain selector, domain roster, audit log
|
||
Reports # Staff reports (Phase 4)
|
||
Number Orders # DIDs, LNP, CNAM (Phase 4)
|
||
```
|
||
|
||
---
|
||
|
||
## Acceptance Criteria by Phase
|
||
|
||
### Phase 1: Foundation
|
||
|
||
- [ ] Login page renders split-half layout; mobile stacks vertically.
|
||
- [ ] Customer can log in with domain ID (e.g., `287275`), account email, or authorized-user email.
|
||
- [ ] Staff can log in with `info@voipsimplicity.com` and see domain selector.
|
||
- [ ] Refresh/back button does NOT log out (sessionStorage persistence).
|
||
- [ ] Dashboard shows per-customer aggregate stats (extensions, queues, DIDs, attendants) — filtered to real extensions (100–399).
|
||
- [ ] Dashboard extension list shows Name, Email, voicemail badge.
|
||
- [ ] Dashboard DID list, queue list, attendant list render with correct data.
|
||
- [ ] Call History table renders with search (if CDR data unavailable: clear "No data available — Call history coming soon" empty state).
|
||
- [ ] Navigation toggles active state; customer never sees Admin nav items.
|
||
- [ ] Domain selector hidden for customer-role users.
|
||
- [ ] All unwired views show canonical "No data available." empty state with RingLogix API note.
|
||
|
||
### Phase 2: Self-Service
|
||
|
||
- [ ] My Info: Name, Email, Phone editable with Edit/Save/Cancel pattern.
|
||
- [ ] Payment method: secure Stripe Elements form, card data never in browser storage.
|
||
- [ ] Authorized users: add/remove with RBAC, invitation email, audit log.
|
||
- [ ] Marketplace: catalog cards render with per-extension vs per-account distinction.
|
||
- [ ] Marketplace: extension/DID selector modal for per-line items (one, multiple, all).
|
||
- [ ] Marketplace: immediate provisioning vs request-discussion radio choice.
|
||
- [ ] Marketplace: all requests produce audit entry + staff notification.
|
||
- [ ] Billing: invoice list with date, number, amount, status.
|
||
- [ ] Billing: inline framed invoice viewer with close/ESC dismiss.
|
||
- [ ] Billing: download individual, multiple (checkbox-select), or all invoices.
|
||
|
||
### Phase 3: Advanced
|
||
|
||
- [ ] Graphical phone-system topology in Dashboard (DID → TF → AA → Queue → Ext).
|
||
- [ ] MFA enrollment flow with email OTP (SMS optional).
|
||
- [ ] Call History: recording playback (only when recording enabled).
|
||
- [ ] Call History: voicemail transcript inline.
|
||
- [ ] Dashboard: Music on Hold display.
|
||
- [ ] Dashboard: Time Frames list with schedules.
|
||
- [ ] 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 reports (aggregate call stats, domain comparisons).
|
||
- [ ] LNP porting status.
|
||
- [ ] Number orders.
|
||
|
||
---
|
||
|
||
## Unknowns & Caveats
|
||
|
||
### Confirmed Unavailable
|
||
|
||
| Feature | Detail | Impact |
|
||
|---|---|---|
|
||
| CDR / Call History API | `cdr`, `call_detail_record`, `callhistory` all return 404 | Call History requires alternative data source |
|
||
| Auto Attendant menu details | `attendant/read` returns object metadata but NOT per-option menu routing | Attendant detail view limited to name, schedule, prompt type |
|
||
| DID domain filtering | `phonenumber/read` ignores `domain` param — returns all DIDs across all domains | Client-side filtering required |
|
||
|
||
### Unconfirmed / Needs Investigation
|
||
|
||
| Feature | What to Verify | Priority |
|
||
|---|---|---|
|
||
| Billing/invoice API | Contact RingLogix: is there a billing API or reseller invoice endpoint? | High |
|
||
| Marketplace catalog API | Is there a reseller product catalog? If not, maintain hardcoded catalog synced manually. | High |
|
||
| Write API (provisioning) | Can add-ons be provisioned via API? `object=subscriber&action=update`? | High |
|
||
| Music on Hold endpoint | Is there an `musiconhold` or `moh` object? Test known NetSapiens object names. | Medium |
|
||
| E911 endpoint | Is there an `e911` or `emergency` object? | Medium |
|
||
| SIP trunk endpoint | Is there a `siptrunk` or `trunk` object? | Medium |
|
||
| Answer rules endpoint | Is there an `answerrule` or `callforward` object? | Medium |
|
||
| CNAM endpoint | ViiBE screenshots show CNAM tab — is this a ViiBE-only feature or available via RingLogix? | Medium |
|
||
| OAuth scope grants | Read endpoints may need scope grants from RingLogix support (Hussain Alkalaf, hussain@ringlogix.com, 440-382-3223) | Medium |
|
||
| Rate limiting | 429 observed — current sync script uses 0.5s delay. Portal must match. | Low |
|
||
|
||
### Design Constraints (from Owner)
|
||
|
||
- **Light/neutral theme ONLY** — white/light gray backgrounds, dark text. No dark mode for customer-facing portal.
|
||
- **Mobile-first** — all views must be usable on ≤375px screens.
|
||
- **No framework dependencies** — single-file HTML SPA, no React/Vue/Angular.
|
||
- **Google Fonts (Inter) only external dependency.**
|
||
- **No fabricated data** — every unwired view shows canonical "No data available." empty state.
|
||
- **Canonical nav** — sidebar with `data-view` attributes, `switchView()` dispatch.
|
||
|
||
---
|
||
|
||
## Out of Scope (Deferred to Post-MVP)
|
||
|
||
| Feature | Reason |
|
||
|---|---|
|
||
| AI Receptionist integration | Separate product (see [ai-receptionist.md](./ai-receptionist.md)), not portal-bound |
|
||
| Twilio call handling | Twilio setup is infrastructure, not portal feature |
|
||
| Competitor price monitoring | Covered in [competitor-analysis.md](./competitor-analysis.md) — not portal feature |
|
||
| WordPress marketing site | `voipsimplicity.com` is a separate WordPress site, out of portal scope |
|
||
| Full RingLogix admin replacement | Portal is customer-facing + staff review, NOT a full admin panel replacement |
|
||
| International numbers / multi-currency | US-only for MVP |
|
||
| Developer APIs / webhooks | Post-MVP |
|
||
| White-label reskinning | Post-MVP |
|
||
| Mobile native app | Web-only SPA for MVP; PWA wrapper considered for Phase 4 |
|
||
|
||
---
|
||
|
||
*Document maintained in `/root/projects/voipsimplicity/PORTAL-REQUIREMENTS.md`. Companion gap analysis at [PORTAL-GAP-ANALYSIS.md](./PORTAL-GAP-ANALYSIS.md).*
|