Commit graph

37 commits

Author SHA1 Message Date
Graham McInitre
88fae5d752 feat: add beacon monitors with user and admin management
Backend:
- Migration: beacon_monitors table (binary_id PK, org/user FK, check_type, target_url, config, monitoring fields)
- Schema: BeaconMonitor with changeset (pattern-matched port validation, check_type inclusion)
- Query: BeaconMonitorQuery — composable scopes (by org, by user, by type, enabled, ordered, preloaded)
- Context: Towerops.Beacons — CRUD, toggle, record_check_result (36/36 tests pass)

Frontend:
- User LiveView: /beacons — stream-based list, create/edit modals, toggle/delete actions
- Admin LiveView: /admin/beacons — cross-org view with preloads (20/20 tests pass)
- Form component: LiveComponent modal with validation
- Helpers: check_type badges, status indicators, response time formatting
- Router: user routes + admin route configured
- Nav: sidebar + mobile links added
- 30+ gettext translations

Verification: compile ✓, format ✓, credo ✓, 56/56 new tests pass
2026-07-22 08:15:03 -05:00
d85d156bc5 credo fixes 2026-06-15 11:15:46 -05:00
5bb55180a7 Fix all mix credo --strict and compiler warnings 2026-06-13 15:45:09 -05:00
454d9821ae credo fixes 2026-06-13 14:25:19 -05:00
40db913170 feat: end-to-end /coverage compute pipeline + antenna catalog + cnHeat-style form
The compute pipeline now actually runs: per-pixel path loss over LIDAR
terrain, antenna pattern lookup, real GeoTIFF + colored PNG output,
Leaflet imageOverlay rendering with opacity slider and dBm legend.

Propagation:
- Towerops.Coverages.Propagation: Friis FSPL + Bullington single-knife-edge
  diffraction (ITU-R P.526). Pure Elixir, closed-form, no NIF dependency.
  Clean signature so a future ITM/Longley-Rice backend can drop in.
- Towerops.Coverages.Profile: AAIGrid sampler with elevation_at, sample
  along great circle, haversine distance.
- Towerops.Coverages.Raster: Float32 GeoTIFF via gdal_translate (with VRT
  wrapper) and colored PNG via gdaldem color-relief. Outputs to
  priv/static/coverage/<org>/<id>/, served by existing Plug.Static.

Worker:
- Towerops.Workers.CoverageWorker now does the full pipeline: bbox compute
  -> Towerops.Lidar.get_elevation_grid -> per-pixel Task.async_stream
  (parallel = schedulers) running antenna pattern lookup + propagation +
  RSSI threshold check, write rasters. Configurable terrain source via
  :coverage_terrain_module application env so tests can stub. Friendly
  failure messages for :no_tile, :grid_too_large, :nodata,
  :unknown_antenna, :missing_location.

Bundled antenna catalog (~95 entries):
- AntennaCatalog with compact specs for every antenna in the request list:
  Cambium, ALPHA, Antel, ITELITE, KP Performance, L-com, MARS, MikroTik,
  Mimosa, MTI, RADWIN, RF Elements, Ruckus, Tarana, Simulate, Ubiquiti.
- Antenna.from_spec/1 synthesizes 360+360 attenuation patterns from
  gain+beamwidth (cosine-squared main lobe, smooth transition,
  front-to-back floor with mild ripple). Real .ant files in priv/antennas/
  override the catalog by slug. Test fixtures moved to test/support.

Schema (migration add_radio_fields_to_coverages):
- tx_power_dbm replaces eirp_dbm; EIRP is now derived as
  tx_power + antenna.gain - cable_loss in Coverage.eirp_dbm/2 and shown
  live in the form header.
- cable_loss_db, sm_gain_dbi, latitude_override, longitude_override,
  height_above_rooftop_m, tx_clearance_m, foliage_tuning (0-100 slider).
- Coverage.location/1 returns {lat, lon} from override or parent site.

UI:
- form.html.heex: cnHeat-style grouped form (Identity / Location /
  Mounting / RF / Coverage extent), foliage tuning range slider,
  computed EIRP badge in the header.
- show.html.heex: Leaflet map area with L.imageOverlay heatmap,
  opacity slider, dBm color legend, antenna marker with directional
  wedge for azimuth.
- assets/js/app.ts: CoverageMap hook registered.

