Commit graph

33 commits

Author SHA1 Message Date
3a408a8dc1 Security hardening + performance fixes across codebase
CRITICAL:
- Membership: remove :role/:org_id/:user_id from mass-assignment cast; use explicit create_changeset/4 and role_update_changeset/2
- GraphQL member resolver: add authorize_invite/3 checking admin/owner role and role hierarchy
- REST invitations controller: add auth check for invite creation

HIGH:
- ApiToken: remove :organization_id/:user_id from cast; use explicit create_changeset/4

MEDIUM:
- Move 8 LiveView Ecto queries into context modules (Admin, Alerts, Coverages, OnCall, Snmp)
- Replace Process.put/Process.get with socket assigns for unresolved_alert_count (user_auth + layouts + 50 templates)
- Add batch get_utilization_for_interfaces/1 to eliminate N+1 capacity queries in device show
- Replace Process.sleep with Process.monitor/assert_receive or Process.send_after in 5 test files

LOW:
- Add handle_params/3 to UserResetPasswordLive, UserRegistrationLive, StatusPageLive
- Remove redundant Repo.preload calls; add preloads to list_site_devices/1
- Fix @impl annotations and credo nesting warnings
2026-06-21 17:40:50 -05:00
c7a236e504 reliability-audit-fixes (#181)
Reviewed-on: graham/towerops-web#181
2026-03-26 14:10:36 -05:00
19abd5508a
ux: improve mobile responsiveness across all pages
- Hide less-critical table columns on small screens (IP, subs, MRR, etc.)
- Add overflow-x-auto wrappers on tables to prevent horizontal scroll
- Fix <.header> component to flex-wrap action buttons on mobile
- Make page action button labels icon-only on small screens
- Add min-w-0 on grid children to prevent viewport overflow
- Right-align device detail dt/dd values consistently
- Fix schedule timeline cards with overflow-x-auto wrappers
2026-03-12 16:49:59 -05:00
1c222f8ff5
feat: add capacity insight worker, UI, and reporting views
Add CapacityInsightWorker (every 15 min) that generates critical/warning
insights when backhaul utilization exceeds 90%/75% and auto-resolves
when it drops below 70%.

Add capacity and utilization columns to the device ports tab with
set/clear capacity controls. Add organization-level /capacity page
with summary cards and per-site capacity table. Add capacity summary
card to site show page. Add Capacity link to nav menu.
2026-03-07 14:42:40 -06:00
7081e5daed
fix: correct subscriber counts by filtering CGNAT IPs and excluding routers
Router devices were inflating per-site subscriber counts because:
1. CGNAT IPs (100.64.0.0/10) in router ARP tables caused false matches
2. Routers see all traffic and shouldn't have subscribers attributed
3. Site totals were computed from raw links without filtering

Changes:
- Filter CGNAT (RFC 6598) IPs from device subscriber links
- Deduplicate accounts across devices by match method priority
- Detect routers via SNMP sys_descr and zero out per-device counts
- Derive site totals from filtered per-device impacts
- Add per-device Subs/MRR columns to site device tables
- Add device link fallback for sites without IP blocks
- Fix Gaiia sync case mismatch and execution order
- Improve device list toolbar button icons and tooltips
2026-02-18 09:15:10 -06:00
6e3db720fd Collapse device page tabs into header row — single line nav 2026-02-16 15:54:42 -06:00
2735c1a032 Add onboarding flow for new organizations 2026-02-16 10:14:45 -06:00
b4c0407ee0 Add granular org roles: executive, technician
New role system:
- owner: full access + financials
- admin: full access + financials (except org deletion)
- executive: read-only + full financial visibility (MRR, revenue)
- technician: field ops (devices, sites, alerts) without financials
- member: legacy alias for technician (migrated)
- viewer: read-only, no financials

Financial data (MRR, revenue, billing) gated behind can_view_financials
assign in all LiveView templates: dashboard, alerts, trace, site show.

Includes migration to rename existing member roles to technician.
2026-02-15 17:40:53 -06:00
d32ba58b75 Hide config backup and config change features from UI
Temporarily hide config change tracking, config timeline links,
and config backup references across dashboard, site show, trace,
and home page. Code preserved with hidden class / HTML comments.
2026-02-15 17:26:10 -06:00
e5796b3464 ui: polish device detail, site detail, and user settings 2026-02-14 21:11:33 -06:00
02474c529f ui: major redesign - NOC dashboard, consolidated nav, dense tables, flat alerts 2026-02-14 20:15:07 -06:00
8752dfec49 fix: netbox url field type, gaiia ipRange→block, remove unknown webhook log 2026-02-14 17:44:01 -06:00
243b773e39 i18n: wrap all user-facing strings in gettext() 2026-02-14 17:44:01 -06:00
146f5745cf
fix: resolve compilation errors, test failures, and credo issues
- Escape HEEx template braces in GraphQL/API docs with raw(~S[...])
- Fix test assertions for updated marketing copy and UI text
- Extract helper functions in GraphQL resolvers to reduce nesting depth
- Create shared ErrorHelpers module for API controllers
- Fix ETS race condition in brute force whitelist cache for async tests
- Fix property test generators to use ASCII instead of printable unicode
- Add alert_severity helper to site_live/show
- Update accounts fixtures for explicit user confirmation
2026-02-14 12:23:10 -06:00
9e7ee5099d refactor: fix all credo strict issues, format all code, fix broken routes
- Fix broken route paths in dashboard (/discovery, /subscribers/trace, /config-changes)
- Fix insights empty state settings link (org-scoped route)
- Add underscores to all 86400 literals across 6 files
- Alphabetize aliases in search.ex and agent_channel.ex
- Extract changelog parser helper to reduce nesting
- Extract dashboard impact calculation to reduce nesting
- Refactor agent_channel config change detection (pattern match, extract function)
- Combine double Enum.reject into single call in trace.ex
- Fix line length in trace.ex search query
- Replace length/1 > 0 with != [] in trace_live
- Run mix format on all files
2026-02-13 19:34:40 -06:00
bc128388ba feat: add loading skeletons and page transitions 2026-02-13 19:18:28 -06:00
eb4556300e fix: safer float formatting in site show template 2026-02-13 18:59:02 -06:00
ba97281beb Rewrite site detail page to use all show.ex helpers
- Add summary stat cards (subscribers, MRR, device count, alerts)
- Add QoE summary with capacity bar (qoe_color, qoe_bg, capacity_bar_color)
- Device health grid with status dots and response times (status_dot_class, format_response_time)
- Active alerts panel with urgency icons (insight_urgency_class, insight_urgency_icon, time_ago)
- Config changes panel with size labels (change_size_label, change_size_color, time_ago)
- Preseem insights panel with urgency styling
- Keep existing latency chart
- Use DaisyUI card/badge components throughout
2026-02-13 18:54:59 -06:00
20f5f48372
feat: command center dashboard with unified insights and contextual enrichment
Transform the dashboard into a single-pane-of-glass command center that
blends operational metrics with business context from Gaiia subscriber data.

- Extend insight schema with multi-source support (snmp, gaiia, system)
- Add Oban workers for automated insight generation (device health, system, gaiia)
- New Dashboard context with health score computation and site summaries
- Rewrite dashboard LiveView with health overview, alert/insight feeds, site grid
- Add source filter pills for insights with URL state management
- Add metrics bar to site detail pages (device count, alerts, subscribers, MRR)
- Add subscriber/MRR context to alert list site links
- Add subscriber badges to device list site headers
- Real-time PubSub updates for alerts on dashboard
2026-02-13 14:52:49 -06:00
8e739283ad refactoring 2026-01-29 10:03:43 -06:00
c54b5d81bb
more dark mode 2026-01-20 17:23:11 -06:00
55fa754a25
add force rediscovery per site 2026-01-18 13:22:17 -06:00
9c2f08317f
feat: remove organization slug from sites and devices URLs
- Created new on_mount hook :load_default_organization that automatically loads user's first organization
- Moved sites and devices routes to root path (/ sites, /devices) instead of /orgs/:org_slug
- Updated all navigation links and route references throughout the app
- Dashboard, alerts, and agents still use org-specific routes (/orgs/:org_slug)
- Users can still switch organizations via org selector for other pages
2026-01-18 13:06:23 -06:00
16bfd7667d
fix: pass timezone attribute to all layout components 2026-01-18 12:49:01 -06:00
35ca827bd0
Add latency graph to site detail page
Shows ping latency for all devices in the site over the last 24 hours.
Each device is displayed as a separate line on the graph with its name
as the label.

Graph only appears if there is latency data available for at least
one device in the site.
2026-01-17 16:58:59 -06:00
a810e75fc4
rename equipment to device 2026-01-17 14:48:46 -06:00
8864b8d26d
Enhance agent assignment UI with clear inheritance indicators
- Add override warnings (amber) when site/equipment explicitly override defaults
- Show inherited agent names in organization and site forms
- Display equipment assignment breakdown in organization settings
- Make equipment boxes fully clickable on site page (remove View button)
- Add hover effects to equipment boxes for better UX
- Consistent icon usage across all assignment levels
2026-01-14 16:20:20 -06:00
806b293ead
Fix impersonation to show correct user data and banner
Two issues were preventing impersonation from working correctly:

1. Templates were not passing current_scope to Layouts.authenticated,
   so the impersonation banner never displayed.

2. fetch_current_scope_for_user was looking up the user from the
   session token, which always pointed to the superuser. This caused
   the superuser to see their own organizations and equipment instead
   of the impersonated user's data.

Changes:
- Pass current_scope={@current_scope} to all Layouts.authenticated calls
- Store target_user_id in session during impersonation
- Fetch target user directly from database using target_user_id
- Update both fetch_current_scope_for_user (for controllers) and
  mount_current_scope (for LiveViews) to properly handle impersonation
- Clean up target_user_id from session when impersonation ends

Now when a superuser impersonates a user, they correctly see:
- The impersonation banner at the top with exit link
- The target user's organizations and equipment
- All data scoped to the impersonated user
2026-01-06 13:22:13 -06:00
52f8af382c
Move delete buttons to edit pages for sites and equipment
- Remove delete buttons from show pages
- Add 'Danger Zone' section to edit pages with delete functionality
- Improves UX by keeping destructive actions on edit pages
- Add clear warnings about deletion consequences
2026-01-04 12:25:31 -06:00
50e7fa13af
Improve onboarding: redirect to site page after creation
- After creating a site, redirect to site detail page instead of list
- Show helpful empty state on site page with instructions to add equipment
- Flash message guides user to add their first device
2026-01-04 12:22:50 -06:00
7d4f7dd7d4
Add active page navigation highlighting
- Add active_page attribute to authenticated layout
- Update nav_link component to show active state with border and text styling
- Update all LiveView templates to pass active_page parameter
- Fix datetime truncation issues in tests and schemas for :utc_datetime fields
- Fix dashboard test assertions for equipment status text
2026-01-03 12:28:26 -06:00
f7b681e8f7
Add authenticated layout to form and show pages
- Add authenticated layout with navigation to equipment/site forms and show pages
- Remove remaining DaisyUI classes from detail pages
- Update buttons to use proper component variants
- Ensure consistent styling across all authenticated pages
2026-01-03 11:06:21 -06:00
1bd72dac78
1. Sites Management
- Sites schema with hierarchical parent-child relationships
  - CRUD operations for sites
  - Sites context with helper functions
  - LiveView pages:
    - /orgs/:slug/sites - List all sites
    - /orgs/:slug/sites/new - Create new site
    - /orgs/:slug/sites/:id - View site details
    - /orgs/:slug/sites/:id/edit - Edit site
  - Support for site locations and descriptions
  - Site tree builder for hierarchy visualization

  2. Equipment Management
  - Equipment schema with monitoring fields
  - IP address validation (IPv4 & IPv6)
  - Equipment status tracking (up/down/unknown)
  - Customizable check intervals per equipment
  - Equipment context with CRUD operations
  - LiveView pages:
    - /orgs/:slug/equipment - List all equipment
    - /orgs/:slug/equipment/new - Add equipment
    - /orgs/:slug/equipment/:id - View equipment details
    - /orgs/:slug/equipment/:id/edit - Edit equipment
  - Equipment can be added from site pages
  - Status badges and last checked timestamps

  3. Database Schema
  - sites table with self-referencing parent_site_id
  - equipment table with status tracking
  - All migrations run successfully
  - Proper indexes on foreign keys and status

  4. Features Implemented
  -  IP address validation using :inet.parse_address
  -  Site hierarchy with parent-child relationships
  -  Equipment linked to sites
  -  Monitoring enabled/disabled per equipment
  -  Customizable check intervals (30s - 3600s)
  -  Status tracking (up/down/unknown)
  -  Timestamps for last check and last status change
  -  Organization-scoped data (users only see their org's data)
2025-12-21 13:39:19 -06:00