docs: define customer portal requirements

This commit is contained in:
root
2026-07-24 11:34:39 -04:00
parent d0acaf6a87
commit 0768622a52
3 changed files with 946 additions and 0 deletions
+15
View File
@@ -1,5 +1,20 @@
# voipsimplicity.com — Migration CHANGELOG # voipsimplicity.com — Migration CHANGELOG
## 2026-07-24 — Portal requirements documentation (revised v2.0)
### Revised
- **[PORTAL-REQUIREMENTS.md](./PORTAL-REQUIREMENTS.md)** — replaced with comprehensive v1.0 covering all 7 owner-specified requirement areas:
1. **My Dashboard:** per-customer stats, lists (extensions/DIDs/queues/attendants), music on hold, time frames, graphical topology (Phase 3).
2. **Call History:** unified search (name + phone), direction/status/destination columns, recording playback (conditional), voicemail transcripts, CSV export (all + filtered), CDR data-source caveat (RingLogix CDR endpoints all return 404).
3. **Marketplace:** plans/features catalog, cart, per-extension vs per-account distinction, one/multiple/all extension selection, immediate provisioning vs request-discussion choice, audit log + ticket + notification, approval boundaries, data-source caveat.
4. **Billing:** plan/price summary, included + available features, prior invoices list (date/number/amount/status), inline framed invoice viewer (closeable), download individual/multiple/all, separate secure card update path, NEVER store card data in browser storage.
5. **My Info:** view/update name/email/phone/address, separately update payment method, add/manage authorized users with RBAC/invitation/audit trail.
6. **Site Login:** split-half login page, authenticate by domain ID/account email/authorized-user email, password reset, MFA/one-time token exploration (email/SMS) with rate limiting and recovery, order-services contact form.
7. **Screenshot-informed features:** ViiBE seller-side (Accounts, Quotes, Products, LNP, Number Orders, CNAM, Mobile Connect, Reports) and NetSapiens customer/manager views (Home/Statistics, Domains, SIP Trunks, Phone Inventory, E911, Call History, Contacts, Answer Rules, Time Frames, Voicemail/Settings, Music/Messages, Call-Center Queues/Statistics, Auto Attendants). Staff-only vs customer views separated. Provider/API unknowns marked — does not claim RingLogix supports unsupported endpoints.
- Document includes sources section (owner screenshots + Obsidian notes), source-of-truth table with API availability, RBAC/tenant isolation rules, audit/compliance requirements, phased MVP sequence (4 phases), acceptance criteria, unknowns/caveats, and out-of-scope items.
- **[PORTAL-GAP-ANALYSIS.md](./PORTAL-GAP-ANALYSIS.md)** — replaced with v2.0, reorganized to map gap analysis directly to the 7 owner requirement areas. Includes source-of-truth data availability matrix (19 data categories with API status), screenshot-to-feature mapping for both Viirtue and Apollo screenshots, design/UX comparison, technical architecture gaps (backend DB, payment gateway, file storage), and P0P4 priority matrix. References 22 owner-provided screenshots and Obsidian notes.
- No code or configuration changes — documentation only. Portal deployment, DNS, APIs, and credentials unchanged.
## 2026-07-24 — Entity record started ## 2026-07-24 — Entity record started
### Added ### Added
+333
View File
@@ -0,0 +1,333 @@
# my.voipsimplicity.com — Portal Gap Analysis
**Status:** Documentation-only analysis
**Version:** 2.0.0 (revised for owner requirement areas)
**Date:** July 24, 2026
**References:** [PORTAL-REQUIREMENTS.md](./PORTAL-REQUIREMENTS.md) — canonical requirements doc; Viirtue/ViiBE seller portal (`voipsimplicity.viibewithus.com`, v2.8.0) and Apollo/NetSapiens manager+user portals (`portal.voipsimplicity.com`, v44.5.1) — 22 screenshots provided by owner Germaine Brown; [Obsidian notes](#sources) from owner.
> **Purpose:** Map the 7 owner-specified requirement areas (Dashboard, Call History, Marketplace, Billing, My Info, Site Login, Screenshot Groups) against current portal state and identify what needs to be built, wired, or deferred.
---
## Table of Contents
1. [Sources](#sources)
2. [Gap Summary by Requirement Area](#gap-summary-by-requirement-area)
3. [Area 1: My Dashboard](#area-1-my-dashboard)
4. [Area 2: Call History](#area-2-call-history)
5. [Area 3: Marketplace](#area-3-marketplace)
6. [Area 4: Billing](#area-4-billing)
7. [Area 5: My Info](#area-5-my-info)
8. [Area 6: Site Login](#area-6-site-login)
9. [Area 7: Screenshot-Informed Features](#area-7-screenshot-informed-features)
10. [Source of Truth & Data Availability](#source-of-truth--data-availability)
11. [Technical Architecture Gaps](#technical-architecture-gaps)
12. [Implementation Priority Matrix](#implementation-priority-matrix)
---
## Sources
| Source | Type | Provider | Date |
|---|---|---|---|
| ViiBE/Viirtue seller portal | Screenshots (Accounts, Quotes, Products, LNP, Number Orders, CNAM, Mobile Connect, Reports) | Owner | July 2026 |
| Apollo/NetSapiens customer + manager portals | Screenshots (Home/Statistics, Domains, SIP Trunks, Phone Inventory, E911, Call History, Contacts, Answer Rules, Time Frames, Voicemail/Settings, Music/Messages, Call-Center Queues/Statistics, Auto Attendants) | Owner | July 2026 |
| Owner Obsidian notes | Design preferences, feature wishlist, operational constraints | Germaine Brown | July 2026 |
| Deployed portal | `/home/myvoip/htdocs/my.voipsimplicity.com/index.html` on app3 | Live system | July 2026 |
| `voip-portal-development` skill | 13 reference files covering API, patterns, deployment | Hermes skill repo | Ongoing |
---
## Gap Summary by Requirement Area
| # | Requirement Area | Current State | Gap Severity | Priority |
|---|---|---|---|---|
| 1 | **My Dashboard** | Stats + basic lists. No topology, MoH, or time frames. | Medium | Phase 13 |
| 2 | **Call History** | Unified search + export implemented. No recordings, no CDR data. | **High** | Phase 13 |
| 3 | **Marketplace** | Catalog + add-on request flow exists. No cart, no provisioning, no order tracking. | Medium | Phase 2 |
| 4 | **Billing** | Plan card + CC form (sessionStorage). No invoices, no gateway. | **High** | Phase 2 |
| 5 | **My Info** | Contact editing + CC form. No authorized users, no RBAC. | Medium | Phase 2 |
| 6 | **Site Login** | Split-half page + session restore. No MFA, no password reset, no contact form. | Medium | Phase 13 |
| 7 | **Screenshot Features** | 12+ feature sections visible in screenshots, 0 implemented. | **High** | Phase 14 |
**Overall gap severity:** High. The portal is a functional skeleton — login, nav, dashboard stats, call history search, and marketplace add-on requests work. Everything beyond these (MFA, billing invoices, authorized users, device lists, answering rules, time frames, contacts, music on hold, quotes/orders, reports) is absent or placeholder. Refer to [PORTAL-REQUIREMENTS.md](./PORTAL-REQUIREMENTS.md) for the complete phased plan.
---
## Area 1: My Dashboard
### Legend
| Symbol | Meaning |
|---|---|
| ✅ | Exists in current portal |
| 🟡 | Partially exists (skeleton, needs wiring) |
| ❌ | Missing entirely |
| ⬜ | Deferred (Phase 3+) |
### Dashboard Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| Per-customer aggregate stats (extensions, queues, DIDs, attendants) | ✅ | Phase 1 | Wired via RingLogix API. Filter to 100399 for real extensions. |
| Extension list (name, email, voicemail badge) | ✅ | Phase 1 | Implemented. System routes hidden by toggle. |
| DID inventory list | 🟡 | Phase 1 | `phonenumber/read` returns ALL DIDs — filter client-side by `dialrule_domain`. |
| Call queue list (name, strategy, members) | 🟡 | Phase 1 | `callqueue/read` wired. Members count not yet displayed. |
| Auto attendant list (name, schedule, prompt) | ✅ | Phase 1 | `attendant/read` wired. Menu options NOT available via API. |
| Subscribed plan display | 🟡 | Phase 1 | Hardcoded in billing card. Needs RingLogix catalog integration. |
| Music on Hold display | ❌ | Phase 3 | No confirmed RingLogix endpoint. Apollo screenshots show MoH UI. |
| Time Frames list | ❌ | Phase 1 (Apollo ref) | `timeframe/read` endpoint confirmed; not yet wired in portal. Apollo shows Name, Owner, When, Recurrence, Ends On columns. |
| Graphical phone-system topology | ❌ | Phase 3 | No current implementation. Requires Canvas/SVG rendering of DID→TF→AA→Queue→Ext routing graph. |
**Dashboard gap assessment:** Current dashboard covers Phase 1 aggregate stats and basic lists. Missing: time frames (Phase 1 wiring needed), music on hold (blocked on API), topology graph (Phase 3 build), and plan display integration.
---
## Area 2: Call History
### Call History Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| Unified search (name + phone, single input) | ✅ | Phase 1 | `oninput` handler, real-time filtering, `data-search` attributes. |
| Direction indicators (↓ incoming, ↑ outgoing) | ✅ | Phase 1 | Teal/gold color scheme implemented. |
| Date/Time, Direction, Name, Phone, Destination, Duration columns | ✅ | Phase 1 | All implemented in call-history-pattern. |
| Status badges (Answered/Missed/Voicemail) | ✅ | Phase 1 | Color-coded badges implemented. |
| Date range filter (Today/Week/Month/All) | 🟡 | Phase 1 | Time period filter in skill; Apollo shows calendar date picker. Enhance to date-range picker. |
| CSV Export (All + Current View) | ✅ | Phase 1 | Both export buttons implemented. Arrow character cleanup. |
| Recording playback (inline, conditional on enabled) | 🟡 | Phase 3 | Play button UI exists. Blocked on Wasabi S3 signed-URL generation and per-domain recording-enabled check. |
| Voicemail transcript (inline modal) | 🟡 | Phase 3 | Transcript button + modal UI implemented. Blocked on CDR/vmail data availability. |
| **CDR data availability** | ❌ | Phase 1 | **CRITICAL BLOCKER.** `cdr`, `call_detail_record`, `callhistory` all return 404 from RingLogix API. All Call History features are placeholder until an alternative data source is found (NetSapiens CDR export, RingLogix reseller-level reporting, or direct PBX collection). |
**Call History gap assessment:** The strongest area in the current portal — search, export, and rendering are well-implemented. The single critical blocker is CDR data availability. Without it, Call History can only show mock/placeholder data. Secondary gaps: recording playback (Wasabi integration), voicemail transcripts (data source), and date-range picker enhancement.
---
## Area 3: Marketplace
### Marketplace Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| Plans/features catalog browsing | ✅ | Phase 2 | Cards with name, description, price, perLine flag. 10 hardcoded items. |
| Per-extension vs per-account distinction | ✅ | Phase 2 | `perLine: true/false/'did'` flags. Event delegation pattern. |
| Extension selector modal (single extension) | ✅ | Phase 2 | Modal with dropdown (100-399). |
| **Multiple/all extensions selection** | ❌ | Phase 2 | Only single extension selection implemented. Need checkboxes + "Select All" for multi-extension add-ons. |
| Per-DID selector (SMS/Text Messaging) | ✅ | Phase 2 | DID dropdown from `extension_list` filtered by 10+ digit regex. |
| Cart metaphor | ❌ | Phase 2 | No cart — items processed one at a time. Need running cart before submission. |
| Immediate provisioning vs request-discussion choice | ❌ | Phase 2 | Only "Request Discussion" flow implemented. Immediate provisioning requires RingLogix write API (unconfirmed). |
| Audit log entries for all changes | ✅ | Phase 2 | `auditLog.push()` on every add-on request. |
| Staff-visible ticket/notification | 🟡 | Phase 2 | Audit entries logged; no separate ticket UI or email notification pipeline. |
| Approval boundaries / staff review workflow | ❌ | Phase 2 | No approval workflow. All requests go to manual review. |
**Marketplace gap assessment:** Add-on request flow is functional. Missing: multiple/all extensions selection, cart metaphor, provisioning choice (blocked on write API), and formal approval/ticket workflow. The catalog is hardcoded — no confirmed RingLogix product catalog API.
---
## Area 4: Billing
### Billing Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| Plan/price summary card | 🟡 | Phase 2 | Hardcoded domain name + pricing. Needs RingLogix plan integration. |
| Included features display | 🟡 | Phase 2 | Not implemented. Teal "Active" badges for plan features. |
| Available but unsubscribed options | ❌ | Phase 2 | Not implemented. Gray "Available" badges with Marketplace link. |
| Prior invoices list (date, number, amount, status) | ❌ | Phase 2 | **BLOCKED.** No confirmed RingLogix billing API. RingOS billing "coming soon." |
| Inline framed invoice viewer (closeable) | ❌ | Phase 2 | **BLOCKED** on invoice data source. |
| Download individual/multiple/all invoices | ❌ | Phase 2 | **BLOCKED** on invoice data source. |
| Separate secure card update path | 🟡 | Phase 2 | CC form exists in billing view but uses `sessionStorage`**NOT PCI-compliant.** Needs Stripe Elements or equivalent gateway. |
| Card data never in browser storage | ❌ | Phase 2 | Current implementation stores last-4 in sessionStorage. Must migrate to tokenized gateway. |
| Payment history | ❌ | Phase 2 | Viirtue shows Payments & Credits, Late Payers. Not in current portal. |
| Tax exemption / tax reports | ❌ | Phase 4 | Viirtue shows Tax Exemptions, Tax Liability, Tax Summary. Deferred. |
| Auto-pay toggle | ❌ | Phase 3 | Not in current portal. Requires payment gateway integration. |
**Billing gap assessment:** The billing view is a skeleton. The critical blocker is RingLogix RingOS billing API availability ("coming soon"). Without it, invoices must be manually uploaded or sourced from Stripe. Payment method needs a full PCI-compliant overhaul (Stripe Elements). Viirtue's Revenue/Billing/Compliance reports are the target model.
---
## Area 5: My Info
### My Info Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| View/update account name | ✅ | Phase 2 | Editable contact form with toggle. |
| View/update account email | ✅ | Phase 2 | Editable. |
| View/update phone | ✅ | Phase 2 | Editable. |
| View/update address | ❌ | Phase 2 | Not in current form. Needs street/city/state/ZIP fields. |
| Company name (read-only) | 🟡 | Phase 2 | Displayed in billing but not in My Info view. |
| Domain ID (read-only) | ❌ | Phase 2 | Not displayed. |
| Separately update payment method | 🟡 | Phase 2 | CC form in same billing view, not isolated. Needs separate secure path. |
| Add/manage authorized users | ❌ | Phase 2 | Not implemented. Viirtue shows multiple accounts per seller; Apollo shows multi-user domains. |
| RBAC for authorized users | ❌ | Phase 2 | Need roles: Customer Admin, Authorized User, View-Only. |
| Invitation flow | ❌ | Phase 2 | No invitation email flow. |
| Audit trail for user management | ❌ | Phase 2 | No audit entries for user add/remove/role-change. |
| Password change (self-service) | ❌ | Phase 1 | Not implemented. Viirtue and Apollo both imply password management. |
| Notification preferences | ❌ | Phase 4 | Apollo shows voicemail email, missed call, mailbox full notifications. |
**My Info gap assessment:** Basic contact editing exists. Major gaps: authorized user management with RBAC (entirely absent), address fields, payment method isolation, password self-service, and notification preferences. The Viirtue Account Detail page (with tabs: Details, Quotes, Number Orders, Notes, Storage) is the primary model for Phase 2+.
---
## Area 6: Site Login
### Site Login Feature Gap
| Feature | Current | Required By | Gap Detail |
|---|---|---|---|
| Split-half login page (login left, help right) | ✅ | Phase 1 | Implemented. Navy gradient left, white right. Mobile stacks vertically. |
| Authenticate by domain ID | ✅ | Phase 1 | Domain ID → password. Customer→domain mapping hardcoded for demo. |
| Authenticate by account email | ✅ | Phase 1 | Email → password. |
| Authenticate by authorized-user email | ❌ | Phase 2 | Requires authorized user table + per-user credentials. |
| Staff login (`info@voipsimplicity.com`) | ✅ | Phase 1 | Hardcoded. Staff badge + domain selector on success. |
| Session persistence (refresh/back button) | ✅ | Phase 1 | `sessionStorage` — cleared on logout. |
| Password reset | ❌ | Phase 1 | Not implemented. Needs email-based token flow with rate limiting. |
| MFA / one-time token (email/SMS) | ❌ | Phase 3 | Not implemented. Exploration target: Twilio Verify, email OTP, TOTP apps. |
| Rate limiting on login attempts | ❌ | Phase 1 | No rate limiting in current implementation. |
| MFA recovery codes | ❌ | Phase 3 | Generated on enrollment, shown once. |
| Order-services contact form | ❌ | Phase 3 | Not implemented. Needs Name/Email/Phone/Company/Interest/Message fields on login page. |
**Site Login gap assessment:** Core authentication (split-half page, domain ID/email login, staff login, session persistence) is solid. Missing: authorized-user email auth, password reset, MFA, rate limiting, and the order-services contact form. MFA is a Phase 3 exploration target due to SMS dependency on Twilio provisioning and A2P 10DLC registration.
---
## Area 7: Screenshot-Informed Features
The owner provided 22+ screenshots from Viirtue/ViiBE (seller-side) and Apollo/NetSapiens (customer + manager). These reveal 12+ feature sections not in the current portal. **Staff-only views are marked.** Provider/API data availability is noted — this document does NOT claim RingLogix supports endpoints that are unverified.
### 7.1 ViiBE/Viirtue Seller-Side Screenshots (Staff-Only)
| Screenshot Feature | Current Portal | Required By | API Availability | Gap Detail |
|---|---|---|---|---|
| **Accounts** (account list, tabs) | 🟡 | Phase 1 | `domain/read` ✅ | Admin Panel shows 14-domain roster. Missing: per-account detail with Details/Quotes/Number Orders/Notes/Storage tabs. |
| **Quotes** (Quote Name, Company, Owner, Status; create/edit) | ❌ | Phase 2 | ❌ No RingLogix quoting API | Need portal DB for quotes. Model: Viirtue table + line-item creation from product catalog. |
| **Products** (product catalog, per-seat/per-account pricing) | ❌ | Phase 2 | ❌ Unknown | Marketplace has hardcoded catalog. Staff need catalog management UI. |
| **LNP** (Port Date, Customer, Port Type, BTN, Status) | ❌ | Phase 4 | ❌ Unknown | Viirtue LNP integration. RingLogix porting API TBD. |
| **Number Orders** (Order No., Customer, Date, Description, Status) | ❌ | Phase 4 | ❌ Unknown | Viirtue number ordering. |
| **CNAM** (Order No., CNAM Value, Telephone No., Status) | ❌ | Phase 4 | ❌ Unknown | Viirtue CNAM tab. |
| **Mobile Connect** | ❌ | Deferred | ❌ Not available | Future: softphone/mobile app pairing. |
| **Reports** (Monthly Revenue, Recurring Revenue Growth, Revenue Projection) | ❌ | Phase 4 | ⚠️ Partial (stats available; CDR not) | Staff revenue dashboard. Viirtue Reports landing model. |
| **Account Notes** (staff-only timeline per account) | ❌ | Phase 4 | N/A (portal DB) | Staff notes per customer account. |
| **Document Storage** (file upload per account: LOAs, agreements) | ❌ | Phase 4 | N/A (portal DB + S3) | File upload/download per account. |
### 7.2 Apollo/NetSapiens Customer + Manager Views
| Screenshot Feature | Current | Required By | API Availability | Customer/Staff? |
|---|---|---|---|---|
| **Home / Statistics** | ✅ | Phase 1 | `subscriber/read`, `callqueue/read`, etc. ✅ | Customer + Staff |
| **Domains** | ✅ | Phase 1 | `domain/read` ✅ | Staff (domain selector) |
| **SIP Trunks** | ❌ | Phase 4 | ❌ Unknown — no confirmed endpoint | Customer/Staff |
| **Phone Inventory / Devices** | ❌ | Phase 4 | ⚠️ `mac/read` may exist — unverified | Customer |
| **E911 Inventory** | ❌ | Phase 4 | ❌ Unknown — no confirmed endpoint | Customer/Staff |
| **Call History** (date picker, recordings, blocked numbers) | 🟡 | Phase 1 | ❌ CDR endpoints return 404 | Customer |
| **Contacts** (Name, Number, Status, Department, Email; add/import/export) | ❌ | Phase 4 | ❌ Not available via RingLogix API | Customer |
| **Answer Rules** (Time Frame, Ring targets, Allow/Block, fallback) | ❌ | Phase 4 | ❌ Unknown | Customer |
| **Time Frames** (Name, Owner, When, Recurrence, Ends On; drag-to-reorder) | ❌ | Phase 1 | `timeframe/read` ✅ | Customer |
| **User Voicemail / Settings** (inbox, greetings, notifications, transcription) | 🟡 | Phase 3 | ⚠️ `vmail/read` may exist — unverified | Customer |
| **Music / Messages** (Add Music, Add Introduction, Add Message) | ❌ | Phase 3 | ❌ Unknown | Customer/Staff |
| **Call-Center Queues / Statistics** | 🟡 | Phase 1 | `callqueue/read` ✅ (list; real-time stats unknown) | Customer/Staff |
| **Auto Attendants** | ✅ | Phase 1 | `attendant/read` ✅ (menu detail NOT available) | Customer/Staff |
### 7.3 Design & UX Comparison (from Screenshots)
| Aspect | Current Portal | Reference Portals | Verdict |
|---|---|---|---|
| Theme | Light/neutral (teal, gold, navy) | Viirtue: dark sidebar, light content; Apollo: light all | Current matches owner intent. No dark mode needed. |
| Navigation | Vertical sidebar | Viirtue: sidebar; Apollo: horizontal icon bar | Sidebar is canonical — keep it. |
| Card layout | Stat cards, billing cards | Apollo: two-column card layout on Home | Consistent. |
| Data tables | Call logs, extensions | Both: tables with sort, search, pagination | Consistent. |
| Empty states | ✅ Canonical "No data available." | Viirtue: "Nothing to see here!"; Apollo: "No new messages." | Current canonical state is correct per skill rules. |
| Mobile | ✅ Hamburger menu, viewport meta | Reference portals appear desktop-only in screenshots | Current portal is *more* mobile-ready than references. |
---
## Source of Truth & Data Availability
| Data Category | Current Source | Required Source | Status |
|---|---|---|---|
| Extensions | RingLogix `subscriber/read` | Same | ✅ Wired |
| Domains | RingLogix `domain/read` | Same | ✅ Wired |
| DIDs | RingLogix `phonenumber/read` | Same (filter client-side) | ✅ Wired |
| Call Queues | RingLogix `callqueue/read` | Same | ✅ Wired |
| Auto Attendants | RingLogix `attendant/read` | Same | ✅ Wired |
| Time Frames | RingLogix `timeframe/read` | Same | ❌ Not yet wired |
| Call History (CDRs) | RingLogix | RingLogix / NetSapiens / alternative | ❌ **BLOCKED**`cdr`, `call_detail_record`, `callhistory` all return 404 |
| Call Recordings | Wasabi S3 (RingLogix writes to it) | Wasabi S3 signed URLs | 🟡 Storage confirmed; signed-URL generation TBD |
| Voicemail | Not wired | RingLogix `vmail/read` (unverified) | ❌ Need API verification |
| Device Registration | Not wired | RingLogix `mac/read` (unverified) | ❌ Need API verification |
| Billing / Invoices | Not applicable | RingLogix RingOS (future) or Stripe | ❌ **BLOCKED** — RingOS billing "coming soon" |
| Payment Methods | `sessionStorage` only | Stripe Elements or equivalent | ❌ Need gateway integration |
| Quotes / Orders | Not applicable | Portal DB (new) or Viirtue API | ❌ Need backend DB |
| Notes / Documents | Not applicable | Portal DB + S3/disk | ❌ Need backend storage |
| Products Catalog | Hardcoded in portal JS | Portal DB or RingLogix catalog API | 🟡 Hardcoded works for MVP; need management UI |
| Customer Profiles | `sessionStorage` only | Portal DB | ❌ Need persistent storage |
| SIP Trunks | Not applicable | RingLogix (unverified) | ❌ Unknown endpoint |
| E911 | Not applicable | RingLogix (unverified) | ❌ Unknown endpoint |
| Answer Rules | Not applicable | RingLogix (unverified) | ❌ Unknown endpoint |
| CNAM | Not applicable | Viirtue (unverified) | ❌ Unknown endpoint |
---
## Technical Architecture Gaps
| Aspect | Current | Needed | Gap |
|---|---|---|---|
| **Architecture** | Single-file HTML SPA (no backend) | Backend for portal DB, payment gateway, file storage, API proxying | ❌ Major gap |
| **Data persistence** | `sessionStorage` only (volatile) | Server-side DB for quotes, orders, notes, products, customer profiles, authorized users | ❌ Need database |
| **API key protection** | Unknown — may be client-side | Server-side proxy to protect RingLogix credentials | 🟡 Needs audit |
| **File upload** | Not supported | Document storage (LOAs, agreements, MoH audio) | ❌ Need upload + storage |
| **Payment processing** | Not integrated | Tokenized payment gateway (Stripe Elements) | ❌ Need gateway |
| **Multi-user per domain** | Not supported | Authorized user management per customer account | ❌ Need user management |
| **PDF generation** | Not supported | Invoice PDF download | ❌ Need PDF gen or stored PDFs |
| **File size** | ~1,500 lines (July 2026) | Could grow to 5,000+ with full feature set | 🟡 Monitor; consider module splitting |
| **Build step** | None (single file) | May need build step if file grows too large | 🟡 Monitor |
---
## Implementation Priority Matrix
| Priority | What | Effort | Depends On |
|---|---|---|---|
| **P0 — Immediate (blocks everything)** | | | |
| P0 | CDR data source for Call History | Investigation | RingLogix support / NetSapiens CDR / alternative |
| P0 | Data isolation enforcement for all views | Low | RBAC infrastructure (exists) |
| **P1 — Phase 1: Foundation** | | | |
| P1 | Time Frames wiring (`timeframe/read` → portal) | Low | RingLogix API |
| P1 | Password reset flow | Medium | Email infrastructure |
| P1 | Call History date range filter (calendar picker) | Low | CDR data |
| P1 | Dashboard plan display integration | Low | RingLogix catalog or hardcoded |
| **P2 — Phase 2: Self-Service** | | | |
| P2 | Contact info (address fields, read-only domain ID) | Low | None |
| P2 | Authorized user management (add/remove/RBAC/invitation) | High | Backend DB + email |
| P2 | Marketplace: multi-extension selection + cart | Medium | None (frontend only) |
| P2 | Marketplace: provisioning choice UI | Low | Write API (for immediate; request-discussion needs no API) |
| P2 | Billing: invoice list + viewer (placeholder until API available) | Medium | Backend DB or manual invoice storage |
| P2 | Payment method: Stripe Elements integration | High | Stripe account + backend |
| P2 | Login: rate limiting | Medium | Backend auth |
| P2 | Login: authorized-user email authentication | Medium | Authorized user DB |
| **P3 — Phase 3: Advanced** | | | |
| P3 | Phone-system topology graph | High | All system objects wired |
| P3 | MFA / one-time token (email/SMS) | High | Backend auth + email/SMS infrastructure |
| P3 | Call recording playback (Wasabi S3) | Medium | Signed URL generation |
| P3 | Voicemail settings/inbox | Medium | `vmail/read` API verification |
| P3 | Music on Hold display | Medium | File upload + storage |
| P3 | Order-services contact form | Low | Email infrastructure |
| P3 | Auto-pay toggle | Medium | Payment gateway |
| **P4 — Phase 4: Feature Parity** | | | |
| P4 | Phones/Devices list | Medium | `mac/read` API verification |
| P4 | Contacts (CRUD + import/export) | High | Backend DB |
| P4 | Answering Rules | High | Backend DB or unverified API |
| P4 | E911 inventory | Medium | Unknown API |
| P4 | SIP trunk status | Medium | Unknown API |
| P4 | Quotes + Orders pipeline | High | Backend DB |
| P4 | Staff Reports | High | All data sources |
| P4 | CNAM management | Medium | Unknown API |
| P4 | LNP / Number Orders | High | Backend DB |
| P4 | Account Notes (staff) | Low | Backend DB |
| P4 | Document Storage | Medium | File storage |
| P4 | Notification preferences | Medium | Backend DB + email |
---
*Gap analysis maintained in `/root/projects/voipsimplicity/PORTAL-GAP-ANALYSIS.md`. Companion requirements at [PORTAL-REQUIREMENTS.md](./PORTAL-REQUIREMENTS.md).*
+598
View File
@@ -0,0 +1,598 @@
# 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 100399 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 100399 | 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 100399. 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 (100399) — 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 (100399).
- [ ] 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).*