Commit Graph

2474 Commits

Author SHA1 Message Date
Adrian Gruntkowski 307d6b004b
Implement plug for checking SSO team access (#5522)
* Implement plug for checking SSO team access

* Add the new plug to the `browser` pipeline and adjust routes

* Don't log in on failed provisioning and display issue notice instead

* Require user to be provisioned as SSO before toggling "Force SSO"

* Label SSO members explicitly in team management LV

* Make slight layout and copy adjustments in provision issue view

* Improve copy (h/t @aerosol)
2025-06-24 08:25:24 +00:00
Adam Rutkowski 3c032f84c3
Minor improvements to Team management UI (#5523)
* Team members setup: indicate disabled with color

* Bugfix: grey-out guest role picker if insufficient permissions.

This wasn't any critical though, the UI would act janky but
permissions were enforced anyway on change.
2025-06-24 08:18:20 +00:00
Adam Rutkowski e56baeb272
Persist login type preference (SSO/standard) (#5520)
* First pass: store login preference

* Only set login preference if SSO is used

* Change mock DNS to use port 5354 and `domain_id` for parameter

* Make login forms use flash message for error passing

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2025-06-23 10:28:27 +00:00
Adrian Gruntkowski a2ed1e04b1
Revise system behaviour for SSO users (#5506)
* Setup MFA properly in SSO tests

* Move `new_identity` test helper to common helpers

* Make standard login only allow Owner SSO users

* Implement `Plausible.Users.type/1` for determining user type

* Implement plug restricting action based on user type

* Restrict or adjust access to settings actions to SSO users

* Make a very small refactor to `Auth.SSO` helper

* Prevent SSO users from acceptig team invitations

* Prevent SSO users from adding websites under "My Presonal Sites"

* Prevent implicit team creation by SSO users

* Add workaround for compiler warning under CE

* Remove SSO user on removing membership

* Prevent changing role to owner when 2FA not enabled

* Prevent provisioning from standard user with active personal team

* Fix `Auth.lookup/1` to not break for standard users on multiple teams

* Use `Plausible.always/1` (h/t @aerosol)

* Revert "Use `Plausible.always/1` (h/t @aerosol)"

This reverts commit 0ee7dd84d3.

* Rename `RestrictType` -> `RestrictUserType`

* Make the configuration intent more explicit in `RestrictUserType` plug

* Rename plug file
2025-06-23 08:19:12 +00:00
Karl-Aksel Puulmann 6ade93bf86
ScriptV2: Self hosted tracker script cache (#5502)
* Allow caching tracker script on CE

Open questions with this approach:
- `ingestion_url`: Using `PlausibleWeb.Endpoint.url()` requires that endpoint has started, but we
  want to pre-warm the cache _before_ the endpoint starts. To work around this, a different approach
  is used to get the right url.
- caching: Other caches currently cache database models, this caches a string. Will this cause issues?

* Slightly better workaround

* Lazier timers
2025-06-20 06:59:18 +00:00
Adam Rutkowski 4387d42409
CRM: First pass SSO support (#5517)
* CRM: First pass SSO support

* Put `sso_integration` association behind `ee` check
2025-06-19 11:52:15 +00:00
Uku Taht 973b626625
Onboarding review flow (#5491)
* Scriptv2 onboarding: review flow

* Make sure bundled features are enabled by default in v2 onboarding

* Call get_or_create correctly

* Refactor custom plan form to use boolean-based checkboxes
2025-06-19 11:34:41 +00:00
Adam Rutkowski 70902bbc5a
SSO: phrasing; settle on domain verification, not validation (#5508)
* SSO domains: s/validation/verification

* Fix careless search&replaces
2025-06-16 18:44:57 +00:00
Adam Rutkowski 1c182d6980
Set a long salts refresh interval on Mix.env == :test (#5510) 2025-06-16 14:50:01 +00:00
Adam Rutkowski b86e4eea7e
SSO: implement domain validation background service (#5505)
* SSO: implement domain validation background service

* Put tests behind `ee`

* Fix up typespecs
2025-06-16 11:56:59 +00:00
Karl-Aksel Puulmann c7779e2f33
ScriptV2: Support `meta` only in legacy scripts (#5492)
* Revert "Log warning when m/meta parameter used in ingestion (#5478)"

This reverts commit d4bec6d9e3.

* Support `meta` argument only on legacy scripts + test

* Changelog

* Bump version
2025-06-16 12:25:00 +03:00
Adam Rutkowski dad00d26c2
Periodically refresh salts so that non-rotating nodes catch up (#5496)
* Periodically refresh salts so that non-rotating nodes catch up

* Remove Logger ref 0a2ed563dd & facf743670

* typo
2025-06-16 05:23:46 +00:00
Karl-Aksel Puulmann d215e50982
ScriptV2: Rework WordPress plugin token adding flow (#5493)
* Remove dead code

* Rework plugin API token flow

* Changelog

* Redundant code

* Remove onfocus
2025-06-12 08:18:58 +00:00
RobertJoonas d00dde183e
Starter Tier: Getting ready for release (#5489)
* make starter tier flag team based not user

* old upgrade page for active or recently ended trials

* adjustments to plan benefits

* mention losing grandfathering when on v4

* extract plan benefits into separate module

* unit tests for plan benefits + fix enterprise site/team_member benefits

* hide Starter tier from grandfathered Growth

Also get rid of the grandfathered notice in Growth plan box

* choose_plan_test.exs to ee_only

* fix ci

* actually fix ci

* stop displaying new starter features for grandfathered teams

* bump starter tier launch date

* Revert "stop displaying new starter features for grandfathered teams"

This reverts commit e024a82d14.
2025-06-11 12:48:22 +00:00
Adrian Gruntkowski 153702c20f
Implement SSO setup UI (#5473)
* Extend core APIs for better insight into SSO state during setup

* Adjust `toggle_switch` compoenent to accept global attributes

* Improve textarea variant of input component

* Make first very crude pass on SSO setup UI

* Display "Single Sign-On" settings option only when enabled

* Extract SP identity ID function to SAMLConfig as a public one

* Move SAML controller logic behind an adapter

* Don't apply CSRF protection to SAML consume endpoint

* Make copy adjustments

* Change SSO sidebar icon

* Fix `fake_domain_verify` handling before integration is set up

* Tweak configuration markup

* Sanitize PEM input

* Tweak SSO settings sections + prevent domain deletion if applicable

* Minor tweaks to SSO settings tiles

* Bootstrap basic test suite

* Ensure SSO settings are guarded by env var

* Make sure to retry fake domain validation on integration-less cycle

* Trim idp entity id input

* Dedup assertions

* Fix domain identifier interpolation

* Tidy up integration fetching

* Expand tests for SSOManagement LV with fixes

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-06-11 10:52:20 +00:00
Karl-Aksel Puulmann d4bec6d9e3
Log warning when m/meta parameter used in ingestion (#5478)
* Log warning when m/meta parameter used in ingestion

This parameter was added in October 2020 and then renamed 2 days later: 40900c7653 and 0b6e645b44

We are hoping we may be able to remove it which this logging will help with.

* Log only domain
2025-06-10 08:01:25 +00:00
RobertJoonas 4e5093f86c
Starter Tier: Shared Link Feature Gates (#5474)
* feature gate creating shared links

* feature gate GET shared_link

* stop granting shared links access in code + organize tests

* allow GET shared_link for WP

* prevent shared link creation with special name

unless created by the Plugins API, the name WordPress - Shared Dashboard
will be considered reserved.

* do not render special shared links in site settings > visibility

* remove hardcoded special name from test

* add function doc for special names

* prevent updates to special name as well

* warn about losing access to shared links

* make features_usage return empty list on ce

* Update lib/plausible/sites.ex

Co-authored-by: hq1 <hq@mtod.org>

* move special name check to changeset

* fix tests

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-06-10 06:43:40 +00:00
hq1 efc55e323d
Remove kaffy (#5423)
* Deal with `FeatruesList` proxy

* Remove kaffy: first pass

* Remove admin controller

* Remove kaffy: last batch

* unlock dependency

* Remove kaffy links

* !fixup
2025-06-10 06:24:47 +00:00
hq1 bdc44d1d33
CRM: Refund lock (#5480)
* Redefine what `on_trial?` means

No subscription combined with
non-zero trial_days_left designates an ongoing trial.
Conversely, any subscription in any state means
the trial is inactive.

* Fix cancellation notices

We now show the cancellation warning
when the subscription is about to expire.

* Implement the ability to lock cancelled subscriptions

in case a refund is made

* Dedup notice body

* Spawn confirmation alert before locking
2025-06-09 13:53:40 +00:00
Karl-Aksel Puulmann 84d8e60e92
Drop installation_meta mentions from schema (#5479)
Nothing is reading or writing this anymore. We can this way (hopefully) eventually drop the column as well.
2025-06-09 09:39:39 +00:00
hq1 df8727f414
CRM: revert #5440; implement lock/unlock for grace period (#5475)
* Revert "CRM: team (un)lock regardless of grace period (#5440)"

This reverts commit bb63c0d0e4.

* Implement grace period (un)lock just like in kaffy

* Test grace period handling
2025-06-06 08:01:29 +00:00
ruslandoga 0a2ed563dd
more salts logging (#5471)
* more salts logging

* even more logs

* wording
2025-06-04 11:13:29 +00:00
Marko Saric f36c0ee642
Slight change to the plugin token copy (#5468)
* Update token_form.ex

* Update token_form.ex

* Format

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-06-04 09:29:42 +00:00
Adrian Gruntkowski 0968ed7f2c
Implement `SSO.Domains.remove/1,2` and `SSO.Domains.check_can_remove/1` (#5461)
* Implement `SSO.Domains.remove/1,2` and `SSO.Domains.check_can_remove/1`

* Add `sso_domain` relation to `Auth.User` schema

* Populate `user.sso_domain` on provisioning and validate identity domain

* Simplify lookup by domain in `SSO.Domains.remove/1,2`

* Extend tests

* Derive user name from email in fake SAML controller

* Fix formatting
2025-06-04 08:56:50 +00:00
RobertJoonas 38f1de6ecd
Starter Tier: Teams UI follow-ups (#5456)
* keep teams feature explicitly for UI

* keep devsubscriptions in sync with prod

On prod, when a subscription is created without a current team in assings,
a new team is force created for that user.

* disable team creation when no point to create it

* fix ce_test compile warning

* fix tests on CE

* Update lib/plausible/teams/billing.ex

Co-authored-by: hq1 <hq@mtod.org>

* add solo team in seeds

* fix top border blur + stop autofocusing input when blurred

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-06-03 10:14:50 +00:00
Karl-Aksel Puulmann 692fd30a3e
Add telemetry to tracker script generation (#5437)
This will be used to measure rollout success and load after purges
2025-06-03 07:11:47 +00:00
Adrian Gruntkowski 4a587e2a6e
Implement remaining `SSO` functions needed for setup (#5444)
* Move data mgmt logic from `UserAuth` to `Auth.UserSessions`

* Implement remaining SSO code API needed for setup

* Change `deprovision_user` -> `deprovision_user!`

* Change `UserSessions.create` -> `UserSessions.create!`

* Change `any_verified_domain?` -> `no_verified_domains?` (h/t @aerosol)
2025-06-03 06:21:51 +00:00
hq1 f86ef2a4c1
Add phx-submit to filter bars (#5455) 2025-06-02 13:20:31 +00:00
Adrian Gruntkowski bca78169bb
Implement SSO login against fake SAML endpoints (#5434)
* Add SSO user as a team member on provisioning

* Implement fake SSO actions and basic login form

* Handle team member limit error and adjust login redirect in `UserAuth`

* Always switch to related SSO team on SSO user login

* Ensure `timeout_at` is set when creating new standard user session

* Add env var flag for gating SSO

* Hide SSO login link when SSO disabled

* Hide SSO routes when SSO disabled

* Implement nonce-based allowance for js in SSO content security policy

* Test controller actions

* Add more tests for UserAuth

* Add sync tests for `GateSSO` plug and env var flag in disabled state

* Add test for SSO owner logging in via standard login
2025-06-02 12:13:56 +00:00
Marko Saric bd2e32586e
Small changes to the teams copy (#5450)
* Update _header.html.heex

* Update notice.ex
2025-06-02 12:07:37 +00:00
Artur Pata 027952e339
Does not include tracking script on /cs module (#5452) 2025-06-02 11:44:42 +00:00
Adrian Gruntkowski 9ec7864f44
Ensure team locked state is updated on site creation and removal (#5451)
* Ensure team locked state is updated on site creation and removal

* Do not lock team when there are no sites

* Ensure SiteLocker is only run on EE

* Get rid of troublesome alias
2025-06-02 10:45:20 +00:00
Uku Taht 9a7cb6cc26
Update tracker config in scriptv2 onboarding (#5443)
* Update tracker config in scriptv2 onboarding

* Use actual scriptv2 installation script

* Unwrap result from transaction

* Only run cache purge tests on ee
2025-06-02 10:39:31 +00:00
RobertJoonas adfcd0f584
for now allow teams and shared links for everyone (#5446) 2025-05-30 16:45:57 +00:00
RobertJoonas e38bda6d00
Starter feature gates (UI) (#5426)
* replace yellow warning notice with more inviting cta (funnels)

* align VAT notice with /year on the upgrade page

* improve tooltip component

do not hide the tooltip when the mouse enters the tooltip itself directly
from the trigger element. This allows clicking links in tooltips.

* improve site segments feature gate UI

Disable the save button when site segment option is selected in create or
edit form. Also render a different upgrade notice if the user is not the owner.

* replace upgrade notices with blur UI

To fully get rid of Notice.premium_feature, we will also display a
"not allowed" cursor with tooltips asking to upgrade where necessary.

* extract toggle switch component

* Hide currency toggle from goal edit form

The currency field cannot be changed for an existing goal anyway. Therefore
it makes sense not to show it at all. This commit makes the currency picker
always visible when editing a revenue goal, and always hidden for custom
event edit form.

* simplify api key creation form

Turn "Sites API access" into a toggle switch identical to "Enable revenue
tracking" in goal creation form.

* remove team setup CTAs for Starter tier

* fix team member limit for starter

* adjust v5 plan limits and limit exceeded notices

* do not display global notices on upgrade-success page

* fix settings/subscription monthly quota boxes alignment

* fix CI

* use tailwind backdrop-blur

* remove dangling log + avoid passing setSaveDisabled

* remove duplicate function clauses revenue goals

* revert create api key UI change but disable button still

* optimize for darkmode

* blur team settings > team members for Starter

* rename team accounts to team management
2025-05-30 13:34:19 +00:00
Marko Saric 0a3e7dab5e
Update team_setup.ex (#5445) 2025-05-29 15:44:33 +00:00
hq1 bb63c0d0e4
CRM: team (un)lock regardless of grace period (#5440)
* Add `locked_by_admin` to teams schema

* Implement team locking

* Look up `teams.locked_by_admin` in relevant background services

* Add background servive tests

* Type faster than think!
2025-05-28 11:28:59 +00:00
ruslandoga facf743670
log salt hashes with warnings (#5441) 2025-05-28 11:19:10 +00:00
Karl-Aksel Puulmann 6a06020ba7
ScriptV2: BunnyCDN cache purging (#5435)
* Purge bunny cdn cache when tracker script config is updated

* Only allow one purge task scheduled per site

Tested by adding logging and toggling a checkbox a few times. Only one job got executed.

* Typo
2025-05-28 10:08:33 +00:00
Adrian Gruntkowski b341f2735a
Always expire SSO User sessions after `identity.expires_at` (#5429)
* Always expire SSO User sessions after `identity.expires_at`

* Refactor

Co-authored-by: hq1 <hq@mtod.org>

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-05-28 06:59:39 +00:00
Karl-Aksel Puulmann 98cdeb23dd
ScriptV2: Configuration renames, iteration (#5427)
* plausible-main -> plausible-web

* Change elixir workflow

* Update tracker option names in tracker.ex

* config.hash -> config.hashBasedRouting

* Enable revenue by default for plausible-web

* Enable taggedEvents by default

* config.local -> config.captureOnLocalhost

* manual -> autoCapturePageviews

* Update playwright tests

* Support adding/editing file types for download in plausible-web

Original docs: https://plausible.io/docs/file-downloads-tracking#what-if-i-want-to-track-a-different-file-type

* rebase: initialize-page-dynamically update

* chore: Bump tracker_script_version to 12

* Ignore pageviews in file-downloads.spec

* Phrasing in tests

* Remove unneeded conditional
2025-05-27 11:28:17 +00:00
Uku Taht 5f33f836fb
Add tabs for installation types (#5425) 2025-05-27 10:33:21 +00:00
Adrian Gruntkowski 4ffdfe3f69
Implement `SSO.provision_user/1` and extend `UserAuth.log_in_user/3` (#5424)
* Add `SSO.Identity` struct

* Ensure timestamps are set to second resolution to avoid issues

* Implement `SSO.provision_user/1`

* Implement `UserAuth.log_in_user/3` clause accepting identity

* Fix type declaration in `UserAuth`
2025-05-27 07:55:23 +00:00
Karl-Aksel Puulmann b5bd623cf1
tracker_script_configuration: plugins API (step 5) (#5410)
* Plugins API for tracker script configuration

* no support for track_404_pages in plugins api

* Update lib/plausible_web/plugins/api/controllers/tracker_script_configuration.ex

Co-authored-by: Uku Taht <Uku.taht@gmail.com>

* Restructure update code

* Remove dead code

---------

Co-authored-by: Uku Taht <Uku.taht@gmail.com>
2025-05-27 06:05:27 +00:00
Karl-Aksel Puulmann 8bbb4408da
tracker_script_configuration: drop writes and reads to `installation_meta` (step 4) (#5409)
* Read and write only new schema

* add cdn_tag header

* Remove default thats not needed
2025-05-27 05:36:36 +00:00
Karl-Aksel Puulmann 93dfb21669
tracker_script_configuration: backfill (step 3) (#5408)
* tracker_script_configuration table migration

* tracker_script_configuration schema + upsert tests

* TrackerScriptConfiguration: read from installation_meta, double-write, refactor installation flow to work off of new model

* Fix a test

* Backfill tracker script configuration
2025-05-26 12:31:22 +00:00
Karl-Aksel Puulmann b972817782
tracker_script_configuration: schema, double-writes (step 2) (#5407)
* tracker_script_configuration table migration

* tracker_script_configuration schema + upsert tests

* TrackerScriptConfiguration: read from installation_meta, double-write, refactor installation flow to work off of new model

* Fix a test
2025-05-26 11:50:22 +00:00
hq1 27933d0045
CRM: Expose site transfer (#5418)
* Expose rescue zone/site transfer in CS

* Add notes

* Clean up
2025-05-22 07:47:22 +00:00
Adrian Gruntkowski 9de15326dc
Introduce migration and schemas for SSO (#5411)
* Add polymorphic_embed library

* Add formatter rules for polymorphic_embed

* Add new and extend existing schemas for SSO
2025-05-21 09:53:12 +00:00
Marko Saric fcb704fa24
Adjust note about no invoices (#5412)
* Note about no invoices

* Adjust tests

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2025-05-21 09:20:09 +00:00
ruslandoga 811a0f049a
Log salts hash (#5401)
* log salts hash

* cleanup
2025-05-21 07:19:23 +00:00
RobertJoonas 2dd144bf85
Starter tier: Upgrade page remodelling (#5394)
* add a new (feature flagged) upgrade page offering v5 plans

* include starter tier plans in available_plans_for + use dev prices in test

* upgrade page remodelling with starter tier

* mobile optimizations

* optimize for darkmode

* add embedded dashboards as a growth benefit

* do not hide header on LegacyChoosePlan

* consistent v5 plan feature order

* slight grandfathering notice adjustment

* display monthly price too on yearly plans

* default to v5 plans unlesss legacy? is true

* refactor: suggest volume not plan for emails

* align back link with page title

* render grandfathering notice for growth v4 too
2025-05-20 13:22:12 +00:00
Karl-Aksel Puulmann 844c118135
ScriptV2: `plausible.init`, `customProperties`, snippet compilation, double initialization protection, `swc` (#5391)
* WIP: init() for plausible.js

* Reformat whitespace

* Handle double-initialization gracefully

* Script customProperties option

* Remove pageview-props from tracker script interpolation - its now an advanced config

* Add compile option for compiling the web snippet. This can then be copied to e.g. onboarding

* Switch minification from uglify-js to swc

* Use 4 passes for optimal output

* Remove use strict to remove it from output. Uglifyjs already removed this

* Minor optimization: Remove nulls from output via runningEngagementStart

* Minor optimization: Reduce onIgnoredEvent

* config_json -> config_js

* Dead attribute

* Remove guard for engagements

* More protective customProperties

* Object.assign

* chore: Bump tracker_script_version to 10

* No need for default in Object.assign

* Remove dead guard
2025-05-20 06:57:35 +00:00
Uku Taht 680eaa563a
Initial UI mock for scriptv2 onboarding (#5383)
* Add flag for scriptv2 onboarding, render different installation screen

* Manual installation screen mockup

* Use phoenix form helpers

* Format

* Move manual tagging to advanced options
2025-05-19 13:21:50 +00:00
Adrian Gruntkowski 6987ea8048
Replace uses of `Teams.owned_sites/1` with better functions where applicable (#5397)
* Slightly refactor `Teams.owned_sites/1`

* Don't use `Teams.owned_sites/1` when there are better functions

* Refactor `Teams.owned_sites/2` and add typespecs
2025-05-19 08:32:09 +00:00
hq1 62da8f115f
CS: display only team's sites + rejecting traffic info if applicable (#5400)
* CS: list only team's sites at all times

Previously, when team was not set up, we'd include
all the guest sites in the list

* Add rejecting traffic info
2025-05-19 07:29:18 +00:00
Karl-Aksel Puulmann f8658320d5
ScriptV2: plausible-main application code (#5389)
* PlausibleWeb.Tracker -> PlausibleWeb.TrackerPlug

* Support getting plausible-main.js via app from `/js/s-${tag}`

tag currently is site.installation_meta["id"] but im planning (separately) to
introduce a different, shorter id version (using something like NanoId/HashId).

This will be introduced in a separate PR though

* Mark some variables as legacy

* Remove compile-time dependency on plausible-main.js

* Fix build

* moduledoc

* Bump CACHE_VERSION to ensure plausible-main is compiled

* 404 consistently

* Revert "Remove compile-time dependency on plausible-main.js"

This reverts commit 4b533ef0f6.

* Ensure file exists at compile-time

* flat_map over reject

* assert -> refute

* JSON.encode!
2025-05-19 06:02:26 +00:00
Adrian Gruntkowski 34c201dc61
Automatically select and deselect dependent API features in CS (#5396) 2025-05-15 11:25:23 +00:00
RobertJoonas 18907aef63
Starter Tier: Add plans and Mix tasks (#5392)
* fix sandbox plans v4 to be in sync with prod ones

* sync sandbox plans + unify formatting

* create v5 plans in paddle prod + sandbox + Mix.tasks

* add teams and shared links features

* remove unused line of code

* paddle credentials as module attrs

* remove teams and shared links as growth benefits for time being
2025-05-15 10:02:43 +00:00
hq1 c009b92fca
Customer support (#5390)
* Add profile_url helper clause

* Add notes

* Sort features alphabetically

* Fix checkbox/textarea components

* Unrlelated: update combobox docs

* Initial customer support UI

* Unrelated: don't expand member dropdown if disabled

* Cross link both CRMs

* Remove unused things

* Stop polluting history with tab navigation

* Truncate search results

* Format

* Use routes in favour of phx-click events

* Fix / keypress to search focus

* Rename phx event

* Rename remaining save events

* Fix up x-data

* Fix alpine placeholder event

* Enable progress animation with topbar

* Team: separate assign clauses per tab

* Site: separate assign clauses per tab

* lint

* Replace URI patch on filter text update

* Unifyu filter_bar component usage

* !fixup

* Fix up filter form event name

* Fix number formatting as you type

* Fix enterprise plan number inputs

* Link CS from HelpScout

* Remove target=_blank from kaffy URLs

* Pre-fill custom plans

* Rework the billing tab

* Make checkbox labels clickable

* Put Stats API first

* Format

* Credo

* !fixup

* Don't show empty labels
2025-05-15 08:05:32 +00:00
Artur Pata 429b055920
Update headlessui to v1.7.19, refactor site switcher (#5255)
* Migrate some

* Making progress

* All fixed

* Convert interval picker to tsx

* Fix format

* Fix tests

* Make sure focus outline looks right on DropdownTabButton

* Refactor Site Switcher to Popover

* Fix site switcher test

* Better jsdom mocks in assets tests

* Try svg placeholder favicon

* Update favicon test

* Try giving transition config directly

* Remove empty props

* Remove unnecessary closeDropdown to prevent Firefox transition issue

* Register open dropmenus globally

This is needed to prevent invalid state when navigating with site hotkeys with Firefox while a dropdown is open and coming back using browser

* Colocate popover-specific component

* Clarify behaviour on hitting hotkey for current site

* Try fix Firefox issue

* Try 1.7.19

* Commit to @headlessui/react v1.7.x

* Fix last two transition origins

* Align active tab on baseline

* Remove unneeded global dropmenu state

* Add changelog

* Funnels menu is searchable and scrollable

* Fix transform origin

* Stop funnels menu from holding onto search state

* Mandate ref be passed to SearchInput from the outside
2025-05-07 05:22:53 +00:00
hq1 aa4a8339cb
Ingest throughput fixes (#5378)
* Update

* Update

* Naive safety valve in front of RL

* Revert "Naive safety valve in front of RL"

This reverts commit 3bb553ec2e.

* rate limit with atomics

* update test

* Reapply "Add +Mdai max emulator flag (#5373)" (#5374)

This reverts commit b28ca2ffee.

* Update load script

* Update LOADTEST mode

* Revert "Stop aggregating buffered ingest counters (#5372)"

This reverts commit 2c41dcd4c1.

* update

* Fix cache hit/miss metric tags

---------

Co-authored-by: ruslandoga <ruslandoga+gh@icloud.com>
2025-05-05 14:00:37 +00:00
RobertJoonas 1de37a125c
Staging subscriptions (#5349)
* sandbox_plans.json -> sandbox_plans_v4.json

* add mix task and generate sandbox plans

* manually add sandbox_legacy_plans.json

* make all staging plans consistent with prod

* slight code style improvement

* add kb link
2025-05-05 09:23:19 +00:00
Adrian Gruntkowski b942081f30
Add ability to create Sites API keys from Account Settings (#5361)
* Extend API key creation with support for Sites API keys

* Remove unnecessary disabled state and improve radio component styling

* Add more tests

* Don't expose Sites API keys in CE

* Only show the notice if Sites API feature is actually disabled

* Adjust API keys subtitle

* Fix condition in one of actions
2025-05-05 09:01:14 +00:00
hq1 2c41dcd4c1
Stop aggregating buffered ingest counters (#5372)
Redundant given events_v2 writes
2025-04-30 10:21:47 +00:00
hq1 ffae16f7b9
Stop Cache.Stats + Revert "Temporarily disable ingest metrics (#5369)" (#5370)
* Revert "Temporarily disable ingest metrics (#5369)"

This reverts commit b96e96a7f6.

* Add :tools to MIX_ENV=dev

* Stop tracking caches hit ratio in favour of raw counters
2025-04-30 08:11:51 +00:00
hq1 b96e96a7f6
Temporarily disable ingest metrics (#5369)
* Temporarily disable ingest metrics

* Skip more
2025-04-29 16:30:20 +00:00
Adrian Gruntkowski 6afd12cdab
Add SitesAPI plan feature (#5366)
* Add SitesAPI plan feature

* Add test for usage of SitesAPI feature
2025-04-29 13:43:00 +00:00
Adrian Gruntkowski 88a1205503
Accept after register via team invite (#5358)
* Pass team identifier for team invites from register form

* Accept team invitation after registering and switch
2025-04-29 07:59:30 +00:00
Karl-Aksel Puulmann a3db3af806
Avoid compiling pageleave variant and p.js (#5351)
* Avoid compiling pageleave variant

Instead, it's treated as a no-op. Tracker still serves it.

Compile wall time went down from 86s -> 46s.

* Vendor, no longer compile p.js

This was a legacy script variant which we keep for backwards
compatibility but little else.

* chore: Bump tracker_script_version to 6
2025-04-29 06:42:48 +00:00
Adrian Gruntkowski dda551e7f5
Tidy Teams logic around and improve service functions names (#5352) 2025-04-28 08:22:04 +00:00
Adrian Gruntkowski 4ec2e8e151
Switch to the team on accepting team invitation (#5357) 2025-04-28 08:00:37 +00:00
Adrian Gruntkowski ddd75a6632
Change email input under Account Settings > Security to proper type (#5353) 2025-04-25 08:03:50 +00:00
hq1 b9ee37ef8c
Adjust notices & permissions (#5348)
* Change how generic notices refer the account

It's now "This team", unless no team is selected.

* Only owner and billing roles can access/manage subscriptions

* Change how Team Settings options are exposed:

- Subscription only available to owner/billing roles
- Invoices only available to owner/billing roles
- API Keys only available to owner/billing/admin/editor roles

* s/team members/members - to avoid repetition

* Only owner/billing can manage dev subscriptions

* Adjust existing tests

* Add test
2025-04-22 06:05:58 +00:00
Karl-Aksel Puulmann 2114c6232d
Allow marking custom events as non-interactive (#5295)
* Tracker: Allow sending non-interactive custom events

These will not affect is_bounce

* Allow marking events as `non-interactive` in events API, change bounce definition

Ref: https://3.basecamp.com/5308029/buckets/26383192/card_tables/cards/8450017341
Feedback: https://feedback.plausible.io/220

* CHANGELOG.md

* credo

* Update tracker script version

* Explicitly ignore event.interactive in schema

* Replace an old test util
2025-04-21 08:11:58 +00:00
Adrian Gruntkowski 1b7fc9c822
Allow super admin to manage other sites' goals (#5345)
* Allow super admin to manage other sites' goals

* Add regression test
2025-04-17 07:10:50 +00:00
hq1 4821c9489e
Change session transfer duration unit (#5338)
* Change session transfer duration unit

* Update buckets

* Change metric name to start clean
2025-04-17 05:10:33 +00:00
Adrian Gruntkowski 3764a4799e
Don't show "Subscription" settings item when user role not permitted (#5341) 2025-04-16 15:06:24 +00:00
RobertJoonas cb465511bb
Streamline creating/updating/deleting subscriptions in development (#5328)
* streamline dev subscriptions

* spawn -> Task

* fix button alignment

* do not define routes in test env

* remove explicit mentions of dev env when deciding whether to sandbox paddle

* decide checkout behaviour at compile time

* Timex -> Date

* hum

* make it work for enterprise plans too

* allow convenient subscription status change

* fix ci warnings

* remove redundant commented out code

* fix crash + review suggestion

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-04-16 13:43:17 +00:00
Adrian Gruntkowski fdb561bcb3
Move invitations related logic under Teams context (#5337) 2025-04-16 11:55:01 +00:00
ruslandoga 9bfb1992d9
Sessions transfer (#5229)
* sessions transfer

* took on ignore

* add slow test

* more tests

* allow BIG messages

* update tests

* continue

* continue

* cleanup

* fewer changes

* add config tests

* todo

* use less app env

* oops

* fixes

* cleanup

* update tests

* remove useless tests

* more buckets

* Update lib/plausible/session/transfer.ex

* Update transfer.ex

* Update lib/plausible/session/transfer.ex

* avoid calling into ConCache directly

* cleanup, add docs

* Update lib/plausible/session/transfer.ex

* fewer options

* there is no loop

* force deploy

* force deploy again

* individual puts

* fewer changes in cache/adapter.ex

* oops

* use existing atom names

* Cosmetic changes

* Bring back slow tag

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-04-16 09:56:39 +00:00
Karl-Aksel Puulmann 2fe154b169
Explicitly handle reverse order DateTimeRange (#5336)
We're seeing warnings as follows:
```
 (plausible 0.0.1) lib/plausible/stats/legacy/legacy_query_builder.ex:32: Plausible.Stats.Legacy.QueryBuilder.from/4 |
 |  (plausible 0.0.1) lib/plausible/stats/query.ex:143: Plausible.Stats.Query.put_imported_opts/2 |
 |  (plausible 0.0.1) lib/plausible/stats/query.ex:163: Plausible.Stats.Query.get_imports_in_range/2 |
 |  (plausible 0.0.1) lib/plausible/imported.ex:98: Plausible.Imported.completed_imports_in_query_range/2 |
 |  (plausible 0.0.1) lib/plausible/stats/query.ex:65: Plausible.Stats.Query.date_range/2 |
 |  (elixir 1.17.3) lib/calendar/date.ex:111: Date.range/2 |
 |
warning: a negative range was inferred for Date.range/2, call Date.range/3 instead with -1 as third argument
```

As well as some Stats API queries with the date time range reversed.

This PR makes it explicit we support passing the range in reverse and
handles that without warnings. Along the way added some tests.

Ref: https://3.basecamp.com/5308029/buckets/36789884/card_tables/cards/8415153184
2025-04-16 09:52:06 +00:00
Marko Saric 472b7bfb1d
Improve the error messages on the change teams screen (#5332)
* improve the error message on the change teams screen

* Update membership_controller.ex

* Adjust tests

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2025-04-16 08:18:04 +00:00
Adrian Gruntkowski eb838174a5
Change redirects from external to internal where possible (#5331) 2025-04-16 08:06:07 +00:00
Adrian Gruntkowski 9627165f36
Make BackfillTeams completely schemaless (#5327) 2025-04-15 08:52:13 +00:00
Adrian Gruntkowski ec4c6c453a
Switch from `Site.locked` to `Team.locked` (#5304)
* Switch to `Team.locked` for checking lock state

* Rename `update_for_sites` => `update_for`
2025-04-15 06:59:34 +00:00
Adrian Gruntkowski 9c6f2ee85a
Expose team setup state in CRM (#5326) 2025-04-15 06:40:39 +00:00
Adrian Gruntkowski d6be2e93a8
Fix error handling of invitations, 2fa form and clean up team creation (#5324)
* Change `:forbidden` error to `:permission_denied` for consistency

* Stop force-filling timestamp fields on personal team and membership

* Fix password field name in (re)generate 2FA recovery codes form
2025-04-14 08:07:51 +00:00
Cenk Kücük e6f6673dca
escape team name in CRM (#5321) 2025-04-11 11:10:31 +00:00
hq1 96ebd01f00
Release 3.0.0 (#5309)
* Update User schema with a field required by teams migration

* Start cloak vault for self-hosted release migrations.

Since this one is using schemas, existing encrypted columns
do require cloak to be up.

* Update changelog

* Make trial notification ee-only

* Replace `Plausible.ee?/0` with `ee?/0` across the codebase

* Bump release date
2025-04-11 08:07:57 +00:00
Artur Pata 2a18ba8f40
Hide footer when viewing stats (#5254)
* Stop showing footer with stats, except when user is not logged in / viewing shared dashboard

* Add testsfor Site Settings menu CE and EE

* Fix test titles, test org and tags
2025-04-11 05:06:27 +00:00
Adrian Gruntkowski 63f75c90d5
Update `team.locked` in parallel with `sites.locked` in SiteLocker (#5315)
* Add `locked` to Team schema and add predicate helper in Teams

* Update `team.locked` in parallel with `sites.locked` in SiteLocker

* Adjust team backfill migration to ignore locked team field
2025-04-10 11:47:18 +00:00
RobertJoonas 087b6e77bc
last 90 days -> last 91 days (#5301) 2025-04-09 16:40:06 +00:00
hq1 59fa96863f
Plugins API: allow prop enable for internal keys (always) (#5302) 2025-04-09 14:01:33 +00:00
Karl-Aksel Puulmann 3d1d0c5139
APIv2: More tolerant shorthands for date ranges (#5282)
* APIv2: More tolerant shorthands for date ranges

I was using APIv2 today and got pissed off that I couldn't do
`"date_range": "3d"`. So I went ahead and fixed this issue...

* Changelog

* typegen

* fix

* More invalid tests
2025-04-09 10:38:54 +00:00
RobertJoonas 4eb4b68b99
Sort by exit rate (#5289)
* WIP

* Works, maybe

* More tests

* format + slight refactor special_metrics

* implement exit_rate equivalent to current dashboard metric

* add validations to query_parser

* implement comparisons for exit_rate

* merge imported exit rate

* plug in the new metric

* make exit_rate sortable

* changelog

* generate types

* rename tests

* changelog

* maintain order of special metrics

* move exit_rate to the bottom as the less significant special metric

* capitalize null + query assign tweaks

* add comment

* Update lib/plausible/stats/sql/special_metrics.ex

Co-authored-by: Karl-Aksel Puulmann <macobo@users.noreply.github.com>

---------

Co-authored-by: Artur Pata <artur.pata@gmail.com>
Co-authored-by: Karl-Aksel Puulmann <macobo@users.noreply.github.com>
2025-04-09 09:47:12 +00:00
Adrian Gruntkowski 1e17d54b5b
Set site and member limits to unlimited for CE (#5288)
* Set site and member limits to unlimited for CE

* Don't even compile billing tests that trigger warnings in `ce_test`

* Split layout test into 2 distinct tests for CE and EE due to limits

* Update CHANGELOG.md

* Remove redundant test tag
2025-04-08 14:22:20 +00:00
hq1 de1bde4529
Backfill teams - CE (#4925)
* OG script

* Adapt to CE

* Remove commented line

* Backfill teams CE in a single transaction (#4985)

* single tx

* add migration

* Reorder migrations

So that identifier is already present and
can be fetched using schema-based queries.

* Reorder again on top of master + use data migration utils

---------

Co-authored-by: ruslandoga <ruslandoga+gh@icloud.com>
2025-04-08 08:23:43 +00:00
Adrian Gruntkowski 659cae50aa
Set current_team when user has team membership in viewed site (#5284)
* Make `site_role/2` return whether real is team or site scoped

* Rename `has_admin_access?` => `has_editor_access?`

* Switch current team if user is a team member in site's team
2025-04-08 08:09:47 +00:00
Karl-Aksel Puulmann 6127ebccc1
time-on-page: Remove flag, CHANGELOG.md, time_on_page in APIv2, update old tests (#5277)
* Remove new_time_on_page feature flag

* Update tests to use new time on page

* Mark time-on-page as a public metric in APIv2

* CHANGELOG.md

* Validate time_on_page in APIv2

* Update typing

* Remove redudant arguments

* Update GA4 test

* Update stats_controller_test

* Remove assertion from csv_importer

* Add nil case to new time on page tests
2025-04-08 07:28:03 +00:00
Karl-Aksel Puulmann 0fcbcc3a8c
time-on-page: csv import/export support, preparation for release (#5274)
* CSV import/export support for time-on-page

Note only the new time-on-page metric is exported this way

* visibility check for graphing of time_on_page

* FE no longer receives/sends legacy_time_on_page_cutoff

* Remove current_user from exports

* Remove legacy_time_on_page_cutoff from query.include, make behavior work off of site.legacy_time_on_page_cutoff explicitly

* Remove dead function

* More current_user_id removals
2025-04-08 06:25:11 +00:00
Adrian Gruntkowski 847353d17e
Fix determining CE/EE in migrations (#5283)
* Exclude MigrationUtils in validation check

* Expose runtime versions of CE/EE checks for migrations

* Fix migrations relying on CE/EE checks
2025-04-07 09:03:01 +00:00
Adrian Gruntkowski d31a175c40
Remove `teams` feature flag and fix seeds (#5276)
* Fix seeds

* Remove teams flag
2025-04-07 07:59:41 +00:00
Adrian Gruntkowski 250e7399a9
Only show team CTA banner to owner when site team is not set up (#5273) 2025-04-03 12:50:50 +00:00
ruslandoga 301a041736
use one lock partition per cache in sessions (#5123) 2025-04-03 12:45:31 +00:00
Adrian Gruntkowski 6ed7d1f8cc
Add styling to CTA link (#5271) 2025-04-03 11:28:53 +00:00
Adrian Gruntkowski a715ed2f32
Remove Editor->Admin site role conversion and limit permissions (#5210)
* Remove editor->admin mapping from Site Settings > People

* Restrict editor role and allow admin to update site role

* Disable actions in Site Settings > People for roles other than admin and owner

* Fix test

* Update labeling of guest members in CRM for clarity

* Update phrasing in other spots of UI

* Update CHANGELONG.md

* Revise team related banners displayed under Site Settings > People

* Fix permissions check for role update
2025-04-03 11:04:19 +00:00
Adrian Gruntkowski 6ee4f57cf7
Revert "Remove trial notice on 1st site creation (#5269)" (#5270)
This reverts commit 8a1ee87acc.
2025-04-03 10:02:14 +00:00
hq1 8a1ee87acc
Remove trial notice on 1st site creation (#5269)
Per @metmarkosaric's request
2025-04-03 08:57:56 +00:00
Adrian Gruntkowski 0f4a90815a
Send e-mail to new owners when site team is changed (#5267)
* Send e-mail to new owners when site team is changed

* Improve subject copy

Co-authored-by: hq1 <hq@mtod.org>

* Update copy in test

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-04-03 08:50:54 +00:00
Adrian Gruntkowski ba08ea9d9d
Show number of setup teams in CRM dashboard (#5268) 2025-04-03 08:33:16 +00:00
Adrian Gruntkowski 299e59afc2
Append `__team` parameter to URLs in notification e-mails (#5266)
* Append `__team` parameter to URLs in notification e-mails

* Improve copy in guest to team member promotion email

* Make "return_to" set in redirect in `RequireAccountPlug` actually work

* Improve accepted site transfer e-mail phrasing and link
2025-04-02 14:38:52 +00:00
hq1 98ffeca6a6
Stack bump: Elixir 1.18, OTP 27.3.1, Node 23.2.0, (#5264)
* Update tool versions

* Update deps

* Address runtime/compilation warnings

* Format

* Update Dockerfile

* wip

* Simpler

* oof

* hum

* format

* Bump cache vsn

* oops

* Fixup

* Fix dockerfile

* Try bumping node too 🤷

* Revert "Try bumping node too 🤷"

This reverts commit cdbe8d4a78.

* Reapply "Try bumping node too 🤷"

This reverts commit 12cafae22b.

* Welp
2025-04-02 12:39:22 +00:00
Marko Saric a1c1f09a73
change the copy on the top of a new dashboard (#5262) 2025-04-02 07:49:17 +00:00
Adrian Gruntkowski cb65f12448
Fix links to users under "Other Members" in Site CRM (#5263) 2025-04-01 13:05:08 +00:00
hq1 ab350e0b2b
Ensure guest promotion e-mail is sent w/ updated team name (#5261) 2025-04-01 10:37:05 +00:00
Adrian Gruntkowski 4f0207ce6f
Prefix site roles with "Guest " in UI (#5259)
* Prefix site roles with "Guest " in UI

* Update tests
2025-04-01 09:02:08 +00:00
Adrian Gruntkowski ffa82176a2
Only show nag screen when the current team has any sites (#5257) 2025-04-01 08:32:37 +00:00
RobertJoonas 7e248d07ca
Fix favicons for domains including a subfolder (#5258)
* fix favicons for subfolder domains

* changelog

* rename source -> domain
2025-04-01 08:08:01 +00:00
RobertJoonas 487e3d81b4
Ingestion: Reject blank engagements with 400 (#5253)
* reject blank engagements with 400

* address review comments

* add request tests
2025-03-31 14:34:21 +00:00
Adrian Gruntkowski 94e9a20038
Populate `team_id` when provisioning API key (#5234)
* Set team when creating API key

* Create API key with team ID and adjust API key CRM

* Make CRM work with team-less API keys still

* Scope owner's API keys by team on setup

* Rate limit team scoped API keys by their team

* Enforce team scoping for API key with a team

* Prevent using legacy API keys against setup teams

* Enforce team scoping in Sites API too

* Scope API keys list in settings by team

* Do not prevent legacy API keys from accessing setup teams

* List legacy API keys across all teams

* Display "API Keys" under "Team Settings" when team is setup

* Scope teams index in Sites API as well

* Test Sites API actions

* Revert "Scope owner's API keys by team on setup"

This reverts commit 08fd5b4e801417a28ebb9937457cf3e59f7386a0.

* Test and slightly simplify API key CRM logic

* Test API key provisioning from Account Settings

* Test `AuthorizePublicApi` plug adjustments

* Simplify conditionals (h/t @aerosol)

* Change back to using `schema` in CRM logic

* Don't run tests triggering Kaffy warning locally

* Run quirky Kaffy tests only on CI in EE env
2025-03-31 11:35:09 +00:00
RobertJoonas 8d98a75cd5
Upgrade page fixes (#5248)
* recommend business plan if user on business plan already

* fix billing notices on choose-plan page
2025-03-31 10:19:34 +00:00
RobertJoonas 167ff65a69
Add top 3 pages to traffic spike email (#5251)
* improve traffic_change_notifier_test

* add top 3 pages to traffic spike email

* improve email layout

* changelog

* fix tests after layout change
2025-03-31 09:24:28 +00:00
RobertJoonas 8e0f618c91
Increase Conversion Rate precision by one decimal place (#5250)
* change cr and group_cr rounding precision

* fix tests

* changelog
2025-03-31 09:11:47 +00:00
Karl-Aksel Puulmann 42cea1d889
time-on-page: `site.legacy_time_on_page` cronjob (#5215)
* site.legacy_time_on_page_cutoff migration

* Update migration logic

* Cronjob for setting legacy_time_on_page_cutoff

* Test site creation default legacy_time_on_page_cutoff

* Use site.legacy_time_on_page_cutoff

Leaving the query param logic for now for testing purposes

* tweak cron

* Work around defaults in tests

* Fixes

* Make cutoff date in job configurable - useful for backfilling
2025-03-31 08:54:49 +00:00
Karl-Aksel Puulmann cbffaa2054
time-on-page: Dashboard tweaks (#5217)
* Make column width of time-on-page wider

This will accomodate for the warnings

* Update warning messsage

* Breakdown table: Show space between * and warning in tooltip
2025-03-31 08:12:49 +00:00
hq1 b5396cc7a3
Use `PartitionSupervisor` for UA parse dispatch (#5245)
* Use `PartitionSupervisor` for UA parse dispatch

* Format
2025-03-27 13:36:19 +00:00
hq1 0e8c8b4063
Make settings sidebars sticky (#5242)
* Make settings sidebars sticky

* Give sticky nav some y-padding

---------

Co-authored-by: Uku Taht <uku.taht@gmail.com>
2025-03-27 11:15:25 +00:00
hq1 b45d5e90c1
Supervise user agent parsing (#5243)
* Supervise user agent parsing

* Instrument UA parse timeout with a counter

* Test
2025-03-27 10:47:19 +00:00
RobertJoonas 1b4aefb7d2
Stop counting today in `7d` and `30d` periods + add `28d` and `90d` (#5240)
* change 7d and 30d periods in API v2

* change 7d and 30d periods in legacy API

* add 28d and 90d into the dashboard

* add tests

* add 28d and 90d to public API v2

* changelog

* npm run generate-types

* typo

* fix NPM test

* fix interval_test

* add P shortcut for last month

* hide last 30d from datepicker but keep keybind functional

* fix keybind hints

* Timex to Date + helpful comment

* prettier format

* adjust comment

* mention 30d -> 28d in changelog as well

* make period hidden param new default
2025-03-27 09:49:56 +00:00
hq1 02370c5335
Change site team (#5238)
* Expose change_team/3 interface

* Extend `Teams.Users` context

* Update tests

* Implement change site's team UI

* Update tests

* Fixup for CE/EE

* Mark more tests as EE only

* Add extra plug-level protection
2025-03-26 10:47:37 +00:00
Artur Pata 5d966208da
Fix pageviews slider (#5209)
* Reposition pageview slider

* Claw back horizontal space so as not to wrap slider output on screens ~1024px wide
2025-03-26 10:35:40 +00:00
Adrian Gruntkowski e17074614e
Fix user and team deletion from CRM (#5241)
* Fix user and team deletion from CRM

* Run tests only against EE
2025-03-26 10:33:21 +00:00
RobertJoonas c7bf54325e
Fix visitors.csv vs main graph discrepancy (#5230)
* fix typo to stop logging error in test output

* add time:minute interval to internal api schema

* always get visitors and visits from sessions table when time:minute dimension used

* query-api generate types

* changelog update
2025-03-25 16:18:48 +00:00
Adrian Gruntkowski e07300e0c0
Limit rate of requests for Stats/Sites API via Team directly (#5231)
* Limit rate of requests for Stats/Sites API via Team directly

* Add logging of guest and non-member API key access for tracking

* Add more tests

* Don't log super admin and capture logs in test output

* Fix a typo in existing `capture_log` tag
2025-03-25 08:37:05 +00:00
Artur Pata f698bbbf57
Clean up Saved Segments feature flags (#5228)
* Clean up Saved Segments feature flags

* Update feature name in Growth tier
2025-03-25 08:06:24 +00:00
RobertJoonas 79f514910b
Add final usage check before locking sites (#5232)
* check usage last chance before locking

* move function to avoid dialyzer error

* keep some tests out of CE

* update variable name
2025-03-24 12:50:24 +00:00
Adrian Gruntkowski 22ce4dcd03
Add `Team.hourly_api_request_limit` and update it on plan change (#5227)
* Add `Team.hourly_api_request_limit` and update it on plan change

* Fix tests for CE

* Fix CE tests once more

* Add backfill script

* Fix backfill script tests for CE
2025-03-24 11:33:40 +00:00
RobertJoonas c32cf24823
Search Terms dashboard report follow-up (#5223)
* search terms: stop returning unused fields

* fix Details link positioning
2025-03-20 13:33:41 +00:00
Adrian Gruntkowski bc143d418b
Add `GET /api/v1/sites/teams` endpoint and make related adjustments (#5220)
* List only sites under team in Sites API if team id provided

* Add tests for Sites API create site with team_id provided

* Implement `GET /api/v1/sites/teams` endpoint

* Remove team identifier input from Team settings

* Use feature availability function

* Fix tests setup
2025-03-20 13:22:49 +00:00
hq1 8d9461d152
Guest Memberships via Sites API (#5205)
* List site guests via Sites API

* Create guests via sites API

* Delete guest memberships/invitations via Sites API

* Credo

* Test e-mail delivery

* Format

* Update extra/lib/plausible_web/controllers/api/external_sites_controller.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update lib/plausible/sites.ex

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Use aliases for optional where clauses

* Swap order columns

* Use GuestMembership.id in the union query

* Prefer explicit enums over boolean status

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2025-03-20 10:56:16 +00:00
Adrian Gruntkowski b51d188ba3
Switch Teams feature flag to scope by user instead of a team (#5222) 2025-03-20 08:33:54 +00:00
hq1 74f02b6cbe
Docs links for teams (#5216)
* Update Team Settings tiles with docs links

* Update

* Add docs link to team setup CTA target

* s/user-roles/users-roles
2025-03-20 08:12:22 +00:00
RobertJoonas 08d865b214
Google Search Terms error message: too recent period (#5212)
* consider too recent period erroneous + missing tests

* to typescript + center loading spinner
2025-03-20 07:38:33 +00:00
Marko Saric e81098855d
fixing a typo (#5221) 2025-03-19 16:04:18 +00:00
hq1 11e43645d9
Stop sending hard bounces to sentry (#5218)
* Update bamboo_postmark

* Filter out hard bounces

* !fixup
2025-03-19 10:39:55 +00:00
Adrian Gruntkowski 77fa590ed3
Fix Team Admin permissions (#5211)
* Fix site role update permissions for admins

* Show transfer option under Site Settings > People to admins too
2025-03-19 08:39:22 +00:00
Adrian Gruntkowski f15305254b
Implement team deletion and refactor user deletion (#5196)
* Implement team deletion and refactor user deletion

* Secure team deletion endpoints with team access plug

* Add dedicated tests for `Teams.delete/1`

* Test new controller actions and views

* Rephrase "Setup a team" => "Create a team"

* Improve team-related copy

* Fix personal team removal on user delete with multiple teams

* Wrap `delete_user!` contents in a transaction

* Add notice in user deletion view in case of multiple teams ownership

* Add a basic test and fix copy
2025-03-18 08:34:07 +00:00
Adrian Gruntkowski 649d1d9af5
Allow site transfer between different teams of the same user (#5192)
* Allow site transfer between different teams of the same user

* Fix typespec

* More type and branching fixes to satisfy dialyzer

* Alter when site transfers are included in sites listing

As now it's possible to transfer site between teams of the same user,
the site listing logic has to account for that. With this change, site
transfers are shown along sites under the condition that user is either
switched to personal sites view without a team or the team they
are currently switched to is different from the one the site belongs to
now.

* Make site danger zone available to admins

* Authorize admins to transfer sites on plug level

* Allow admin to initiate site transfer
2025-03-18 08:16:15 +00:00
Karl-Aksel Puulmann 7439529fdd
Store `tracker_script_version` under `ingest_counters` (#5203)
* Migration to add `tracker_script_version` to ingest_counters table

* Store tracker_script_version in ingest_counters

* Default 0
2025-03-18 06:56:55 +00:00
hq1 eac089b271
Improve verification diagnostics (#5204)
For when both GTM & WordPress Plugin are detected,
give WP priority. Also, consider `data-cfasync`
a known attribute since it's the plugin that
adds that.
2025-03-17 09:56:55 +00:00
RobertJoonas c8ba6d918c
Scroll depth flag cleanup (#5195)
* Backend: get rid of scroll_depth.ex

This commit starts treating the scroll depth feature as *always visible*,
removing the ClickHouse queries on dashboard loads and starting to always
include scroll_depth in dashboard reports and export queries.

* Frontend: remove site.scrollDepthVisible

* adjust csv_importer_test

* remove site.scroll_depth_visible_at
2025-03-13 13:39:38 +00:00
Artur Pata f7b535df4b
Fix dashboard report behavior when goals are in segments - variant C (#5175)
* Replace GET /segments and GET /segments/:segment_id with server-rendered list, fix issue with dashboard report columns

* Remove WIP comments and throw earlier for invalid dashboard state

* Fix Segments details issue on public / shared link sites, add tests
2025-03-13 13:02:14 +00:00
hq1 30560364aa
Friends don't let friends overflow integers (#5194) 2025-03-13 10:26:05 +00:00
Artur Pata 6b7cac3673
Make setting sites limit slightly more convenient (#5193) 2025-03-13 10:25:32 +00:00
hq1 d5f6563548
Email notification on guest->team member promotion (#5191)
* Notify guests on team member promotion

* Fix

* Send out the guest promotion e-mail based on explicit condition
2025-03-13 10:12:12 +00:00
Karl-Aksel Puulmann ca4da16744
Mark unreasonably high engagement_time values as 0-s (#5190)
Follow-up to https://github.com/plausible/analytics/pull/5181

Users might have the old version of the script cached for a while yet so
avoid ingesting invalid data while that's the case.
2025-03-13 08:42:59 +00:00
hq1 629902cdbc
Get rid of `billable_user` in favour of `current_team_role` (or `site_role` if need be) (#5180)
* Get rid of `billable_user` in favour of `current_role`

* s/current_role/current_team_role

* Sort it out (tm)

* Remove unresolvable property from sentry context

* Test & adjust dashboard locked box

* Satisfy a test
2025-03-12 14:40:30 +00:00
RobertJoonas 37813a1605
Ingest scroll depth and engagment time from string + drop blanks (#5182)
* parse scroll depth from string in ingestion

* drop engagement that are missing both sd and e

* parse engagement time from string too

* fix flaky test

* move dropping into a more suitable place in code

* add test

* silence credo
2025-03-12 14:06:04 +00:00
Artur Pata dbca97f02e
Fix shared link site role (#5186)
* Fallback to :public with data-current-user-role

* Add tests
2025-03-12 13:30:23 +00:00
Karl-Aksel Puulmann 2f27ce02be
Don't read/write active_visitors from GA4 (#5178)
Ref: https://3.basecamp.com/5308029/buckets/41123095/card_tables/cards/8391930289

This column was speculatively added for time-on-page but we don't need
it.
2025-03-12 11:22:05 +00:00
Karl-Aksel Puulmann 0514a6db18
time-on-page: dashboard + timeseries support (#5174)
* Support passing `include` as a query parameter for dashboard APIs

* Mark time-on-page metric sortable

It now is thanks to the changed query

* new-time-on-page flag with cutoff being sent to the frontend

* Add correct tooltip title

* Implement metric warning for when legacy and new time_on_page metrics are mixed

* Send legacy_time_on_page_cutoff to backend

* Make time-on-page graphable with the new metric

* Only show metric warnings for time_on_page if flag is enabled

* Changelog

* Solve an clickhouse error when querying timeseries with only legacy time-on-page

* Add tests for timeseries of new time-on-page

Along the way fix an issue with comparisons not working properly

* Solve a typing issue

* Allow toggling legacy_time_on_page_cutoff off in dashboard

* Slightly better workaround

* Solve typing issue

* Prettier

* Guard against no warning

* Solve warning
2025-03-12 09:51:53 +00:00
hq1 841abf5e53
Add billing role (#5171)
* Update role enums with billing

* [wip] Ensure no team management can be done for roles other than admin/editor

* Track `current_role` at plug/mount level

* Some team role policy enforcement

* Guard remaining routes based on current team role

* Notify billing members via check usage worker

* Include billing members in trial/locked notifications

* Permissive team access policy when no current team assigned

Effectively the plug should no-op, so that existing user
notices/alerts can be displayed.

* Send cancellation notifications to billing role members

* Include billing members in renewal notifications

* Update moduledoc

* Exclude :guest role from team access auth plug
2025-03-11 15:43:37 +00:00
Karl-Aksel Puulmann e9b30e0ba5
time-on-page: query (#5159)
* Default to time_on_page

* Add new columns to schema

* Read from new column in legacy query

* Read/write new imported_pages columns

* Remove time_on_page column from imported_pages

* Simple, stupid new_time_on_page metric

* Update csv_importer schema

* Refactor: consistent __internal helpers, this will help with joining the query

* Refactor select_joined_metrics

* Refactor: pass `query` to event_metric

* Refactor: remove needless site argument from various calls

* Legacy joining query attempt

* Move test around

* Add more tests for both legacy and new time_on_page metrics in query API

* time_on_page reported in seconds

* timeseries test for metric

* WIP

* Wrap main query in subquery - without this run into trouble performing the join

* Calculate time_on_page in main query, no more new_time_on_page

* Add some TODOs

* Return NULL over 0 when no visits with time-on-page data

* Update moduledoc

* Update some tests that were not expecting integers

* Add a TODO

* Update tests

* Make graphing time series with combined metrics work.

* Slightly more consistent approach to flag updating in APIv2

* Seeds with engagement data

* Make graphing time series when cutoff is in the middle work

Bakes less assumptions into everything as well.

* Rename to legacy_time_on_page_cutoff

* Fixup lib/plausible_web/controllers/api/external_query_api_controller.ex

* Remove a todo and dead/misleading code

* Remove a resolved todo

* Remove needless rounding

* gen types

* Update pages test

* Remove needless columns from select

* Update tests: timestamps and remove comment

* Flip branches
2025-03-11 11:19:58 +00:00
Adrian Gruntkowski 486a272498
Refine team switching and switch from `my_team` to `current_team` (#5144)
* Rename "My Team" to "My Personal Sites"

* Rename "Create" to "Setup" in context of teams

* Set default Team Name to "Username's Team"

* wip

* end

* Expose team identifier

* fixup

* team id

* wip

* Rename `Teams.name()` -> `Teams.default_name()` for clarity

* Update test name

* Always reset team name when navigating to Team CTA

* Always use default team name for non-setup team

* Add tests for team name function

* Put sites list heading change behind FF

* Don't rely on FF for implicit team existence check

* Remove unnecessary team pick by parameter in site creation action

* Put first 3 teams in auth assigns context

* Fix setting current team from session

* Make `dropdown_item` component accept method for link

* Implement embedded team switcher in nav bar

* Store only personal team under my_team

* WIP

* Minor team switcher visual tweak

* Fix personal team selection

* Show only guest sites when no team picked

* Show CTA only in reference to `@my_team`

* Fix dedicated team switcher view

* Move picker indicator to the right in dedicated team select

* Alter site listing logic and fix tests

* Add viewer invitation to seeds

* Fix embedded team switch display condition

* Switch current team after setup

* Explicitly clean current team session value when no longer valid

* Remove redundant team switching logic

* Add quick link to team settings

* Don't show quick link when there's no current team

* Fix dedicated team switcher for no current team case

* Add test for my team fallback case

* Don't allow opening team settings for personal team

* Fix formatting

* Add site listing tests

* Fix team switching to avoid clash with existing conn params

* Fix formatting

* Remove unneeded `method` from `dropdown_item` component

* Decalre attributes for `team_switcher` component

* Render Invoices/Subscription sections based on team state

* Fix formatting

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-03-11 08:31:12 +00:00
hq1 0c62deefc7
Show site placeholders on 1st mount (#5167) 2025-03-10 12:30:00 +00:00
hq1 bfd7c45842
Dont crash sites when ch 24 intervals unavailable (#5165)
* Don't crash /sites LV when 24h intervals query fails

* Log error
2025-03-10 11:48:53 +00:00
RobertJoonas 3f43cfa077
Scroll Depth Release (#5120)
* make scroll depth public in json schema

* add test for 400 response

* add info paragraphs in 'add goal' form

* changelog update

* fix typo

---------

Co-authored-by: Uku Taht <Uku.taht@gmail.com>
2025-03-10 11:18:39 +00:00
Karl-Aksel Puulmann 4078e762d3
Stop counting engagement events into current visitors (#5163)
This was unexpected breakage from releasing new tracker script with engagement tracking to the world. Users are seeing inflated current visitors counts compared to top sources report.
2025-03-10 08:12:26 +00:00
Artur Pata 2db60c90af
Provide top stats graphable metrics from BE (#5160)
* Provide top stats graphable metrics from BE

* Update changelog
2025-03-07 12:08:25 +00:00
Artur Pata 964ca85f68
Fix issue with shared link auth with /current-visitors and segments requests (#5154)
* Remove Segments API feature gate since flag is globally true

* Include auth param with all requests when on shared dashboard

* Update changelog

* Remove feature flag check plug

* Unify logic, refactor names

* Refactor name
2025-03-06 15:35:56 +00:00
hq1 aa91289153
Team provisioning tweaks (#5155)
* Remove "team layout updated" flash message

* Remove flash when switching team

* Prevent illegal UI states when at team members limit already

* Test UI states at team members limit

* Remove unnecessary socket assign
2025-03-06 12:52:44 +00:00
Karl-Aksel Puulmann 694bd6fae2
Improve dashboard main graph - revenue metrics, nulls (#5153)
* Main graph: Graph revenue metrics as zeroes instead of nils.

This has no effect on existing APIs as:
- Comparisons/empty data point logic only affects APIv1 which does not expose revenue metrics

Also changes semantics for visit_duration to be more in-line with the
rest.

* Improve dashboard main graph

- Graph tooltip for revenue metrics now shows revenue with the relevant
  monetary unit.
- Graph tooltips for scroll depth, visit duration and so on now shows `-`
  instead of 0 on dates where no relevant visits occurred.

* Remove business logic duplication
2025-03-06 12:11:01 +00:00
hq1 b7912c665e
Expose `teams.notes` in CRM/HelpScout (#5151)
* Expose teams.notes in CRM

* Expose team notes via HelpScout notes

* Fix dialyzer
2025-03-06 10:10:27 +00:00
hq1 eaeec7ae5f
Exports revert (#5152)
* Revert "Ensure no export button is rendered for public roles"

This reverts commit 213fafe041.

* Revert "Restrict public CSV export access (#5089)"

This reverts commit d3d0547484.

* Keep the Role.public enum needed elsewhere
2025-03-06 09:58:03 +00:00
Artur Pata 75e46bf54b
Prepare FE feature flag for launching smoothly (#5146)
* Prepare FE feature flag for launching smoothly

* Enable choose_plan visuals on saved_segments_fe as well
2025-03-05 12:24:54 +00:00
hq1 2eef3d9969
Use compile-time Ingestion.Source lookups (#5141)
* Use Source compile-time source lookups

* skip a test
2025-03-05 09:18:45 +00:00
Artur Pata 47b8553ca1
Implement Site Segments billing feature (#5129)
* Implement Site Segments billing feature

* Make sure Site Segments benefit appears only when feature flag is present

* Add site_segments flag to v3 plans

* Refactor new filter menu back to ghost button

* Stop error state from persisting (#5131)

* Refactor how Segments appear on Choose Plan page

* Limit to 500 segments per site
2025-03-04 10:09:40 +00:00
ruslandoga 8926f6d6c1
peep (#5130)
* peep

* adapt peep to prom_ex buckets

* handle overmax
2025-02-28 13:15:05 +00:00
hq1 9e5be7103a
Revert "peep (#5126)" (#5128)
This reverts commit 90d0581c99.
2025-02-28 08:00:48 +00:00
Artur Pata 5ae2fd89f0
Resolve segment owner names and dates in site timezone in the BE (#5119)
* Resolve segment owner names and dates in site timezone in the BE

* Fix SegmentAuthorship

* Fix issue with updating dangling segment

* Refactor flaky PATCH segment test

* Unify segment type label logic

* Refactor SegmentOwnership type definitions for clarity
2025-02-28 07:06:20 +00:00
ruslandoga 90d0581c99
peep (#5126) 2025-02-28 06:46:16 +00:00
hq1 357da7b719
Reduce n lock partitions (#5124)
* Reduce n lock partitions

Isolated operations are no longer performed.

* !fixup

* !fixup
2025-02-27 14:45:54 +00:00
Uku Taht 6d3e6a76da
Segments end of life (#5095)
* Deal with segments when guest member is removed

* Handle segments when user removed from team

* Deal with user deletion

* Fix spelling

* Fix postgres client make task

* Remove migration
2025-02-26 13:54:07 +00:00
Artur Pata 421e7d2766
Add Saved Segments UI (variant D) (#4891)
* WIP

* Load members

* Assert that we know has_not_done will not work without changes

* Add tests

* Assert that dates are in the expected format

* Add tests, better authorship dates, api.js -> api.ts

* Add error panels

* Flatten errors on the API side

* Stop name copy from getting too long

* Make comparison mode and edit segment modes exclusive

* Fix flicker calculating space

* Fix issue with definite state not persisting

* Unhitch modals from query-context

* Separate API format and dashboard format of segment_data

* Clarify purpose of useDefiniteLocationState

* Tweak UI: site switcher, save as segment

* Fix issues with modals

* Remove commented and unnecessary code, better query context

* Fix too permissive site members dataset

* Make sure Segment doesn't show up as an option to customer without the FF

* Fix issue with 'See more' menu being present when it should not be

* Permit :has_not_done filter in segments

* Refactor to matching on filter list structure

* Flatten :and stemming from segment filters on first level

* Update test
2025-02-26 12:32:25 +00:00
hq1 ccdf50b734
Balance sessions across worker queues instead of explicit locks (#5113) 2025-02-26 08:03:52 +00:00
Karl-Aksel Puulmann 8aad9b1adc
APIv2: Fix `percentage` metric 500s (#5099)
* Refactor: remove metrics argument from merge_imported()

* Support querying percentage without visitors metric

* Fix ordering by special metrics with imports causing a 500

We don't calculate all metrics directly on imports, hence cannot order
the import by them either.

* Changelog
2025-02-26 07:07:17 +00:00
RobertJoonas 74f9717f5b
Scroll Depth Release: ingestion flag check for incremental load increase (#5106)
* check engagements flag on ingestion

* extend drop_reason
2025-02-25 09:19:59 +00:00
hq1 a0129a50fd
Stop capturing UA errors (#5108) 2025-02-24 15:59:51 +00:00
hq1 52fa881646
Bugfix: allow Team updates via CRM (#5107) 2025-02-24 10:20:21 +00:00
Karl-Aksel Puulmann 4c0c9e8411
Ingestion logic for engagement_time (#5100) 2025-02-20 11:26:20 +00:00
Adrian Gruntkowski 0e356c14f7
Ignore excess logger errors from Cowboy when sending to Sentry (#5096)
* Ignore excess logger errors from Cowboy when sending to Sentry

* Add test and simplify
2025-02-19 13:39:06 +00:00
RobertJoonas dfeb2c332b
Improve Page Scroll Goals UX (#5066)
* dont let blue background overflow rounded corners

* move scroll goal creation into a separate tab

* render goal type as Scroll

* add scroll goal edit capability

* implement automatic display name update in create form

* make UX more user-friendly

* autoselect the entire display name on first focus

* adjust tests

* set min value to 1 in scroll_threshold input

* rename goal trigger tab
2025-02-19 09:46:31 +00:00
Adrian Gruntkowski bf010a1537
Implement support for multiple team owners and multiple teams per user (#5008)
* Add tests for `Teams.get_or_create/1` and `Teams.get_by_owner/1`

* Start populating `current_team` in assigns fetching value from session

* Clean up team passing in invitation services

* Make site transfer service handle multi-team scenario

* Handle multi-team and permission transfer errors on controller level

* Handle multi-teams in site creation on service and controller level

* Drop validation limiting full membership to a single team

* Make user deletion account for public team ownership

* Adjust feature availability checks for Stats API key

* Use current_team when determining limits on site transfer invitation

* Adjust trial upgrade email submission to account for multiple owners

* Remove unnecessary `Teams.load_for_site/1`

* Spike renaming `owner` and `ownership` relationships to plural versions

* Make HelpScout integration handle owner of multiple teams gracefully

* Add FIXME note

* Resolve paddle callback issue by always provisioning a new team when none passed

* Set `current_team` as `my_team` only when user is an owner

* Implement basics of Teams CRM

* Extend Teams CRM

* Further adjust User and Site CRM and refine Team CRM

* Convert Enterprise Plan CRM to refer to team directly and not via user

* Remove unused virtual fields from User schema

* Add note to HelpScout integration

* Allow listing multiple owners under Site Settings / People

* Remove unused User schema relations

* Fix current team fetch in auth plug and context

* Implement basic team switcher

* Ensure (site) editor role is properly handled in site actions auth

* Don't set `site_limit_exceeded` error marker on `permission_denied` error

* Link from HS integration to Team CRM instead of User CRM when available

* Ensure consistent ordering of preloaded owners

* Add `with_subscription` preload for optimisitation

* Add ability to search sites by team identifier

* Add ability to pick team when transferring ownership directly

* Fix failing HelpScout tests

* Scope by team when listing sites in dashboard and via API (optional)

* Add ability to search by team identifier in plans CRM lookup widget

* Add subscription plan, status and grace period to team status info

* Expose teams list in user CRM edit form and fix team details CRM view

* Fix Team Switcher styling

* Reorganise header nav menu

* Avoid additional queries when authenticating user

* Hide the pay/site transfer message on lock screen when teams FF is on

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-02-19 09:33:25 +00:00
Uku Taht 7ae88c2c97
Make sure goal changeset error can be handled outside transaction (#5076)
* Make sure changeset error can be handled outside transaction

* Add test for goal form

* Also rollback upgrade required
2025-02-19 09:08:57 +00:00
Adrian Gruntkowski d3d0547484
Restrict public CSV export access (#5089)
* Restrict public CSV export access

* restrict export

* Restrict public CSV export access

* Revert "restrict export"

This reverts commit f756486420.

* Don't show CSV export option for viewers who are not logged in

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-02-18 17:07:58 +00:00
hq1 aa64d7ba4c
Update oban + sentry (#5088)
* Update oban + sentry

* Fixup

* dialyzer

* Add Reindexer plugin daily at 1am
2025-02-18 15:27:31 +00:00
RobertJoonas c97ef318a3
make page scroll goals work in funnels (#5077) 2025-02-18 12:26:47 +00:00
hq1 9312087fc8
Tweak remaining cache ets options (#5081) 2025-02-17 13:41:21 +00:00
hq1 6ff90b8645
Add R/W concurrency ets options to sessions cache tables (#5080) 2025-02-17 13:17:20 +00:00
RobertJoonas 51a6ca6654
Refactor comparison query & including imported data (#5068)
* write comparison_utc_time_range into query

* write site_imports into query

* use struct! over Query.set

* variable to module attr

* remove redundant comment

* reject over filter

* Map.reject over Enum.reject
2025-02-17 10:44:48 +00:00
Karl-Aksel Puulmann 53581973d0
Scroll depth: ingestion, query and import/export changes (#5072)
* Revert "Disable scroll depth exports temporarily"

This reverts commit 48ad691f53.

* Remove support for pageleave events being equivelent to engagement in ingestion

* Explicit column ordering inside csv imports

Subtle change, but this ensures that CSVs that contain extra columns or differently named columns do not cause trouble

* Add scale_sample fragment helper

* Update scroll depth queries to be based on visits rather than visitors

* Add test demonstrating session-based results

* Update csv test (session vs user-based difference)

* Attempt to update csv tests

* PR feedback
2025-02-17 10:03:39 +00:00
Karl-Aksel Puulmann 89a6b77132
Scroll depth: Rename imported_pages columns to reflect whats desired (#5071)
* Migration: Rename imported_pages columns to reflect whats desired

* Disable scroll depth exports temporarily

* Migration fix
2025-02-17 11:48:19 +02:00
Adrian Gruntkowski a0c13383e7
Implement support for cache partitioning for sessions (#5073)
* Implement very rudimentary support for cache partitioning for sessions

* Convenience for starting partitioned caches

* Test basic partitioning expectations

* Include put_many in test

* Use div/2

* Remove unused alias

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-02-17 08:38:34 +00:00
hq1 417e996c1a
Speed up salts lookup by serving them off ets (#5067)
* Speed up salts lookup by serving them off ets

* Add basic tests

* fixup

* Move now to init fn

* Just checking

* Use GenServer
2025-02-14 08:55:30 +00:00
Uku Taht c44151f040
Remove channels feature flag (#4972)
* Remove channels feature flag

* Add changelog
2025-02-13 11:48:24 +00:00
Karl-Aksel Puulmann ecae780750
Scroll depth: Engagement events should refresh in-memory session cache (#5063)
* Engagement events should refresh in-memory session cache

This will drop less events when session was actually active but didn't
have any pageviews/custom events arrive

* unwrap error

* Different handling of response types
2025-02-13 07:26:59 +00:00
Karl-Aksel Puulmann 47c095f65b
Remove a dead todo (#5064) 2025-02-13 07:26:54 +00:00
Adrian Gruntkowski 68268c5f98
Adjust sessions cache TTL check interval down to 10s (#5070) 2025-02-12 21:54:07 +00:00
Adrian Gruntkowski 2c2a179d4d
Lower sessions cache TTL check interval (#5069) 2025-02-12 21:16:13 +00:00
Uku Taht 9f1d8ec2b7
Update goal in segment (#5027)
* First attempt to update goal in segment

* Use transform_filters function for updating segments

* Use site id index in segment update query

* Escape regex

* Remove IO.inspect

* Stop double-wrapping goal :ok after update

* Expand segments goal update test

* Add whitespace matchers around square brackets

* Add comment for regex

* Use update_all to avoid bumping timestamp
2025-02-12 14:03:56 +00:00
Uku Taht 70bfc9ef66
Increase sessions and user agents cache ttl checks (#5062) 2025-02-12 14:03:27 +00:00
hq1 d2e0dcd2b4
Reorder application supervision tree (#5057)
* Reorder application supervision tree

* Move TOTP vault to the top

* Start Cache Stats emitters first
2025-02-12 12:07:06 +00:00
Karl-Aksel Puulmann 40926686f8
Fix mismatch between session and event user_ids after salts are rotated (#5065)
* Refactor test suite to allow seeking multiple sessions

* Fix mismatch between session and event user_ids after salts are rotated

Consider the following scenario
1. We receive a pageview from a user A
2. Salts are rotated after day end
3. We receive another pageview

Previously, this would result in:
- 2 different sessions with mismatching user_ids
- 2 events where each would have different user_ids

This fixes the problem by removing the previous faulty session updating
and forcing the event.user_id to be updated after we found a session
with the previous salt.

* Remove an assertion
2025-02-12 10:07:55 +00:00
Karl-Aksel Puulmann a7ff6faf00
Scroll depth: hide total conversions metric on dashboard (#5059)
* Hide top stat if value is null

* Handle nulls in events metric on dashboard - rendering - instead

* Return nulls for `event` metric when dealing with scroll goals

Counting conversions doesn't really make sense in this scenario.

If there are multiple goals, nulls are only returned for those affected.

If there is at least one scroll goal included by the filter, conversions
cannot be counted.

* Prettier

* Handle case with goal dimension AND filters correctly

* Remove todo
2025-02-11 08:49:07 +00:00
hq1 421f7610f2
ComboBox: revert unused changes (#5061)
* ComboBox: revert unused changes

Remnants from https://github.com/plausible/analytics/pull/4960

* Update
2025-02-11 08:30:54 +00:00
Uku Taht d762795979
Separate liveness and readiness checks (#5048)
* Separate liveness and readiness checks

* Changelog

* Make sure /api/health uses readiness check

* Do not expose internal error

* Make healthcheck repo calls parallel
2025-02-10 16:34:30 +00:00
RobertJoonas 269430281d
Scroll depth dashboard warnings (imported data) (#5051)
* add migration

* add schema field

* mark site_imports with has_scroll_depth

* add function to get imports in query range

* add scroll_depth metric warning in QueryResult

* return scroll_depth warning in top stats

* render minimalistic warning in top stats

* minimalistic warning in Top Pages breakdown

* prettier format

* silence credo

* add test

* use a snapshot of SiteImport schema in data migration

* also use a snapshot list of imported_* tables

* moduledoc (credo)

* change tooltip message

* change metric warnings structure in top stats response

* pass meta from queryresult directly

* revert top_stats_entry refactor

* prettier

* stop using SiteImport module in data migration
2025-02-10 14:50:54 +00:00
hq1 2cc3615486
Team Management UI (#4997)
* Start PromEx first; don't run the Oban plugin in test

* Implement `find_team_invitations`

* Implement `all_members`

* Allow disabling e-mail notifications on team member removal

Will be needed later, when operations are applied
in bulk and notifications go out only when transaction
succeeded.

* Fix visuals per @ukutath's suggestions

* Add `:setup_team` test context function

* Don't show team settings in the sidebar, if setup incomplete

* Add high-level interface for team layout arrangement

Will be used in setup but also later on, in membership settings.

* Update team/setup to use `Team.Management.Layout`

* Implement team general settings allowing layout arrangement

* Format

* Remove unused setup_team

* Add id attributes to member dropdown elements

* Format

* Unify team management experience

By sharing the same form layout in both views,
and enabling promoting guests to team members
in a separate section.

* Rename Invitations/Memberships getters

* Tweak team setup layout

* Update team setup markers only once

* Update tests

* Add another future regression test

* Fix typo

* Prune guest memberships on guest->team member promotion

* Remove now unnecessary `Candidates` module

* Add missing tests

* Catch up on multiple owners fixes

* Add missing describe-block setup

* Hopefully make Layout easier to follow

* Remove default prevention from dropdown

* Remove unused assign

* Make `sorted_for_display` skip scheduled for deletion

* `use PlausibleWeb.Component`

* Use `data-test-kind` for test specific selectors

* Remove `class="relative"` from `.dropdown` instances
2025-02-10 06:48:36 +00:00
Karl-Aksel Puulmann 3f6c64cf03
Update queries to work off of `engagement` events over pageleaves (#5053)
Note that export pageleave_visitors column has not been updated here.
2025-02-06 11:27:38 +00:00
Adrian Gruntkowski ae0d6af508
Turn TeamController tests into service tests and remove the controller (#5047) 2025-02-05 13:25:54 +00:00
RobertJoonas 4d05245036
Page Scroll Goals (#5029)
* migration: add scroll_threshold to goals

* update goal schema

* setup simple UI for creating scroll goals

* add ability to filter and breakdown scroll goals

* fix goals form tests

* add valiation for page path exists

* move todo comments to expression.ex

* move tests

* make it clear that scroll_threshold is optional

* avoid calling Plausible.Goal.type() too many times

* do not consider 255 scroll depth a conversion

* migration: add scroll_threshold to goals

* do not drop the old index yet

* More efficient goals join again

* Refactor: move goals stats code explicitly under Stats.Goals module

* Move code under Plausible.Stats.Goals

* 254 -> 100

* add scroll_threshold field to goal schema + new unique constraint

* adjust test to test what it claims to

* mix format

* add migration

* consider imported query unsupported when page scroll goal filter

* add missing tests

* pattern match imported argument

* silence credo

* Update lib/plausible/stats/sql/expression.ex

Co-authored-by: Karl-Aksel Puulmann <macobo@users.noreply.github.com>

* use site_imports populated in test setup

---------

Co-authored-by: Karl-Aksel Puulmann <oxymaccy@gmail.com>
Co-authored-by: Karl-Aksel Puulmann <macobo@users.noreply.github.com>
2025-02-04 10:37:04 +00:00
Artur Pata 15d78bd9a8
Stop segment queries when not needed (#5043) 2025-02-04 10:14:13 +00:00
RobertJoonas 2579bbea7b
Page Scroll Goals: migration step 2 (#5034)
* migration: add scroll_threshold to goals

* do not drop the old index yet

* add scroll_threshold field to goal schema + new unique constraint

* adjust test to test what it claims to

* mix format
2025-02-04 09:42:18 +00:00
Cenk Kücük b4ec09c6cb
Revert "Scroll depth: update `site.scroll_depth_visible_at` in ingestion (#5035)" (#5042)
This reverts commit 84aea97b95.
2025-02-03 15:07:15 +00:00
Karl-Aksel Puulmann 84aea97b95
Scroll depth: update `site.scroll_depth_visible_at` in ingestion (#5035)
* WIP: Update scroll_depth_visible_at in ingestion

* Simplify code and test genserver directly

* No more check_scroll_depth_visible!

* Update a test

* Update a test

* GenServer -> ets

* Additional where

* Fix a test
2025-02-03 09:37:58 +00:00
Karl-Aksel Puulmann de62f80564
Use `fetch` over `XMLHttpRequest` in plausible.js (#5025)
`fetch` allows us to use the keepalive flag, which more reliably
delivers data to us. It's also required for reliable scroll depth
capturing down the line.

The only major browser not to support fetch is Internet Explorer.
Clients who care about IE traffic can use the `.compat` variant of our
script (documented in
https://plausible.io/docs/script-extensions#scriptcompatjs). As of this
commit, IE makes up less than ~0.003% of incoming traffic to plausible.
2025-02-03 08:48:37 +00:00
RobertJoonas 1ae350a4e0
Looker studio (#5032)
* add very basic info box in site settings > integrations

* add looker studio as plan benefit

* add paragraph of text

* remove unwanted comma

* hide new settings section on ce

* moduledoc

* organize files and modules better + call ee-only condition in template

* move everything into a single template
2025-01-30 16:16:03 +00:00
Adrian Gruntkowski 86f3919625
Don't preload goal settings modal to avoid issues with opening in edit mode (#5031)
* Don't preload goal settings modal to avoid issues with opening in edit mode

* Remove test which is no longer holding ture

* Still enable preload for tests, as it's needed

* Fix and move test env switch inside the modal component

* Fix for release build
2025-01-30 11:01:17 +00:00
Adrian Gruntkowski 339dd89a98
Rework team creation constraints (#5003)
* Move `GracePeriod` under `Teams` and clean it up a bit

* Switch to relying on new team membership constraint when creating my team

* Remove unused unique_constraint from Teams.Membership schema changeset
2025-01-29 13:05:44 +00:00
Karl-Aksel Puulmann 7c6ba04a3c
Handle missing scroll depth #2 (#5017)
* add migration

* move scroll_depth_enabled? fn

* maybe set engagement_metrics_enabled_at when requesting dashboard

* maybe set engagement_metrics_enabled_at in shared_link action

* maybe set engagement_metrics_enabled_at on full export

* fix tests

* feature gate scroll depth on the dashboard with site.engagement_metrics_enabled_at

* feature gate scroll depth in full export too

* fix npm ci

* Rename things into FE, remove unneccessary flag checks

* Continue with renaming

* Rename site flag to be more descriptive

* Move business logic, calculate based on scroll depth, make more precalculatable

* Some docs

* Rename to site.scrollDepthVisible in frontend

* Update migration

* Fix template

* Remove boilerplate from tests

* Update tests

* More straight-forward test

* Update condition

---------

Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
2025-01-29 09:47:49 +00:00
hq1 94799b6d7a
Allow over-limit site ownership transfer for users having grandfathered plans (#5026)
* Add failing test

* Allow over-limit transfer ownership for grandfathered plans

* Update existing test - team timestamps are now relied upon
2025-01-29 09:18:11 +00:00
Karl-Aksel Puulmann 334f8bbdfc
Tracker: Send `engagement` events on visibilitychange (if pageleave extension) (#5023)
* Separate `engagement` event triggered on visibilitychange

* Set up shared tests for engagement requests and pageleaves

* Store scroll_depth on engagement events

* Move test to be shared

* Update cache_store
2025-01-29 06:30:41 +00:00
Karl-Aksel Puulmann 4c68010dd9
Proposal: Remove `unique users` from dashboard when filtering by goal (#4999) 2025-01-28 10:41:43 +00:00
Artur Pata dd8e143758
Expand segments also when using Query.from (#5021) 2025-01-28 07:45:53 +00:00
RobertJoonas 00deb05d64
Refactor including imports in stats queries (#5011)
* preload completed site_imports for site when needed

* remove unused field from top stats response

* refactor imports meta

* remove redundant function clause

* fix ordering in queryresult

* preload completed_imports in plugs

* write code more short
2025-01-27 10:23:58 +00:00
RobertJoonas 9ba6df7b3c
Add a special goal: "WP Form Completions" (#5013)
* add special goal with special prop

* rename form to path

* enable WP Form Completion in exports/imports

* get internal keys from public function in test

* also test including imported data

* improve test coverage

* rename goal
2025-01-27 09:10:58 +00:00
Karl-Aksel Puulmann b256d32b8a
Properly validate combining event-only metrics with session-only dimensions (#5015)
Currently the following query results in a 500:

```json
{
  "site_id": "plausible.io",
  "metrics": ["visitors", "events", "pageviews"],
  "dimensions": ["visit:exit_page"],
  "date_range": "7d"
}
```

This adds proper validation for that case that was previously missing.
2025-01-27 08:19:54 +00:00
Karl-Aksel Puulmann c0a762ae56
Excluding goals in dashboard (#4983)
* Simple frontend for has_done_not

* Simple UI for goal filter adding or removal

* Better alignment on trash icons, avoid moving around if row expands

* Refactor filter text functions, share code

* has_not_done, special casing for has not done when formatting filter text

* Changelog

* Fix lint

* prettier format

* Add tests

* Lowercase Goal

* Update changelog

* has_not_done for goals is now named `is not` in the UI

* prettier

* Document and test serializeApiFilters
2025-01-23 08:23:25 +00:00
Artur Pata 117cf46183
Keybind and modal refactor (#5007)
* Fix doc string

* Allow keybind listeners to be registered on any element

* Support custom placeholders in search input

* Support modals that aren't treated as pages
2025-01-23 08:09:56 +00:00
Karl-Aksel Puulmann 585c85b24e
Test out fetch-with-keepalive on plausible.io (#5005)
* Test out fetch-with-keepalive on plausible.io

Fetch with keepalive is a
[widely-supported](https://developer.mozilla.org/en-US/docs/Web/API/Request/keepalive)
which indicates whether the browser will keep the associated request alive if the page that initiated it is unloaded before the request is complete.

We're hoping it will improve event capture rates for `pageleave` and
`pageview` events when the user closes the tab

To use it, we also need to start using `fetch` (with fallback to xhr).

For extra safety, we will only deploy this on `plausible.io` initially.
This will ensure that if there are issues we will be able to react
without affecting any other customers.

TODO after this PR:
- [ ] Companion docs PR
- [ ] Purge bunny cache
- [ ] Make fetch the default request method without data-property

* Mark some code conditional
2025-01-23 07:53:27 +00:00
Adrian Gruntkowski 4f98259874
Fix passthrough processing billing callback (#5006)
* Revert "Remove support for legacy Paddle webhook passthrough formats (#4939)"

This reverts commit 48bd2fbd88.

* Drop support for legacy passthrough formats _but_ leave new user only one
2025-01-22 13:03:15 +00:00
Adrian Gruntkowski 48bd2fbd88
Remove support for legacy Paddle webhook passthrough formats (#4939)
* Remove support for legacy Paddle webhook passthrough formats

* Drop support for legacy and user_id only passthrough entirely

* Make codespell CI check happy
2025-01-22 09:46:54 +00:00
Karl-Aksel Puulmann 714f7f4603
Refactor: Remove `filter_key` terminology from backend (#4994)
* Remove filter_key terminology from the backend

This resurfaced in a recent review, `dimension` or `filter_dimension` is the correct terminology in the backend

* Update table_decider

* Solve new issues
2025-01-21 15:36:34 +00:00
ruslandoga ad4e9ee0ff
remove unused Sentry before_send Clickhousex clauses (#4996) 2025-01-21 12:08:31 +00:00
Karl-Aksel Puulmann 9a4969e105
APIv2: Behavioral filtering (#4980)
* Expose site_id and site_native_stats_start_at via query

This allows to do more query-building without exposing and passing `site` directly.

* Very basic has_done/has_done_not operator support

No event:goal support yet, no validations

* Add validations that only event: dimensions can be used within has_done/has_done_not

* Allow event:goal filters nested within has_done/has_done_not behavioral filters

* Minor fix for do_decide_custom_prop_table

* has_done support for goals

Minor changes along the way:
- preloaded_goals structure changes
- event:goal restrictions were loosened within has_done
- we don't allow nesting has_done anymore

* Dont query imports when behavioral filters are present

* Update callsites of filtering_on_dimension? to work with new behavioral filters

* has_done_not -> has_not_done

* Changelog entry

* Typegen

* credo cleanup

* Fix changelog

* Remove changelog

* Mark has_done as internal-only

* combine two validations into a single loop

* has_done is now session-based not user-based

* Update a test

* Update transform_tree
2025-01-21 12:03:26 +00:00
Artur Pata f0104cb6e7
Expand segments in queries (#4982)
* Refactor segments model

* Fix inconsistent code

* Remove superfluous error case

* Beautify Plausible.Segments module

* Expand segments in filters

* Add tests

* Generate types

* Remove extraneous newlines

* Move Segment filters logic away from QueryParser

* Add moduledoc

* Add tests for /v2/query-internal-test

* Refactor max segment filters count to module attribute

* Add more parser tests and unify asserts in query
2025-01-21 11:33:08 +00:00
Adrian Gruntkowski a45bc1c963
Implement team member and invitation management actions (#4977)
* Implement scaffolding for team member and invite mgmt actions

* Implement updating team role

* Prevent changing role if the subject is the only remaining owner

* Implement removing team membership

* Fix only remaining owner removal checks

* Fix remove team membership service

* Fix and clean up imports

* Implement team invitation removal

* Fix errors surfaced by dialyzer

* Test and fix removing team invitations

* Make accept invitation action work for team invitations

* Test rejecting team invitation

* Test team membership role update and removal actions

* Fix flash message interpolation and missing team in transfer result

* Implement migration adding UUID identifier to team

* Set UUID identifier on team creation

* Implement get team by identifier

* Display team invitations on /sites

* Test rendering team invitations on /sites

* Add team management notices on /settings/people

* Test showing team management notices on /settings/people

* Stop drawing double horizontal rule

* Add modueldoc

* Handle guest member trying to call team membership endpoints gracefully

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-01-20 14:24:21 +00:00
ruslandoga d16f478091
Remove "priority" Postmark message stream from CE (#4990)
* no postmark message stream in ce

* fix test

* format
2025-01-20 12:04:48 +00:00
Artur Pata 5af43a93d5
Refactor Segments controller to be thinner (#4981)
* Refactor segments model

* Fix inconsistent code

* Remove superfluous error case

* Beautify Plausible.Segments module
2025-01-20 09:58:31 +00:00