Skip to content

Dev#502

Merged
mayanayza merged 144 commits intomainfrom
dev
Feb 11, 2026
Merged

Dev#502
mayanayza merged 144 commits intomainfrom
dev

Conversation

@mayanayza
Copy link
Collaborator

No description provided.

mayanayza and others added 30 commits February 1, 2026 20:24
… daemons

The /api/daemons/{id}/heartbeat endpoint was removed in the ServerPoll
feature (8f722c8), breaking compatibility with daemons running v0.13.x
or earlier. These older daemons call /heartbeat every 30 seconds and
receive 405 Method Not Allowed from v0.14.0+ servers.

This adds the endpoint back as a deprecated compatibility shim that
processes heartbeats using the same logic as /request-work.
- Add SNMP credential deletion to reset_organization_data() to prevent
  unique constraint violations when repopulating demo data
- Add UniFi Switch 24 PoE host with SNMP service to demo data
- Add bidirectional LLDP neighbor relationships between switch and
  connected devices (pfSense, TrueNAS, Proxmox, UniFi AP)
- Include 24 switch ports with realistic LLDP/CDP data fields
- Add SNMP credential deletion to reset_organization_data() to prevent
  unique constraint violations when repopulating demo data
- Add UniFi Switch 24 PoE host with SNMP service to demo data
- Add bidirectional LLDP neighbor relationships between switch and
  connected devices (pfSense, TrueNAS, Proxmox, UniFi AP)
- Include 24 switch ports with realistic LLDP/CDP data fields
- Add job_ids mapping (discovery_id -> scheduler job_id) to DiscoveryService
- Store job_id when scheduling a discovery job
- Use correct job_id when removing jobs on schedule update or deletion
- Clear stale job_id mappings on scheduler restart

Previously, updating a discovery schedule would fail to remove the old job
because scheduler.remove() was called with discovery.id instead of the
actual job_id returned by scheduler.add(). This caused both old and new
jobs to run simultaneously.
- Add single-interface host fallback for if_entry interface resolution
- When an if_entry has no interface_id but its host has exactly one
  interface, use that interface (unambiguous mapping)