Tests: 24 new (propagation reference values, profile sampling,
worker end-to-end with stubbed terrain that writes real GeoTIFF + PNG,
org-mismatch job-cancel guard). Full suite: 10815 tests.
2026-05-06 14:32:38 -05:00
5a9381f91a feat: add /coverage RF prediction feature scaffold
End-to-end CRUD scaffold for per-site, per-antenna RF coverage
prediction. Schema, context, antenna registry, Oban worker stub, and
three LiveViews are wired up; the actual ITM + LIDAR + buildings
compute pipeline lands in a follow-up.

- Migration + Coverage schema with full validation (RF params, pixel-
  budget cap, antenna_slug existence). organization_id excluded from
  cast (programmatic-only).
- Coverages context: org-scoped CRUD, validate_site_in_organization
  rejects cross-tenant site_id refs at insert/update, queue_compute
  with PubSub broadcast on per-coverage and per-org topics.
- MSI Planet .ant parser + persistent_term registry loaded at boot
  from priv/antennas/. Two synthetic .ant fixtures (omni + 90deg
  sector) bundled.
- CoverageWorker on new :coverage Oban queue (concurrency 2). Job
  args carry organization_id; worker refuses to run on org mismatch.
  Stub flips status to "failed" with "compute not yet implemented"
  so the UI flow is exercisable.
- LiveViews: index (org-wide, live status updates), form (antenna
  picker grouped by manufacturer), show (status banners, params
  panel, map placeholder). Sidebar nav link added.
- Routes /coverage, /coverage/new, /coverage/:id, /coverage/:id/edit
  under :require_authenticated_user_with_default_org.
- 41 new tests covering schema validation, .ant parsing, context
  CRUD with cross-org guards, Oban job enqueue.
2026-05-06 13:44:14 -05:00
7232ae6306 refactor/dry-improvements (#202)
Reviewed-on: graham/towerops-web#202
2026-03-28 10:56:34 -05:00
0bc6407c3f feature/entity-physical-inventory (#187)
Reviewed-on: graham/towerops-web#187
2026-03-27 10:48:50 -05:00
17fa005781
add maintenance windows REST API and GraphQL support
REST endpoints for CRUD, scoped filtering (active/upcoming/past).
GraphQL queries and mutations for maintenance windows.
Fix agent edit test assertion message.
2026-03-11 14:33:25 -05:00
0cd2ed3567
feat: add on-call schedules and escalation policies
Built-in PagerDuty-equivalent system for on-call scheduling and alert
escalation. Users can now manage schedules, rotation layers, overrides,
and escalation policies directly in the app alongside PagerDuty.

- On-call schedules with rotation layers (daily/weekly/custom), member
  management, and temporary overrides
- Escalation policies with ordered rules, timeout-based escalation,
  and user/schedule targets
- Automatic escalation via Oban worker with configurable repeat count
- Email notifications via Swoosh for on-call alerts
- Resolver computes who's on-call from layer stacking and overrides
- AlertNotificationWorker integration: starts escalation alongside
  PagerDuty, acknowledges/resolves incidents on alert state changes
- Device and organization schemas support escalation_policy_id
- Escalation policy picker on device form
- Schedules nav item with tabbed index (schedules + escalation policies)
- Full CRUD UI for schedules, layers, members, overrides, rules, targets
- 62 LiveView tests, 56 context/schema/resolver/escalation tests
- 26 E2E Playwright tests for smoke and critical path coverage
2026-03-11 12:32:54 -05:00
4e6a038fb5
test: fix all compile warnings in subscriber matching tests
- Prefix unused variables with underscore in subscriber_matching_test.exs
- Fix unused integration_id parameters in gaiia_fixtures.ex
- Remove duplicate site_fixture/1 from access_control_test.exs
- Use public site_fixture/2 from OrganizationsFixtures instead
- Remove unused Sites alias from access_control_test.exs

All 19 subscriber matching tests passing with no warnings.
2026-03-10 13:02:32 -05:00
53f7a31c2d
test: add comprehensive VISP sync tests and Gaiia/SNMP fixtures
- Created comprehensive VISP sync test suite (10 tests, all passing)
  - Tests Decimal-based MRR calculations (float, integer, nil handling)
  - Tests API error handling (401, 403, 500, connection errors)
  - Tests sync status and message updates
  - Validates financial correctness after float→Decimal refactor

- Added GaiiaFixtures module for test support
  - gaiia_integration_fixture/2
  - gaiia_account_fixture/3
  - gaiia_inventory_item_fixture/2
  - gaiia_network_site_fixture/3

- Extended SnmpFixtures with missing helpers
  - arp_entry_fixture/2 for ARP table tests
  - wireless_client_fixture/3 wrapper for positional args

- Extended DevicesFixtures and OrganizationsFixtures
  - device_fixture/3 wrapper (org_id, site_id, attrs)
  - site_fixture/2 for creating test sites

Note: subscriber_matching_test.exs created but has 10 failing tests
(testing private functions, missing Repo.query_count/1). Will address
separately if needed.
2026-03-10 12:36:07 -05:00
6fd03ace16
feat: add comprehensive wireless client tracking and monitoring
Implements real-time wireless client monitoring with historical tracking,
LiveView UI, proactive alerting, and cross-browser e2e tests.

Phase 1: Historical Tracking
- Add TimescaleDB hypertable for wireless_client_readings
- Batch insert client metrics every 60 seconds from DevicePollerWorker
- 90-day retention with compression after 7 days
- Continuous aggregates for hourly (1 year) and daily (5 years) rollups

Phase 2: LiveView UI
- Add wireless tab to device detail page
- Real-time client list with PubSub updates
- Signal strength and SNR badges with 5-level thresholds
- Display MAC, IP, subscriber, TX/RX rates, distance, uptime
- Subscriber matching via device_subscriber_links
- Empty state handling

Phase 3: Proactive Alerting
- WirelessInsightWorker runs every 5 minutes via Oban cron
- 4 insight types with auto-resolution:
  * wireless_signal_weak: < -75 dBm (warning), < -85 dBm (critical)
  * wireless_snr_low: < 15 dB (warning), < 10 dB (critical)
  * wireless_ap_overloaded: > 50 clients (warning), > 75 clients (critical)
  * wireless_client_missing: expected subscribers not connecting
- Hysteresis thresholds prevent alert flapping
- Multi-organization isolation with proper deduplication

Code Quality:
- Refactored reload_current_tab_data to reduce cyclomatic complexity
- Combined double Enum.filter into single pass for efficiency
- Fixed length/1 comparison to use empty list check
- All Credo checks passing

Testing:
- 28 unit tests (ExUnit) - 100% passing
- 15 e2e tests (Playwright) - 100% passing across chromium/firefox/webkit
- Total: 73 tests, all passing

Files changed:
- lib/towerops/workers/wireless_insight_worker.ex (NEW)
- lib/towerops_web/live/device_live/show.ex (wireless tab + refactoring)
- lib/towerops_web/live/device_live/show.html.heex (wireless template)
- lib/towerops/snmp.ex (5 new query functions)
- lib/towerops/gaiia.ex (list_missing_subscribers)
- lib/towerops/preseem/insight.ex (5 new insight types)
- config/runtime.exs (Oban cron schedule)
- test/support/fixtures/snmp_fixtures.ex (NEW)
- test/towerops/workers/wireless_insight_worker_test.exs (NEW)
- test/towerops_web/live/device_live/show_test.exs (9 new tests)
- e2e/tests/wireless-clients.spec.ts (NEW - 15 cross-browser tests)
2026-03-10 09:57:12 -05:00
b3cff9afbb
stripe and email after signup 2026-03-06 10:07:27 -06:00
0ea54b63db
perf(tests): disable TOTP by default in fixtures for faster tests
**Performance improvement: 52s → 33.2s test suite (35% faster)**

Changes:
- Disable TOTP by default in user_fixture (was enabled for all 7400+ tests)
- Enable TOTP only where needed (auth flows, TOTP-specific tests)
- Update ConnCase helpers to enable TOTP (required for authenticated sessions)
- Update test setups that need TOTP for LiveView authentication

Impact:
- Eliminates unnecessary TOTP secret generation + DB writes for most tests
- Reduces Argon2 password hashing overhead across test suite
- 281 tests now properly handle TOTP requirements

Files updated:
- test/support/fixtures/accounts_fixtures.ex: enable_totp default false → true only when needed
- test/support/conn_case.ex: register_and_log_in_user helpers enable TOTP
- test/towerops/accounts_test.exs: TOTP-related describe blocks enable TOTP
- test/towerops_web/user_auth_test.exs: setup enables TOTP
- test/towerops_web/live/admin/*: admin LiveView tests enable TOTP
- test/towerops_web/live/org/preseem_devices_live_test.exs: enable TOTP
2026-03-06 07:21:52 -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
f326eb5dd4 feat: require email verification before first login
- Remove auto-confirmation on registration (register_user and register_user_with_organization)
- Add deliver_user_confirmation_instructions/2 and confirm_user/1 to Accounts context
- Add verify_email_token_query/2 and by_user_and_contexts_query/2 to UserToken
- Make deliver_confirmation_email public in UserNotifier
- Send confirmation email after registration in both flows
- Block unconfirmed users at password login with helpful message
- Add UserConfirmationController with confirm/resend routes
- Add resend confirmation link to login page
- Update test fixtures to confirm users after registration
2026-02-14 11:28:57 -06:00
9f3eb55476
add integrations test fixture 2026-02-12 17:03:00 -06:00
3931a9c14a
more tests and fixes 2026-02-07 11:50:18 -06:00
3eb3d4890e
Merge branch 'feature/job-monitoring-dashboard'
# Conflicts:
#	lib/towerops/workers/device_poller_worker.ex
#	lib/towerops/workers/discovery_worker.ex
2026-02-06 19:01:08 -06:00
35c7328831
feat: add JobMonitoring context with list_active_jobs query
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:15:18 -06:00
ed50257d8a
fix snmp v3 test 2026-02-06 10:21:54 -06:00
8ee39a2d36
Add comprehensive tests for API authentication and authorization
Implemented tests for critical security modules with significant coverage improvements:
- ApiAuth plug: 0% → 100% (12 tests)
- Permissions module: 0% → 85% (32 tests)
- Devices API controller: 0% → 95% (22 tests)

Enhanced test fixtures to support membership roles and device creation with proper organization scoping.
2026-02-05 16:39:01 -06:00
8382b5df6a
make devices site optional and many test fix 2026-02-04 15:05:42 -06:00
1a054fd598
make sites optional 2026-02-04 13:05:32 -06:00
3c00dcf37c remove passkeys for now 2026-01-31 09:50:35 -06:00
c0736d4c2e gdpr consent tracking 2026-01-29 11:12:35 -06:00
d29fb8cfd7 totp fixes 2026-01-28 16:16:59 -06:00
5fb92dd961
add device/org limit 2026-01-27 14:14:25 -06:00
3abd70e133
use password for user regi 2026-01-21 09:13:08 -06:00
a810e75fc4
rename equipment to device 2026-01-17 14:48:46 -06:00
7a33fbff66
Add tests for OrganizationsFixtures
- Test unique organization name generation
- Test valid organization attributes
- Test organization creation with defaults and custom attributes
- Test membership creation for organization owner
2026-01-13 08:59:40 -06:00
2c35ad457c
Add comprehensive tests for AccountsFixtures
- Test all fixture generation functions
- Test user creation (confirmed and unconfirmed)
- Test scope fixtures
- Test password setting
- Test token generation and manipulation
- Test credential fixtures
2026-01-13 08:57:49 -06:00
0689fec38c
Add AgentsFixtures tests
Added 4 tests covering all fixture functions:
- unique_agent_name/0 generation
- agent_token_fixture/2 with default and custom names
- agent_assignment_fixture/2 creation

Coverage increased from 40% to 100%.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-13 08:42:15 -06:00
cf77949527
add remote agent setup 2026-01-09 13:15:31 -06:00
4f924ba9a7
add passkey 2026-01-09 12:26:32 -06:00
c52f313e2d
1. User Authentication
- Full auth system with email/password (using phx.gen.auth)
  - Login, registration, password reset
  - Session management with remember-me functionality
  - Magic link login support

  2. Organization Management
  - Multi-tenant organization system
  - Organizations schema with unique slugs
  - Automatic organization creation when users register
  - Organization switcher UI at /orgs

  3. Membership System
  - Users can belong to multiple organizations
  - 4 permission levels: Owner, Admin, Member, Viewer
  - Complete permission matrix implemented
  - Join/leave organizations

  4. Invitation System
  - Email-based invitations with secure tokens
  - 7-day expiration on invites
  - Track who invited and who accepted

  5. Authorization
  - Full policy system (Organizations.Policy)
  - can?(membership, :action, :resource) helper
  - Enforced via plugs in router

  6. LiveView Pages
  - /orgs - List all your organizations
  - /orgs/new - Create new organization
  - /orgs/:slug - Organization dashboard (placeholder)

  7. Database Schema
  - users table
  - organizations table
  - organization_memberships table
  - organization_invitations table
  - All migrations run successfully
2025-12-21 13:31:59 -06:00