- Revert switch ports 2/3 to interface_id: None since fallback handles it
- Fix LLDP chassis_id and port_id display to extract .value from objects
Exclude /api/auth/* paths from demo mode restrictions so users can
login, logout, and authenticate even when they have an existing
session cookie from a non-owner demo account.
Phase 4 compat tests replay fixture requests that auto-create sessions
in daemon_sessions map. clear_discovery_data() only clears the database,
leaving stale sessions in memory. When Phase 5 creates a new session,
the daemon may pick up old fixture sessions first, causing timeouts.

- Add clear_sessions_for_daemon() to DiscoveryService
- Make cancel_server_discovery_sessions public in compat module
- Call session cleanup before Phase 5 triggers discovery
- Add marketing_opt_in field to RegisterRequest and OidcAuthorizeParams
- Thread marketing_opt_in through auth service to OrgCreated event metadata
- Store/retrieve marketing_opt_in in OIDC session for OAuth registration flow
- Add scanopy_marketing_opt_in property to HubSpot ContactProperties
- Extract marketing_opt_in from event metadata in HubSpot service
- Update frontend to send marketing_opt_in with registration requests
- Disable HubSpot automatic form collection to prevent login form scraping
CDN requests can intermittently fail in CI. Use backon for exponential
backoff retries (3 attempts) and futures::stream for parallel requests
(up to 10 concurrent) to improve test reliability.
- Add supports_full_server_poll() method to check daemon version
- Skip polling for legacy daemons (they don't have /api/status, /api/poll, etc.)
- Make API key optional in post_to_daemon and discovery request methods
- Allow subscriber to send discovery commands without auth for legacy daemons
- Add info-level logging for HubSpot org sync on startup

Legacy daemons stay alive via their own heartbeat calls and can still
receive discovery initiate/cancel commands without authentication.
Bumps the cargo group with 1 update in the /backend directory: [bytes](https://github.com/tokio-rs/bytes).


Updates `bytes` from 1.11.0 to 1.11.1
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](tokio-rs/bytes@v1.11.0...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <[email protected]>
Add event queue to buffer analytics events that fire before PostHog
finishes loading. Events are flushed when PostHog's loaded callback
fires, preventing billing_completed and other early events from being
silently dropped.
- Remove ip label from http_requests_total (was creating unique series per visitor)
- Add path normalization to reduce unbounded static asset paths:
  - SvelteKit immutable assets (/_app/immutable/*) -> "static_immutable"
  - Files with known extensions (.js, .css, .png, etc.) -> "static_file"
  - API and page routes pass through unchanged
- Add unit tests for path normalization logic

This reduces metric series from ~47.8k to a few hundred, fitting within
Grafana Cloud free tier limit of 10k series.
Change default daemon mode from ServerPoll to DaemonPoll to restore
self-registration behavior. In v0.14.0, the default was changed to
ServerPoll which skips registration, but integrated daemons need to
self-register after being initialized by the server.

- backend/src/daemon/shared/config.rs: Change default mode to DaemonPoll
- docker-compose.yml: Change default SCANOPY_MODE to daemon_poll
Previously the GDPR cookie consent banner only appeared when PostHog
was configured. This meant HubSpot tracking could never be enabled on
deployments without PostHog, since users had no way to grant marketing
consent.

Now the banner shows if either PostHog or HubSpot is configured.
mayanayza and others added 27 commits February 9, 2026 15:48
…ttributes

The PaymentMethod.customer field is null after detachment, so the handler
silently skipped. Now parses the previous customer ID from the raw event
payload's data.previous_attributes.
…ytics

- Add invoice.payment_failed, invoice.payment_action_required, and
  invoice.paid webhook handlers with telemetry events for CRM tracking
- Fix past-due UX: treat past_due as active (user keeps access while
  Stripe retries), auto-open non-dismissible settings modal to billing
  tab with prominent "Manage Subscription" button
- Fix subscription.paused webhook bug: inner match now handles both
  CustomerSubscriptionPaused and CustomerSubscriptionDeleted event objects
- Fix billing middleware: allow past_due through (was returning 402)
- Fix webhook rate limiting: correct exempt path for /api/billing/webhooks
  (trailing slash mismatch caused 429s during event bursts)
- Add PaymentFailed/PaymentActionRequired/PaymentRecovered telemetry
  operations with Brevo CRM handlers
- Move "Manage Subscription" into plan card for all states
- Add PostHog analytics events and billing plan UI refinements
Currently translated at 17.3% (165 of 952 strings)

Translation: Scanopy/scanopy
Translate-URL: https://hosted.weblate.org/projects/scanopy/scanopy/fr/
Currently translated at 20.1% (192 of 952 strings)

Translation: Scanopy/scanopy
Translate-URL: https://hosted.weblate.org/projects/scanopy/scanopy/fr/
Currently translated at 20.3% (194 of 952 strings)

Translation: Scanopy/scanopy
Translate-URL: https://hosted.weblate.org/projects/scanopy/scanopy/fr/
…5e7861b48

chore(deps): bump the cargo group across 1 directory with 2 updates
Translations update from Hosted Weblate
- Split RegisterModal into email-first (3a) and password (3b) sub-steps
- Add POST /api/auth/check-email endpoint for email availability check
- Auto-link OIDC identity when email matches existing account instead of
  erroring, redirect existing users to app root instead of onboarding
- Show inline error with "Sign in instead" link for duplicate emails
- Fix OIDC error propagation: use error_code query param, read on mount
- Fix small-screen modal layout with responsive padding and max-height
- Bump anonymous rate limit from 20/min to 40/min (burst 5 -> 10)
- Track onboarding_use_case_selected event in self-hosted flow
- Clean up 17 unused i18n keys
- Remove trackEventOnce/hasCompletedOnboarding from frontend analytics
- Remove first_daemon_registered, first_topology_rebuild, first_api_key_created
  tracking calls from query hooks
- Add posthog-rs dependency and create PosthogService with EventSubscriber
  that captures entity CRUD, login, billing, and discovery events server-side
- Register PosthogService in ServiceFactory when posthog_key is configured
- Add Brevo list management (add/remove contacts to lists) to client
- Set email_blacklisted=false for all app signups, use list membership
  for Product Updates (all users) and Marketing (opt-in only)
- Track SCANOPY_MARKETING_OPT_IN and SCANOPY_MARKETING_OPT_IN_DATE
- Default marketing checkbox to unchecked (GDPR compliance)
- Update marketing label to clarify scope (partnerships, press, news)
Daemon containers (daemon_poll and server_poll) share a volume mount and
both wrote to server_to_daemon.json, causing the last writer to overwrite
the other's exchanges. Use SCANOPY_MODE env var to write mode-specific
files (server_to_daemon_poll.json, server_to_server_poll.json), then
merge them during Phase 10 fixture generation.
- generate_networks: assign Default SNMPv2c to HQ and Denver,
  Network Devices to Riverside Medical, None to Cloud
- create_host: accept optional snmp_credential_id parameter
- generate_hosts_and_services: override credential on pfsense-fw01,
  unifi-usw-24, and denver-fw with Network Devices credential
- Reorder demo data insertion: SNMP credentials before networks
  to satisfy FK constraint
@mayanayza mayanayza merged commit 439528d into main Feb 11, 2026
4 of 5 checks passed
mayanayza added a commit that referenced this pull request Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants